diff options
280 files changed, 6944 insertions, 3800 deletions
diff --git a/Android.mk b/Android.mk index e96a93239f01..a02b32630426 100644 --- a/Android.mk +++ b/Android.mk @@ -142,6 +142,7 @@ LOCAL_SRC_FILES += \ core/java/android/content/pm/IPackageManager.aidl \ core/java/android/content/pm/IPackageMoveObserver.aidl \ core/java/android/content/pm/IPackageStatsObserver.aidl \ + core/java/android/content/pm/IPackagesProvider.aidl \ core/java/android/content/pm/IOnPermissionsChangeListener.aidl \ core/java/android/database/IContentObserver.aidl \ core/java/android/hardware/ICameraService.aidl \ diff --git a/api/current.txt b/api/current.txt index 1287c74e370b..aa07a9726024 100644 --- a/api/current.txt +++ b/api/current.txt @@ -105,12 +105,9 @@ package android { field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE"; field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS"; field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; - field public static final deprecated java.lang.String READ_PROFILE = "android.permission.READ_PROFILE"; field public static final java.lang.String READ_SMS = "android.permission.READ_SMS"; - field public static final deprecated java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM"; field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS"; field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS"; - field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY"; field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL"; field public static final java.lang.String REBOOT = "android.permission.REBOOT"; field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED"; @@ -152,12 +149,9 @@ package android { field public static final java.lang.String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS"; field public static final java.lang.String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES"; - field public static final deprecated java.lang.String WRITE_PROFILE = "android.permission.WRITE_PROFILE"; field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS"; field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS"; - field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM"; field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS"; - field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY"; field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL"; } @@ -172,9 +166,7 @@ package android { field public static final java.lang.String PHONE = "android.permission-group.PHONE"; field public static final java.lang.String SENSORS = "android.permission-group.SENSORS"; field public static final java.lang.String SMS = "android.permission-group.SMS"; - field public static final java.lang.String SOCIAL_INFO = "android.permission-group.SOCIAL_INFO"; field public static final java.lang.String STORAGE = "android.permission-group.STORAGE"; - field public static final java.lang.String USER_DICTIONARY = "android.permission-group.USER_DICTIONARY"; } public final class R { @@ -4016,79 +4008,6 @@ package android.app { field public java.lang.String serviceDetails; } - public deprecated class AssistContent { - ctor public AssistContent(); - method public android.content.ClipData getClipData(); - method public android.os.Bundle getExtras(); - method public java.lang.String getStructuredData(); - method public android.net.Uri getWebUri(); - method public boolean isAppProvidedIntent(); - method public void setClipData(android.content.ClipData); - method public void setIntent(android.content.Intent); - method public void setStructuredData(java.lang.String); - method public void setWebUri(android.net.Uri); - } - - public deprecated class AssistStructure { - ctor public AssistStructure(); - method public android.content.ComponentName getActivityComponent(); - method public int getWindowNodeCount(); - } - - public static class AssistStructure.ViewNode { - method public android.app.AssistStructure.ViewNode getChildAt(int); - method public int getChildCount(); - method public java.lang.String getClassName(); - method public java.lang.CharSequence getContentDescription(); - method public android.os.Bundle getExtras(); - method public int getHeight(); - method public java.lang.String getHint(); - method public int getId(); - method public java.lang.String getIdEntry(); - method public java.lang.String getIdPackage(); - method public java.lang.String getIdType(); - method public int getLeft(); - method public int getScrollX(); - method public int getScrollY(); - method public java.lang.CharSequence getText(); - method public int getTextBackgroundColor(); - method public int getTextColor(); - method public int getTextSelectionEnd(); - method public int getTextSelectionStart(); - method public float getTextSize(); - method public int getTextStyle(); - method public int getTop(); - method public int getVisibility(); - method public int getWidth(); - method public boolean isAccessibilityFocused(); - method public boolean isActivated(); - method public boolean isAssistBlocked(); - method public boolean isCheckable(); - method public boolean isChecked(); - method public boolean isClickable(); - method public boolean isContextClickable(); - method public boolean isEnabled(); - method public boolean isFocusable(); - method public boolean isFocused(); - method public boolean isLongClickable(); - method public boolean isSelected(); - field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1 - field public static final int TEXT_STYLE_BOLD = 1; // 0x1 - field public static final int TEXT_STYLE_ITALIC = 2; // 0x2 - field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8 - field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4 - } - - public static class AssistStructure.WindowNode { - method public int getDisplayId(); - method public int getHeight(); - method public int getLeft(); - method public android.app.AssistStructure.ViewNode getRootViewNode(); - method public java.lang.CharSequence getTitle(); - method public int getTop(); - method public int getWidth(); - } - public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener { ctor public DatePickerDialog(android.content.Context, android.app.DatePickerDialog.OnDateSetListener, int, int, int); ctor public DatePickerDialog(android.content.Context, int, android.app.DatePickerDialog.OnDateSetListener, int, int, int); @@ -5900,22 +5819,87 @@ package android.app.admin { package android.app.assist { - public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable { - ctor public AssistContent(android.os.Parcel); + public deprecated class AssistContent implements android.os.Parcelable { + ctor public AssistContent(); method public int describeContents(); + method public android.content.ClipData getClipData(); + method public android.os.Bundle getExtras(); method public android.content.Intent getIntent(); + method public java.lang.String getStructuredData(); + method public android.net.Uri getWebUri(); + method public boolean isAppProvidedIntent(); + method public void setClipData(android.content.ClipData); + method public void setIntent(android.content.Intent); + method public void setStructuredData(java.lang.String); + method public void setWebUri(android.net.Uri); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR; } - public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable { + public class AssistStructure implements android.os.Parcelable { ctor public AssistStructure(); method public int describeContents(); - method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); + method public android.content.ComponentName getActivityComponent(); + method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int); + method public int getWindowNodeCount(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR; } + public static class AssistStructure.ViewNode { + method public android.app.assist.AssistStructure.ViewNode getChildAt(int); + method public int getChildCount(); + method public java.lang.String getClassName(); + method public java.lang.CharSequence getContentDescription(); + method public android.os.Bundle getExtras(); + method public int getHeight(); + method public java.lang.String getHint(); + method public int getId(); + method public java.lang.String getIdEntry(); + method public java.lang.String getIdPackage(); + method public java.lang.String getIdType(); + method public int getLeft(); + method public int getScrollX(); + method public int getScrollY(); + method public java.lang.CharSequence getText(); + method public int getTextBackgroundColor(); + method public int getTextColor(); + method public int getTextSelectionEnd(); + method public int getTextSelectionStart(); + method public float getTextSize(); + method public int getTextStyle(); + method public int getTop(); + method public int getVisibility(); + method public int getWidth(); + method public boolean isAccessibilityFocused(); + method public boolean isActivated(); + method public boolean isAssistBlocked(); + method public boolean isCheckable(); + method public boolean isChecked(); + method public boolean isClickable(); + method public boolean isContextClickable(); + method public boolean isEnabled(); + method public boolean isFocusable(); + method public boolean isFocused(); + method public boolean isLongClickable(); + method public boolean isSelected(); + field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1 + field public static final int TEXT_STYLE_BOLD = 1; // 0x1 + field public static final int TEXT_STYLE_ITALIC = 2; // 0x2 + field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8 + field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4 + } + + public static class AssistStructure.WindowNode { + method public int getDisplayId(); + method public int getHeight(); + method public int getLeft(); + method public android.app.assist.AssistStructure.ViewNode getRootViewNode(); + method public java.lang.CharSequence getTitle(); + method public int getTop(); + method public int getWidth(); + } + } package android.app.backup { @@ -7211,6 +7195,7 @@ package android.content { method public android.content.Context getContext(); method public final android.os.IBinder getSyncAdapterBinder(); method public abstract void onPerformSync(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.ContentProviderClient, android.content.SyncResult); + method public void onSecurityException(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.SyncResult); method public void onSyncCanceled(); method public void onSyncCanceled(java.lang.Thread); field public static final deprecated int LOG_SYNC_DETAILS = 2743; // 0xab7 @@ -12308,7 +12293,6 @@ package android.graphics.drawable { method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void invalidateSelf(); method public boolean isAutoMirrored(); - method public boolean isDither(); method public boolean isFilterBitmap(); method public boolean isStateful(); method public final boolean isVisible(); @@ -12328,7 +12312,7 @@ package android.graphics.drawable { method public void setChangingConfigurations(int); method public abstract void setColorFilter(android.graphics.ColorFilter); method public void setColorFilter(int, android.graphics.PorterDuff.Mode); - method public void setDither(boolean); + method public deprecated void setDither(boolean); method public void setFilterBitmap(boolean); method public void setHotspot(float, float); method public void setHotspotBounds(int, int, int, int); @@ -12469,6 +12453,9 @@ package android.graphics.drawable { method public android.graphics.drawable.Drawable loadDrawable(android.content.Context); method public void loadDrawableAsync(android.content.Context, android.os.Message); method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler); + method public android.graphics.drawable.Icon setTint(int); + method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList); + method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR; } @@ -13505,7 +13492,6 @@ package android.hardware.camera2 { field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2 field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1 - field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3; // 0x3 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0 field public static final int LENS_FACING_BACK = 1; // 0x1 @@ -13858,6 +13844,7 @@ package android.hardware.camera2.params { } public final class StreamConfigurationMap { + method public android.util.Size[] getHighResolutionOutputSizes(int); method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges(); method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size); method public android.util.Size[] getHighSpeedVideoSizes(); @@ -18207,7 +18194,6 @@ package android.net { method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties); method public void onLosing(android.net.Network, int); method public void onLost(android.net.Network); - method public void onPreCheck(android.net.Network); } public static abstract interface ConnectivityManager.OnNetworkActiveListener { @@ -18358,6 +18344,7 @@ package android.net { method public boolean hasTransport(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR; + field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11 field public static final int NET_CAPABILITY_CBS = 5; // 0x5 field public static final int NET_CAPABILITY_DUN = 2; // 0x2 field public static final int NET_CAPABILITY_EIMS = 10; // 0xa @@ -18372,6 +18359,7 @@ package android.net { field public static final int NET_CAPABILITY_RCS = 8; // 0x8 field public static final int NET_CAPABILITY_SUPL = 1; // 0x1 field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe + field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10 field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6 field public static final int NET_CAPABILITY_XCAP = 9; // 0x9 field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2 @@ -19085,6 +19073,8 @@ package android.net.wifi { public class ScanResult implements android.os.Parcelable { method public int describeContents(); + method public boolean is80211mcResponder(); + method public boolean isPasspointNetwork(); method public void writeToParcel(android.os.Parcel, int); field public java.lang.String BSSID; field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3 @@ -19092,18 +19082,19 @@ package android.net.wifi { field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1 field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2 field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4 + field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L + field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L field public java.lang.String SSID; field public java.lang.String capabilities; field public int centerFreq0; field public int centerFreq1; field public int channelWidth; + field public long flags; field public int frequency; - field public boolean is80211McRTTResponder; field public int level; - field public java.lang.String operatorFriendlyName; - field public boolean passpointNetwork; + field public java.lang.CharSequence operatorFriendlyName; field public long timestamp; - field public java.lang.String venueName; + field public java.lang.CharSequence venueName; } public final class SupplicantState extends java.lang.Enum implements android.os.Parcelable { @@ -19146,7 +19137,7 @@ package android.net.wifi { field public java.lang.String preSharedKey; field public int priority; field public java.lang.String providerFriendlyName; - field public java.util.HashSet<java.lang.Long> roamingConsortiumIds; + field public java.lang.Long[] roamingConsortiumIds; field public int status; field public java.lang.String[] wepKeys; field public int wepTxKeyIndex; @@ -19208,7 +19199,7 @@ package android.net.wifi { method public java.lang.String getAnonymousIdentity(); method public java.security.cert.X509Certificate getCaCertificate(); method public java.security.cert.X509Certificate getClientCertificate(); - method public java.lang.String getDomainSubjectMatch(); + method public java.lang.String getDomainSuffixMatch(); method public int getEapMethod(); method public java.lang.String getIdentity(); method public java.lang.String getPassword(); @@ -23663,6 +23654,7 @@ package android.os { method public deprecated void setUserRestriction(java.lang.String, boolean); method public deprecated void setUserRestrictions(android.os.Bundle); method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle); + field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking"; field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user"; field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume"; field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps"; @@ -25575,10 +25567,6 @@ package android.provider { field public static final java.lang.String PHOTO_FILE_ID = "data14"; } - public static final deprecated class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; - } - protected static abstract interface ContactsContract.ContactsColumns { field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp"; field public static final java.lang.String DISPLAY_NAME = "display_name"; @@ -25894,10 +25882,6 @@ package android.provider { field public static final java.lang.String DATA_ID = "data_id"; } - public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; - } - protected static abstract interface ContactsContract.RawContactsColumns { field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set"; field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode"; @@ -25968,56 +25952,6 @@ package android.provider { field public static final android.net.Uri PROFILE_CONTENT_URI; } - public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String PHOTO = "photo"; - } - - protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id"; - field public static final deprecated java.lang.String PHOTO_URI = "photo_uri"; - field public static final deprecated java.lang.String SORT_INDEX = "sort_index"; - field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id"; - field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1"; - field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2"; - field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3"; - field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4"; - } - - public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item"; - field public static final deprecated android.net.Uri CONTENT_LIMIT_URI; - field public static final deprecated android.net.Uri CONTENT_PHOTO_URI; - field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item"; - field public static final deprecated android.net.Uri CONTENT_URI; - field public static final deprecated java.lang.String MAX_ITEMS = "max_items"; - } - - public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo"; - field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo"; - field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo"; - } - - protected static abstract deprecated interface ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name"; - field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type"; - field public static final deprecated java.lang.String COMMENTS = "comments"; - field public static final deprecated java.lang.String CONTACT_ID = "contact_id"; - field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup"; - field public static final deprecated java.lang.String DATA_SET = "data_set"; - field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id"; - field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id"; - field public static final deprecated java.lang.String RES_ICON = "icon"; - field public static final deprecated java.lang.String RES_LABEL = "label"; - field public static final deprecated java.lang.String RES_PACKAGE = "res_package"; - field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1"; - field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2"; - field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3"; - field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4"; - field public static final deprecated java.lang.String TEXT = "text"; - field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; - } - protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns { field public static final java.lang.String ACCOUNT_NAME = "account_name"; field public static final java.lang.String ACCOUNT_TYPE = "account_type"; @@ -26581,6 +26515,7 @@ package android.provider { field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled"; field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail"; field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger"; + field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown"; field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count"; field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms"; field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; @@ -28601,8 +28536,7 @@ package android.service.carrier { method public final void notifyCarrierNetworkChange(boolean); method public android.os.IBinder onBind(android.content.Intent); method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier); - field public static final java.lang.String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService"; - field public static final java.lang.String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService"; + field public static final java.lang.String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; } public final class MessagePdu implements android.os.Parcelable { @@ -36631,10 +36565,6 @@ package android.view { method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float); } - public abstract deprecated class ViewAssistStructure extends android.view.ViewStructure { - ctor public ViewAssistStructure(); - } - public class ViewConfiguration { ctor public deprecated ViewConfiguration(); method public static android.view.ViewConfiguration get(android.content.Context); @@ -37016,7 +36946,7 @@ package android.view { ctor public ViewStructure(); method public abstract int addChildCount(int); method public abstract void asyncCommit(); - method public abstract android.view.ViewAssistStructure asyncNewChild(int); + method public abstract android.view.ViewStructure asyncNewChild(int); method public abstract int getChildCount(); method public abstract android.os.Bundle getExtras(); method public abstract java.lang.CharSequence getHint(); @@ -37024,7 +36954,7 @@ package android.view { method public abstract int getTextSelectionEnd(); method public abstract int getTextSelectionStart(); method public abstract boolean hasExtras(); - method public abstract android.view.ViewAssistStructure newChild(int); + method public abstract android.view.ViewStructure newChild(int); method public abstract void setAccessibilityFocused(boolean); method public abstract void setActivated(boolean); method public abstract void setCheckable(boolean); diff --git a/api/removed.txt b/api/removed.txt index 2e6c6854a090..7fc927bcffa6 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -117,6 +117,64 @@ package android.provider { field public static final deprecated java.lang.String URL = "url"; } + public static final deprecated class ContactsContract.Contacts.StreamItems { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + + public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + + public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns { + field public static final deprecated java.lang.String PHOTO = "photo"; + } + + protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns { + field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id"; + field public static final deprecated java.lang.String PHOTO_URI = "photo_uri"; + field public static final deprecated java.lang.String SORT_INDEX = "sort_index"; + field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id"; + field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1"; + field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2"; + field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3"; + field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4"; + } + + public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item"; + field public static final deprecated android.net.Uri CONTENT_LIMIT_URI; + field public static final deprecated android.net.Uri CONTENT_PHOTO_URI; + field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item"; + field public static final deprecated android.net.Uri CONTENT_URI; + field public static final deprecated java.lang.String MAX_ITEMS = "max_items"; + } + + public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo"; + field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo"; + field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo"; + } + + protected static abstract deprecated interface ContactsContract.StreamItemsColumns { + field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name"; + field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type"; + field public static final deprecated java.lang.String COMMENTS = "comments"; + field public static final deprecated java.lang.String CONTACT_ID = "contact_id"; + field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup"; + field public static final deprecated java.lang.String DATA_SET = "data_set"; + field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id"; + field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id"; + field public static final deprecated java.lang.String RES_ICON = "icon"; + field public static final deprecated java.lang.String RES_LABEL = "label"; + field public static final deprecated java.lang.String RES_PACKAGE = "res_package"; + field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1"; + field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2"; + field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3"; + field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4"; + field public static final deprecated java.lang.String TEXT = "text"; + field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; + } + public static final class Settings.System extends android.provider.Settings.NameValueTable { field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible"; field public static final java.lang.String VOLUME_ALARM = "volume_alarm"; diff --git a/api/system-current.txt b/api/system-current.txt index 1f8f7a39c6c5..a245a3e2bdaa 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -156,13 +156,10 @@ package android { field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY"; field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE"; - field public static final deprecated java.lang.String READ_PROFILE = "android.permission.READ_PROFILE"; field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES"; field public static final java.lang.String READ_SMS = "android.permission.READ_SMS"; - field public static final deprecated java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM"; field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS"; field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS"; - field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY"; field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL"; field public static final java.lang.String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL"; field public static final java.lang.String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS"; @@ -227,12 +224,9 @@ package android { field public static final java.lang.String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES"; field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE"; - field public static final deprecated java.lang.String WRITE_PROFILE = "android.permission.WRITE_PROFILE"; field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS"; field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS"; - field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM"; field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS"; - field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY"; field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL"; } @@ -247,9 +241,7 @@ package android { field public static final java.lang.String PHONE = "android.permission-group.PHONE"; field public static final java.lang.String SENSORS = "android.permission-group.SENSORS"; field public static final java.lang.String SMS = "android.permission-group.SMS"; - field public static final java.lang.String SOCIAL_INFO = "android.permission-group.SOCIAL_INFO"; field public static final java.lang.String STORAGE = "android.permission-group.STORAGE"; - field public static final java.lang.String USER_DICTIONARY = "android.permission-group.USER_DICTIONARY"; } public final class R { @@ -4112,79 +4104,6 @@ package android.app { field public java.lang.String serviceDetails; } - public deprecated class AssistContent { - ctor public AssistContent(); - method public android.content.ClipData getClipData(); - method public android.os.Bundle getExtras(); - method public java.lang.String getStructuredData(); - method public android.net.Uri getWebUri(); - method public boolean isAppProvidedIntent(); - method public void setClipData(android.content.ClipData); - method public void setIntent(android.content.Intent); - method public void setStructuredData(java.lang.String); - method public void setWebUri(android.net.Uri); - } - - public deprecated class AssistStructure { - ctor public AssistStructure(); - method public android.content.ComponentName getActivityComponent(); - method public int getWindowNodeCount(); - } - - public static class AssistStructure.ViewNode { - method public android.app.AssistStructure.ViewNode getChildAt(int); - method public int getChildCount(); - method public java.lang.String getClassName(); - method public java.lang.CharSequence getContentDescription(); - method public android.os.Bundle getExtras(); - method public int getHeight(); - method public java.lang.String getHint(); - method public int getId(); - method public java.lang.String getIdEntry(); - method public java.lang.String getIdPackage(); - method public java.lang.String getIdType(); - method public int getLeft(); - method public int getScrollX(); - method public int getScrollY(); - method public java.lang.CharSequence getText(); - method public int getTextBackgroundColor(); - method public int getTextColor(); - method public int getTextSelectionEnd(); - method public int getTextSelectionStart(); - method public float getTextSize(); - method public int getTextStyle(); - method public int getTop(); - method public int getVisibility(); - method public int getWidth(); - method public boolean isAccessibilityFocused(); - method public boolean isActivated(); - method public boolean isAssistBlocked(); - method public boolean isCheckable(); - method public boolean isChecked(); - method public boolean isClickable(); - method public boolean isContextClickable(); - method public boolean isEnabled(); - method public boolean isFocusable(); - method public boolean isFocused(); - method public boolean isLongClickable(); - method public boolean isSelected(); - field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1 - field public static final int TEXT_STYLE_BOLD = 1; // 0x1 - field public static final int TEXT_STYLE_ITALIC = 2; // 0x2 - field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8 - field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4 - } - - public static class AssistStructure.WindowNode { - method public int getDisplayId(); - method public int getHeight(); - method public int getLeft(); - method public android.app.AssistStructure.ViewNode getRootViewNode(); - method public java.lang.CharSequence getTitle(); - method public int getTop(); - method public int getWidth(); - } - public class BroadcastOptions { method public static android.app.BroadcastOptions makeBasic(); method public void setTemporaryAppWhitelistDuration(long); @@ -6018,22 +5937,87 @@ package android.app.admin { package android.app.assist { - public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable { - ctor public AssistContent(android.os.Parcel); + public deprecated class AssistContent implements android.os.Parcelable { + ctor public AssistContent(); method public int describeContents(); + method public android.content.ClipData getClipData(); + method public android.os.Bundle getExtras(); method public android.content.Intent getIntent(); + method public java.lang.String getStructuredData(); + method public android.net.Uri getWebUri(); + method public boolean isAppProvidedIntent(); + method public void setClipData(android.content.ClipData); + method public void setIntent(android.content.Intent); + method public void setStructuredData(java.lang.String); + method public void setWebUri(android.net.Uri); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR; } - public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable { + public class AssistStructure implements android.os.Parcelable { ctor public AssistStructure(); method public int describeContents(); - method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); + method public android.content.ComponentName getActivityComponent(); + method public android.app.assist.AssistStructure.WindowNode getWindowNodeAt(int); + method public int getWindowNodeCount(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR; } + public static class AssistStructure.ViewNode { + method public android.app.assist.AssistStructure.ViewNode getChildAt(int); + method public int getChildCount(); + method public java.lang.String getClassName(); + method public java.lang.CharSequence getContentDescription(); + method public android.os.Bundle getExtras(); + method public int getHeight(); + method public java.lang.String getHint(); + method public int getId(); + method public java.lang.String getIdEntry(); + method public java.lang.String getIdPackage(); + method public java.lang.String getIdType(); + method public int getLeft(); + method public int getScrollX(); + method public int getScrollY(); + method public java.lang.CharSequence getText(); + method public int getTextBackgroundColor(); + method public int getTextColor(); + method public int getTextSelectionEnd(); + method public int getTextSelectionStart(); + method public float getTextSize(); + method public int getTextStyle(); + method public int getTop(); + method public int getVisibility(); + method public int getWidth(); + method public boolean isAccessibilityFocused(); + method public boolean isActivated(); + method public boolean isAssistBlocked(); + method public boolean isCheckable(); + method public boolean isChecked(); + method public boolean isClickable(); + method public boolean isContextClickable(); + method public boolean isEnabled(); + method public boolean isFocusable(); + method public boolean isFocused(); + method public boolean isLongClickable(); + method public boolean isSelected(); + field public static final int TEXT_COLOR_UNDEFINED = 1; // 0x1 + field public static final int TEXT_STYLE_BOLD = 1; // 0x1 + field public static final int TEXT_STYLE_ITALIC = 2; // 0x2 + field public static final int TEXT_STYLE_STRIKE_THRU = 8; // 0x8 + field public static final int TEXT_STYLE_UNDERLINE = 4; // 0x4 + } + + public static class AssistStructure.WindowNode { + method public int getDisplayId(); + method public int getHeight(); + method public int getLeft(); + method public android.app.assist.AssistStructure.ViewNode getRootViewNode(); + method public java.lang.CharSequence getTitle(); + method public int getTop(); + method public int getWidth(); + } + } package android.app.backup { @@ -7436,6 +7420,7 @@ package android.content { method public android.content.Context getContext(); method public final android.os.IBinder getSyncAdapterBinder(); method public abstract void onPerformSync(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.ContentProviderClient, android.content.SyncResult); + method public void onSecurityException(android.accounts.Account, android.os.Bundle, java.lang.String, android.content.SyncResult); method public void onSyncCanceled(); method public void onSyncCanceled(java.lang.Thread); field public static final deprecated int LOG_SYNC_DETAILS = 2743; // 0xab7 @@ -12634,7 +12619,6 @@ package android.graphics.drawable { method public void inflate(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet, android.content.res.Resources.Theme) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public void invalidateSelf(); method public boolean isAutoMirrored(); - method public boolean isDither(); method public boolean isFilterBitmap(); method public boolean isStateful(); method public final boolean isVisible(); @@ -12654,7 +12638,7 @@ package android.graphics.drawable { method public void setChangingConfigurations(int); method public abstract void setColorFilter(android.graphics.ColorFilter); method public void setColorFilter(int, android.graphics.PorterDuff.Mode); - method public void setDither(boolean); + method public deprecated void setDither(boolean); method public void setFilterBitmap(boolean); method public void setHotspot(float, float); method public void setHotspotBounds(int, int, int, int); @@ -12795,6 +12779,9 @@ package android.graphics.drawable { method public android.graphics.drawable.Drawable loadDrawable(android.content.Context); method public void loadDrawableAsync(android.content.Context, android.os.Message); method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler); + method public android.graphics.drawable.Icon setTint(int); + method public android.graphics.drawable.Icon setTintList(android.content.res.ColorStateList); + method public android.graphics.drawable.Icon setTintMode(android.graphics.PorterDuff.Mode); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR; } @@ -13836,7 +13823,6 @@ package android.hardware.camera2 { field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2 field public static final int HOT_PIXEL_MODE_OFF = 0; // 0x0 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1; // 0x1 - field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3; // 0x3 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; // 0x2 field public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED = 0; // 0x0 field public static final int LENS_FACING_BACK = 1; // 0x1 @@ -14189,6 +14175,7 @@ package android.hardware.camera2.params { } public final class StreamConfigurationMap { + method public android.util.Size[] getHighResolutionOutputSizes(int); method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRanges(); method public android.util.Range<java.lang.Integer>[] getHighSpeedVideoFpsRangesFor(android.util.Size); method public android.util.Size[] getHighSpeedVideoSizes(); @@ -19708,7 +19695,6 @@ package android.net { method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties); method public void onLosing(android.net.Network, int); method public void onLost(android.net.Network); - method public void onPreCheck(android.net.Network); } public static abstract interface ConnectivityManager.OnNetworkActiveListener { @@ -19859,6 +19845,7 @@ package android.net { method public boolean hasTransport(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR; + field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11 field public static final int NET_CAPABILITY_CBS = 5; // 0x5 field public static final int NET_CAPABILITY_DUN = 2; // 0x2 field public static final int NET_CAPABILITY_EIMS = 10; // 0xa @@ -19873,6 +19860,7 @@ package android.net { field public static final int NET_CAPABILITY_RCS = 8; // 0x8 field public static final int NET_CAPABILITY_SUPL = 1; // 0x1 field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe + field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10 field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6 field public static final int NET_CAPABILITY_XCAP = 9; // 0x9 field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2 @@ -20827,6 +20815,8 @@ package android.net.wifi { public class ScanResult implements android.os.Parcelable { method public int describeContents(); + method public boolean is80211mcResponder(); + method public boolean isPasspointNetwork(); method public void writeToParcel(android.os.Parcel, int); field public java.lang.String BSSID; field public static final int CHANNEL_WIDTH_160MHZ = 3; // 0x3 @@ -20834,18 +20824,19 @@ package android.net.wifi { field public static final int CHANNEL_WIDTH_40MHZ = 1; // 0x1 field public static final int CHANNEL_WIDTH_80MHZ = 2; // 0x2 field public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; // 0x4 + field public static final long FLAG_80211mc_RESPONDER = 2L; // 0x2L + field public static final long FLAG_PASSPOINT_NETWORK = 1L; // 0x1L field public java.lang.String SSID; field public java.lang.String capabilities; field public int centerFreq0; field public int centerFreq1; field public int channelWidth; + field public long flags; field public int frequency; - field public boolean is80211McRTTResponder; field public int level; - field public java.lang.String operatorFriendlyName; - field public boolean passpointNetwork; + field public java.lang.CharSequence operatorFriendlyName; field public long timestamp; - field public java.lang.String venueName; + field public java.lang.CharSequence venueName; } public final class SupplicantState extends java.lang.Enum implements android.os.Parcelable { @@ -20895,7 +20886,7 @@ package android.net.wifi { field public java.lang.String preSharedKey; field public int priority; field public java.lang.String providerFriendlyName; - field public java.util.HashSet<java.lang.Long> roamingConsortiumIds; + field public java.lang.Long[] roamingConsortiumIds; field public int status; field public java.lang.String[] wepKeys; field public int wepTxKeyIndex; @@ -20972,7 +20963,7 @@ package android.net.wifi { method public java.lang.String getAnonymousIdentity(); method public java.security.cert.X509Certificate getCaCertificate(); method public java.security.cert.X509Certificate getClientCertificate(); - method public java.lang.String getDomainSubjectMatch(); + method public java.lang.String getDomainSuffixMatch(); method public int getEapMethod(); method public java.lang.String getIdentity(); method public java.lang.String getPassword(); @@ -25608,6 +25599,7 @@ package android.os { method public deprecated void setUserRestriction(java.lang.String, boolean); method public deprecated void setUserRestrictions(android.os.Bundle); method public deprecated void setUserRestrictions(android.os.Bundle, android.os.UserHandle); + field public static final java.lang.String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking"; field public static final java.lang.String DISALLOW_ADD_USER = "no_add_user"; field public static final java.lang.String DISALLOW_ADJUST_VOLUME = "no_adjust_volume"; field public static final java.lang.String DISALLOW_APPS_CONTROL = "no_control_apps"; @@ -27520,10 +27512,6 @@ package android.provider { field public static final java.lang.String PHOTO_FILE_ID = "data14"; } - public static final deprecated class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; - } - protected static abstract interface ContactsContract.ContactsColumns { field public static final java.lang.String CONTACT_LAST_UPDATED_TIMESTAMP = "contact_last_updated_timestamp"; field public static final java.lang.String DISPLAY_NAME = "display_name"; @@ -27839,10 +27827,6 @@ package android.provider { field public static final java.lang.String DATA_ID = "data_id"; } - public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; - } - protected static abstract interface ContactsContract.RawContactsColumns { field public static final java.lang.String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set"; field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode"; @@ -27913,56 +27897,6 @@ package android.provider { field public static final android.net.Uri PROFILE_CONTENT_URI; } - public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String PHOTO = "photo"; - } - - protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id"; - field public static final deprecated java.lang.String PHOTO_URI = "photo_uri"; - field public static final deprecated java.lang.String SORT_INDEX = "sort_index"; - field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id"; - field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1"; - field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2"; - field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3"; - field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4"; - } - - public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item"; - field public static final deprecated android.net.Uri CONTENT_LIMIT_URI; - field public static final deprecated android.net.Uri CONTENT_PHOTO_URI; - field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item"; - field public static final deprecated android.net.Uri CONTENT_URI; - field public static final deprecated java.lang.String MAX_ITEMS = "max_items"; - } - - public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns { - field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo"; - field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo"; - field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo"; - } - - protected static abstract deprecated interface ContactsContract.StreamItemsColumns { - field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name"; - field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type"; - field public static final deprecated java.lang.String COMMENTS = "comments"; - field public static final deprecated java.lang.String CONTACT_ID = "contact_id"; - field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup"; - field public static final deprecated java.lang.String DATA_SET = "data_set"; - field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id"; - field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id"; - field public static final deprecated java.lang.String RES_ICON = "icon"; - field public static final deprecated java.lang.String RES_LABEL = "label"; - field public static final deprecated java.lang.String RES_PACKAGE = "res_package"; - field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1"; - field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2"; - field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3"; - field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4"; - field public static final deprecated java.lang.String TEXT = "text"; - field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; - } - protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns { field public static final java.lang.String ACCOUNT_NAME = "account_name"; field public static final java.lang.String ACCOUNT_TYPE = "account_type"; @@ -28629,6 +28563,7 @@ package android.provider { field public static final java.lang.String USB_MASS_STORAGE_ENABLED = "usb_mass_storage_enabled"; field public static final java.lang.String USE_GOOGLE_MAIL = "use_google_mail"; field public static final java.lang.String WAIT_FOR_DEBUGGER = "wait_for_debugger"; + field public static final java.lang.String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = "wifi_device_owner_configs_lockdown"; field public static final java.lang.String WIFI_MAX_DHCP_RETRY_COUNT = "wifi_max_dhcp_retry_count"; field public static final java.lang.String WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS = "wifi_mobile_data_transition_wakelock_timeout_ms"; field public static final java.lang.String WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON = "wifi_networks_available_notification_on"; @@ -30649,8 +30584,7 @@ package android.service.carrier { method public final void notifyCarrierNetworkChange(boolean); method public android.os.IBinder onBind(android.content.Intent); method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier); - field public static final java.lang.String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService"; - field public static final java.lang.String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService"; + field public static final java.lang.String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; } public final class MessagePdu implements android.os.Parcelable { @@ -38912,10 +38846,6 @@ package android.view { method public static android.animation.Animator createCircularReveal(android.view.View, int, int, float, float); } - public abstract deprecated class ViewAssistStructure extends android.view.ViewStructure { - ctor public ViewAssistStructure(); - } - public class ViewConfiguration { ctor public deprecated ViewConfiguration(); method public static android.view.ViewConfiguration get(android.content.Context); @@ -39297,7 +39227,7 @@ package android.view { ctor public ViewStructure(); method public abstract int addChildCount(int); method public abstract void asyncCommit(); - method public abstract android.view.ViewAssistStructure asyncNewChild(int); + method public abstract android.view.ViewStructure asyncNewChild(int); method public abstract int getChildCount(); method public abstract android.os.Bundle getExtras(); method public abstract java.lang.CharSequence getHint(); @@ -39305,7 +39235,7 @@ package android.view { method public abstract int getTextSelectionEnd(); method public abstract int getTextSelectionStart(); method public abstract boolean hasExtras(); - method public abstract android.view.ViewAssistStructure newChild(int); + method public abstract android.view.ViewStructure newChild(int); method public abstract void setAccessibilityFocused(boolean); method public abstract void setActivated(boolean); method public abstract void setCheckable(boolean); diff --git a/api/system-removed.txt b/api/system-removed.txt index 2e6c6854a090..7fc927bcffa6 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -117,6 +117,64 @@ package android.provider { field public static final deprecated java.lang.String URL = "url"; } + public static final deprecated class ContactsContract.Contacts.StreamItems { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + + public static final deprecated class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "stream_items"; + } + + public static final deprecated class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns { + field public static final deprecated java.lang.String PHOTO = "photo"; + } + + protected static abstract deprecated interface ContactsContract.StreamItemPhotosColumns { + field public static final deprecated java.lang.String PHOTO_FILE_ID = "photo_file_id"; + field public static final deprecated java.lang.String PHOTO_URI = "photo_uri"; + field public static final deprecated java.lang.String SORT_INDEX = "sort_index"; + field public static final deprecated java.lang.String STREAM_ITEM_ID = "stream_item_id"; + field public static final deprecated java.lang.String SYNC1 = "stream_item_photo_sync1"; + field public static final deprecated java.lang.String SYNC2 = "stream_item_photo_sync2"; + field public static final deprecated java.lang.String SYNC3 = "stream_item_photo_sync3"; + field public static final deprecated java.lang.String SYNC4 = "stream_item_photo_sync4"; + } + + public static final deprecated class ContactsContract.StreamItems implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item"; + field public static final deprecated android.net.Uri CONTENT_LIMIT_URI; + field public static final deprecated android.net.Uri CONTENT_PHOTO_URI; + field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item"; + field public static final deprecated android.net.Uri CONTENT_URI; + field public static final deprecated java.lang.String MAX_ITEMS = "max_items"; + } + + public static final deprecated class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns { + field public static final deprecated java.lang.String CONTENT_DIRECTORY = "photo"; + field public static final deprecated java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo"; + field public static final deprecated java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo"; + } + + protected static abstract deprecated interface ContactsContract.StreamItemsColumns { + field public static final deprecated java.lang.String ACCOUNT_NAME = "account_name"; + field public static final deprecated java.lang.String ACCOUNT_TYPE = "account_type"; + field public static final deprecated java.lang.String COMMENTS = "comments"; + field public static final deprecated java.lang.String CONTACT_ID = "contact_id"; + field public static final deprecated java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup"; + field public static final deprecated java.lang.String DATA_SET = "data_set"; + field public static final deprecated java.lang.String RAW_CONTACT_ID = "raw_contact_id"; + field public static final deprecated java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id"; + field public static final deprecated java.lang.String RES_ICON = "icon"; + field public static final deprecated java.lang.String RES_LABEL = "label"; + field public static final deprecated java.lang.String RES_PACKAGE = "res_package"; + field public static final deprecated java.lang.String SYNC1 = "stream_item_sync1"; + field public static final deprecated java.lang.String SYNC2 = "stream_item_sync2"; + field public static final deprecated java.lang.String SYNC3 = "stream_item_sync3"; + field public static final deprecated java.lang.String SYNC4 = "stream_item_sync4"; + field public static final deprecated java.lang.String TEXT = "text"; + field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; + } + public static final class Settings.System extends android.provider.Settings.NameValueTable { field public static final java.lang.String APPEND_FOR_LAST_AUDIBLE = "_last_audible"; field public static final java.lang.String VOLUME_ALARM = "volume_alarm"; diff --git a/cmds/hid/Android.mk b/cmds/hid/Android.mk new file mode 100644 index 000000000000..ff3691dd51bd --- /dev/null +++ b/cmds/hid/Android.mk @@ -0,0 +1,18 @@ +# Copyright 2015 The Android Open Source Project +# +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_MODULE := hid +LOCAL_JNI_SHARED_LIBRARIES := libhidcommand_jni +include $(BUILD_JAVA_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := hid +LOCAL_SRC_FILES := hid +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := EXECUTABLES +include $(BUILD_PREBUILT) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/cmds/hid/MODULE_LICENSE_APACHE2 b/cmds/hid/MODULE_LICENSE_APACHE2 new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/cmds/hid/MODULE_LICENSE_APACHE2 diff --git a/cmds/hid/NOTICE b/cmds/hid/NOTICE new file mode 100644 index 000000000000..c5b1efa7aac7 --- /dev/null +++ b/cmds/hid/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, 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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/cmds/hid/hid b/cmds/hid/hid new file mode 100755 index 000000000000..2359fcd738dd --- /dev/null +++ b/cmds/hid/hid @@ -0,0 +1,8 @@ +#!/system/bin/sh +# +# Script to start "hid" on the device, which has a very rudimentary +# shell. +# +base=/system +export CLASSPATH=$base/framework/hid.jar +exec app_process $base/bin com.android.commands.hid.Hid "$@" diff --git a/cmds/hid/jni/Android.mk b/cmds/hid/jni/Android.mk new file mode 100644 index 000000000000..8163a9d764ff --- /dev/null +++ b/cmds/hid/jni/Android.mk @@ -0,0 +1,23 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + com_android_commands_hid_Device.cpp + +LOCAL_C_INCLUDES := \ + $(JNI_H_INCLUDE) \ + frameworks/base/core/jni + +LOCAL_SHARED_LIBRARIES := \ + libandroid_runtime \ + liblog \ + libnativehelper \ + libutils + +LOCAL_MODULE := libhidcommand_jni +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS += -Wall + +include $(BUILD_SHARED_LIBRARY) diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp new file mode 100644 index 000000000000..4278e7d3ac12 --- /dev/null +++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2015 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. + */ + +#define LOG_TAG "HidCommandDevice" + +#include "com_android_commands_hid_Device.h" + +#include <linux/uhid.h> + +#include <fcntl.h> +#include <cstdio> +#include <cstring> +#include <memory> +#include <unistd.h> + +#include <android_runtime/AndroidRuntime.h> +#include <android_runtime/Log.h> +#include <android_os_MessageQueue.h> +#include <core_jni_helpers.h> +#include <jni.h> +#include <JNIHelp.h> +#include <ScopedPrimitiveArray.h> +#include <ScopedUtfChars.h> +#include <utils/Log.h> +#include <utils/Looper.h> +#include <utils/StrongPointer.h> + +namespace android { +namespace uhid { + +static const char* UHID_PATH = "/dev/uhid"; +static const size_t UHID_MAX_NAME_LENGTH = 128; + +static struct { + jmethodID onDeviceOpen; + jmethodID onDeviceError; +} gDeviceCallbackClassInfo; + +static int handleLooperEvents(int fd, int events, void* data) { + Device* d = reinterpret_cast<Device*>(data); + return d->handleEvents(events); +} + +static void checkAndClearException(JNIEnv* env, const char* methodName) { + if (env->ExceptionCheck()) { + ALOGE("An exception was thrown by callback '%s'.", methodName); + LOGE_EX(env); + env->ExceptionClear(); + } +} + +DeviceCallback::DeviceCallback(JNIEnv* env, jobject callback) : + mCallbackObject(env->NewGlobalRef(callback)) { } + +DeviceCallback::~DeviceCallback() { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->DeleteGlobalRef(mCallbackObject); +} + +void DeviceCallback::onDeviceError() { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceError); + checkAndClearException(env, "onDeviceError"); +} + +void DeviceCallback::onDeviceOpen() { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceOpen); + checkAndClearException(env, "onDeviceOpen"); +} + +Device* Device::open(int32_t id, const char* name, int32_t vid, int32_t pid, + std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize, + std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) { + + int fd = ::open(UHID_PATH, O_RDWR | O_CLOEXEC); + if (fd < 0) { + ALOGE("Failed to open uhid: %s", strerror(errno)); + return nullptr; + } + + struct uhid_event ev; + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_CREATE; + strncpy((char*)ev.u.create.name, name, UHID_MAX_NAME_LENGTH); + ev.u.create.rd_data = descriptor.get(); + ev.u.create.rd_size = descriptorSize; + ev.u.create.bus = BUS_BLUETOOTH; + ev.u.create.vendor = vid; + ev.u.create.product = pid; + ev.u.create.version = 0; + ev.u.create.country = 0; + + errno = 0; + ssize_t ret = TEMP_FAILURE_RETRY(::write(fd, &ev, sizeof(ev))); + if (ret < 0 || ret != sizeof(ev)) { + ::close(fd); + ALOGE("Failed to create uhid node: %s", strerror(errno)); + return nullptr; + } + + // Wait for the device to actually be created. + ret = TEMP_FAILURE_RETRY(::read(fd, &ev, sizeof(ev))); + if (ret < 0 || ev.type != UHID_START) { + ::close(fd); + ALOGE("uhid node failed to start: %s", strerror(errno)); + return nullptr; + } + + return new Device(id, fd, std::move(callback), looper); +} + +Device::Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper) : + mId(id), mFd(fd), mDeviceCallback(std::move(callback)), mLooper(looper) { + looper->addFd(fd, 0, Looper::EVENT_INPUT, handleLooperEvents, reinterpret_cast<void*>(this)); +} + +Device::~Device() { + mLooper->removeFd(mFd); + struct uhid_event ev; + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_DESTROY; + TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev))); + ::close(mFd); + mFd = -1; +} + +void Device::sendReport(uint8_t* report, size_t reportSize) { + struct uhid_event ev; + memset(&ev, 0, sizeof(ev)); + ev.type = UHID_INPUT; + ev.u.input.size = reportSize; + memcpy(&ev.u.input.data, report, reportSize); + ssize_t ret = TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev))); + if (ret < 0 || ret != sizeof(ev)) { + ALOGE("Failed to send hid event: %s", strerror(errno)); + } +} + +int Device::handleEvents(int events) { + if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) { + ALOGE("uhid node was closed or an error occurred. events=0x%x", events); + mDeviceCallback->onDeviceError(); + return 0; + } + struct uhid_event ev; + ssize_t ret = TEMP_FAILURE_RETRY(::read(mFd, &ev, sizeof(ev))); + if (ret < 0) { + ALOGE("Failed to read from uhid node: %s", strerror(errno)); + mDeviceCallback->onDeviceError(); + return 0; + } + + if (ev.type == UHID_OPEN) { + mDeviceCallback->onDeviceOpen(); + } + + return 1; +} + +} // namespace uhid + +std::unique_ptr<uint8_t[]> getData(JNIEnv* env, jbyteArray javaArray, size_t& outSize) { + ScopedByteArrayRO scopedArray(env, javaArray); + outSize = scopedArray.size(); + std::unique_ptr<uint8_t[]> data(new uint8_t[outSize]); + for (size_t i = 0; i < outSize; i++) { + data[i] = static_cast<uint8_t>(scopedArray[i]); + } + return data; +} + +static jlong openDevice(JNIEnv* env, jclass clazz, jstring rawName, jint id, jint vid, jint pid, + jbyteArray rawDescriptor, jobject queue, jobject callback) { + ScopedUtfChars name(env, rawName); + if (name.c_str() == nullptr) { + return 0; + } + + size_t size; + std::unique_ptr<uint8_t[]> desc = getData(env, rawDescriptor, size); + + std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback)); + sp<Looper> looper = android_os_MessageQueue_getMessageQueue(env, queue)->getLooper(); + + uhid::Device* d = uhid::Device::open( + id, reinterpret_cast<const char*>(name.c_str()), vid, pid, + std::move(desc), size, std::move(cb), std::move(looper)); + return reinterpret_cast<jlong>(d); +} + +static void sendReport(JNIEnv* env, jclass clazz, jlong ptr,jbyteArray rawReport) { + size_t size; + std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size); + uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr); + if (d) { + d->sendReport(report.get(), size); + } +} + +static void closeDevice(JNIEnv* env, jclass clazz, jlong ptr) { + uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr); + if (d) { + delete d; + } +} + +static JNINativeMethod sMethods[] = { + { "nativeOpenDevice", + "(Ljava/lang/String;III[BLandroid/os/MessageQueue;" + "Lcom/android/commands/hid/Device$DeviceCallback;)J", + reinterpret_cast<void*>(openDevice) }, + { "nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport) }, + { "nativeCloseDevice", "(J)V", reinterpret_cast<void*>(closeDevice) }, +}; + +int register_com_android_commands_hid_Device(JNIEnv* env) { + jclass clazz = FindClassOrDie(env, "com/android/commands/hid/Device$DeviceCallback"); + uhid::gDeviceCallbackClassInfo.onDeviceOpen = + GetMethodIDOrDie(env, clazz, "onDeviceOpen", "()V"); + uhid::gDeviceCallbackClassInfo.onDeviceError= + GetMethodIDOrDie(env, clazz, "onDeviceError", "()V"); + return jniRegisterNativeMethods(env, "com/android/commands/hid/Device", + sMethods, NELEM(sMethods)); +} + +} // namespace android + +jint JNI_OnLoad(JavaVM* jvm, void*) { + JNIEnv *env = NULL; + if (jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6)) { + return JNI_ERR; + } + + if (android::register_com_android_commands_hid_Device(env) < 0 ){ + return JNI_ERR; + } + + return JNI_VERSION_1_6; +} diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h new file mode 100644 index 000000000000..6c5899eeb861 --- /dev/null +++ b/cmds/hid/jni/com_android_commands_hid_Device.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <memory> + +#include <jni.h> +#include <utils/Looper.h> +#include <utils/StrongPointer.h> + +namespace android { +namespace uhid { + +class DeviceCallback { +public: + DeviceCallback(JNIEnv* env, jobject callback); + ~DeviceCallback(); + + void onDeviceOpen(); + void onDeviceError(); + +private: + jobject mCallbackObject; +}; + +class Device { +public: + static Device* open(int32_t id, const char* name, int32_t vid, int32_t pid, + std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize, + std::unique_ptr<DeviceCallback> callback, sp<Looper> looper); + + Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback, sp<Looper> looper); + ~Device(); + + void sendReport(uint8_t* report, size_t reportSize); + void close(); + + int handleEvents(int events); + +private: + int32_t mId; + int mFd; + std::unique_ptr<DeviceCallback> mDeviceCallback; + sp<Looper> mLooper; +}; + + +} // namespace uhid +} // namespace android diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java new file mode 100644 index 000000000000..dbe883bd1136 --- /dev/null +++ b/cmds/hid/src/com/android/commands/hid/Device.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2015 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.hid; + +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.MessageQueue; +import android.os.SystemClock; +import android.util.Log; + +import com.android.internal.os.SomeArgs; + +public class Device { + private static final String TAG = "HidDevice"; + + // Minimum amount of time to wait before sending input events to a device. Even though we're + // guaranteed that the device has been created and opened by the input system, there's still a + // window in which the system hasn't started reading events out of it. If a stream of events + // begins in during this window (like a button down event) and *then* we start reading, we're + // liable to ignore the whole stream. + private static final int MIN_WAIT_FOR_FIRST_EVENT = 150; + + private static final int MSG_OPEN_DEVICE = 1; + private static final int MSG_SEND_REPORT = 2; + private static final int MSG_CLOSE_DEVICE = 3; + + + private final int mId; + private final HandlerThread mThread; + private final DeviceHandler mHandler; + private long mEventTime; + + private final Object mCond = new Object(); + + static { + System.loadLibrary("hidcommand_jni"); + } + + private static native long nativeOpenDevice(String name, int id, int vid, int pid, + byte[] descriptor, MessageQueue queue, DeviceCallback callback); + private static native void nativeSendReport(long ptr, byte[] data); + private static native void nativeCloseDevice(long ptr); + + public Device(int id, String name, int vid, int pid, byte[] descriptor, byte[] report) { + mId = id; + mThread = new HandlerThread("HidDeviceHandler"); + mThread.start(); + mHandler = new DeviceHandler(mThread.getLooper()); + SomeArgs args = SomeArgs.obtain(); + args.argi1 = id; + args.argi2 = vid; + args.argi3 = pid; + if (name != null) { + args.arg1 = name; + } else { + args.arg1 = id + ":" + vid + ":" + pid; + } + args.arg2 = descriptor; + args.arg3 = report; + mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget(); + mEventTime = SystemClock.uptimeMillis() + MIN_WAIT_FOR_FIRST_EVENT; + } + + public void sendReport(byte[] report) { + Message msg = mHandler.obtainMessage(MSG_SEND_REPORT, report); + mHandler.sendMessageAtTime(msg, mEventTime); + } + + public void addDelay(int delay) { + mEventTime += delay; + } + + public void close() { + Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE); + msg.setAsynchronous(true); + mHandler.sendMessageAtTime(msg, mEventTime + 1); + try { + synchronized (mCond) { + mCond.wait(); + } + } catch (InterruptedException ignore) {} + } + + private class DeviceHandler extends Handler { + private long mPtr; + private int mBarrierToken; + + public DeviceHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_OPEN_DEVICE: + SomeArgs args = (SomeArgs) msg.obj; + mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3, + (byte[]) args.arg2, getLooper().myQueue(), new DeviceCallback()); + nativeSendReport(mPtr, (byte[]) args.arg3); + pauseEvents(); + break; + case MSG_SEND_REPORT: + if (mPtr != 0) { + nativeSendReport(mPtr, (byte[]) msg.obj); + } else { + Log.e(TAG, "Tried to send report to closed device."); + } + break; + case MSG_CLOSE_DEVICE: + if (mPtr != 0) { + nativeCloseDevice(mPtr); + getLooper().quitSafely(); + mPtr = 0; + } else { + Log.e(TAG, "Tried to close already closed device."); + } + synchronized (mCond) { + mCond.notify(); + } + break; + default: + throw new IllegalArgumentException("Unknown device message"); + } + } + + public void pauseEvents() { + mBarrierToken = getLooper().myQueue().postSyncBarrier(); + } + + public void resumeEvents() { + getLooper().myQueue().removeSyncBarrier(mBarrierToken); + mBarrierToken = 0; + } + } + + private class DeviceCallback { + public void onDeviceOpen() { + mHandler.resumeEvents(); + } + + public void onDeviceError() { + Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE); + msg.setAsynchronous(true); + msg.sendToTarget(); + } + } +} diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java new file mode 100644 index 000000000000..c6a37bd3c48f --- /dev/null +++ b/cmds/hid/src/com/android/commands/hid/Event.java @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2015 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.hid; + +import android.util.JsonReader; +import android.util.JsonToken; +import android.util.Log; + +import java.io.InputStreamReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +public class Event { + private static final String TAG = "HidEvent"; + + public static final String COMMAND_REGISTER = "register"; + public static final String COMMAND_DELAY = "delay"; + public static final String COMMAND_REPORT = "report"; + + private int mId; + private String mCommand; + private String mName; + private byte[] mDescriptor; + private int mVid; + private int mPid; + private byte[] mReport; + private int mDuration; + + public int getId() { + return mId; + } + + public String getCommand() { + return mCommand; + } + + public String getName() { + return mName; + } + + public byte[] getDescriptor() { + return mDescriptor; + } + + public int getVendorId() { + return mVid; + } + + public int getProductId() { + return mPid; + } + + public byte[] getReport() { + return mReport; + } + + public int getDuration() { + return mDuration; + } + + public String toString() { + return "Event{id=" + mId + + ", command=" + String.valueOf(mCommand) + + ", name=" + String.valueOf(mName) + + ", descriptor=" + Arrays.toString(mDescriptor) + + ", vid=" + mVid + + ", pid=" + mPid + + ", report=" + Arrays.toString(mReport) + + ", duration=" + mDuration + + "}"; + } + + private static class Builder { + private Event mEvent; + + public Builder() { + mEvent = new Event(); + } + + public void setId(int id) { + mEvent.mId = id; + } + + private void setCommand(String command) { + mEvent.mCommand = command; + } + + public void setName(String name) { + mEvent.mName = name; + } + + public void setDescriptor(byte[] descriptor) { + mEvent.mDescriptor = descriptor; + } + + public void setReport(byte[] report) { + mEvent.mReport = report; + } + + public void setVid(int vid) { + mEvent.mVid = vid; + } + + public void setPid(int pid) { + mEvent.mPid = pid; + } + + public void setDuration(int duration) { + mEvent.mDuration = duration; + } + + public Event build() { + if (mEvent.mId == -1) { + throw new IllegalStateException("No event id"); + } else if (mEvent.mCommand == null) { + throw new IllegalStateException("Event does not contain a command"); + } + if (COMMAND_REGISTER.equals(mEvent.mCommand)) { + if (mEvent.mDescriptor == null) { + throw new IllegalStateException("Device registration is missing descriptor"); + } + } else if (COMMAND_DELAY.equals(mEvent.mCommand)) { + if (mEvent.mDuration <= 0) { + throw new IllegalStateException("Delay has missing or invalid duration"); + } + } else if (COMMAND_REPORT.equals(mEvent.mCommand)) { + if (mEvent.mReport == null) { + throw new IllegalStateException("Report command is missing report data"); + } + } + return mEvent; + } + } + + public static class Reader { + private JsonReader mReader; + + public Reader(InputStreamReader in) { + mReader = new JsonReader(in); + mReader.setLenient(true); + } + + public Event getNextEvent() throws IOException { + Event e = null; + while (e == null && mReader.peek() != JsonToken.END_DOCUMENT) { + Event.Builder eb = new Event.Builder(); + try { + mReader.beginObject(); + while (mReader.hasNext()) { + String name = mReader.nextName(); + switch (name) { + case "id": + eb.setId(readInt()); + break; + case "command": + eb.setCommand(mReader.nextString()); + break; + case "descriptor": + eb.setDescriptor(readData()); + break; + case "name": + eb.setName(mReader.nextString()); + break; + case "vid": + eb.setVid(readInt()); + break; + case "pid": + eb.setPid(readInt()); + break; + case "report": + eb.setReport(readData()); + break; + case "duration": + eb.setDuration(readInt()); + break; + default: + mReader.skipValue(); + } + } + mReader.endObject(); + } catch (IllegalStateException ex) { + error("Error reading in object, ignoring.", ex); + consumeRemainingElements(); + mReader.endObject(); + continue; + } + e = eb.build(); + } + + return e; + } + + private byte[] readData() throws IOException { + ArrayList<Integer> data = new ArrayList<Integer>(); + try { + mReader.beginArray(); + while (mReader.hasNext()) { + data.add(Integer.decode(mReader.nextString())); + } + mReader.endArray(); + } catch (IllegalStateException|NumberFormatException e) { + consumeRemainingElements(); + mReader.endArray(); + throw new IllegalStateException("Encountered malformed data.", e); + } + byte[] rawData = new byte[data.size()]; + for (int i = 0; i < data.size(); i++) { + int d = data.get(i); + if ((d & 0xFF) != d) { + throw new IllegalStateException("Invalid data, all values must be byte-sized"); + } + rawData[i] = (byte)d; + } + return rawData; + } + + private int readInt() throws IOException { + String val = mReader.nextString(); + return Integer.decode(val); + } + + private void consumeRemainingElements() throws IOException { + while (mReader.hasNext()) { + mReader.skipValue(); + } + } + } + + private static void error(String msg) { + error(msg, null); + } + + private static void error(String msg, Exception e) { + System.out.println(msg); + Log.e(TAG, msg); + if (e != null) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } +} diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java new file mode 100644 index 000000000000..976a78249bec --- /dev/null +++ b/cmds/hid/src/com/android/commands/hid/Hid.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015 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.hid; + +import android.os.SystemClock; +import android.util.JsonReader; +import android.util.JsonToken; +import android.util.Log; +import android.util.SparseArray; + +import libcore.io.IoUtils; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; + +public class Hid { + private static final String TAG = "HID"; + + private final Event.Reader mReader; + private final SparseArray<Device> mDevices; + + private static void usage() { + error("Usage: hid [FILE]"); + } + + public static void main(String[] args) { + if (args.length != 1) { + usage(); + System.exit(1); + } + + InputStream stream = null; + try { + if (args[0].equals("-")) { + stream = System.in; + } else { + File f = new File(args[0]); + stream = new FileInputStream(f); + } + (new Hid(stream)).run(); + } catch (Exception e) { + error("HID injection failed.", e); + System.exit(1); + } finally { + IoUtils.closeQuietly(stream); + } + } + + private Hid(InputStream in) { + mDevices = new SparseArray<Device>(); + try { + mReader = new Event.Reader(new InputStreamReader(in, "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + private void run() { + try { + Event e = null; + while ((e = mReader.getNextEvent()) != null) { + process(e); + } + } catch (IOException ex) { + error("Error reading in events.", ex); + } + + for (int i = 0; i < mDevices.size(); i++) { + mDevices.valueAt(i).close(); + } + } + + + private void process(Event e) { + final int index = mDevices.indexOfKey(e.getId()); + if (index >= 0) { + Device d = mDevices.valueAt(index); + if (Event.COMMAND_DELAY.equals(e.getCommand())) { + d.addDelay(e.getDuration()); + } else if (Event.COMMAND_REPORT.equals(e.getCommand())) { + d.sendReport(e.getReport()); + } else { + error("Unknown command \"" + e.getCommand() + "\". Ignoring event."); + } + } else { + registerDevice(e); + } + } + + private void registerDevice(Event e) { + if (!Event.COMMAND_REGISTER.equals(e.getCommand())) { + throw new IllegalStateException( + "Tried to send command \"" + e.getCommand() + "\" to an unregistered device!"); + } + int id = e.getId(); + Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), + e.getDescriptor(), e.getReport()); + mDevices.append(id, d); + } + + private static void error(String msg) { + error(msg, null); + } + + private static void error(String msg, Exception e) { + System.out.println(msg); + Log.e(TAG, msg); + if (e != null) { + Log.e(TAG, Log.getStackTraceString(e)); + } + } +} diff --git a/cmds/wm/src/com/android/commands/wm/Wm.java b/cmds/wm/src/com/android/commands/wm/Wm.java index 64f023f16abf..fb050e545931 100644 --- a/cmds/wm/src/com/android/commands/wm/Wm.java +++ b/cmds/wm/src/com/android/commands/wm/Wm.java @@ -54,6 +54,7 @@ public class Wm extends BaseCommand { " wm density [reset|DENSITY]\n" + " wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM]\n" + " wm scaling [off|auto]\n" + + " wm screen-capture [userId] [true|false]\n" + "\n" + "wm size: return or override display size.\n" + " width and height in pixels unless suffixed with 'dp'.\n" + @@ -62,7 +63,9 @@ public class Wm extends BaseCommand { "\n" + "wm overscan: set overscan area for display.\n" + "\n" + - "wm scaling: set display scaling mode.\n" + "wm scaling: set display scaling mode.\n" + + "\n" + + "wm screen-capture: enable/disable screen capture.\n" ); } @@ -85,16 +88,39 @@ public class Wm extends BaseCommand { runDisplayOverscan(); } else if (op.equals("scaling")) { runDisplayScaling(); + } else if (op.equals("screen-capture")) { + runSetScreenCapture(); } else { showError("Error: unknown command '" + op + "'"); return; } } + private void runSetScreenCapture() throws Exception { + String userIdStr = nextArg(); + String enableStr = nextArg(); + int userId; + boolean disable; + + try { + userId = Integer.parseInt(userIdStr); + } catch (NumberFormatException e) { + System.err.println("Error: bad number " + e); + return; + } + + disable = !Boolean.parseBoolean(enableStr); + + try { + mWm.setScreenCaptureDisabled(userId, disable); + } catch (RemoteException e) { + System.err.println("Error: Can't set screen capture " + e); + } + } + private void runDisplaySize() throws Exception { String size = nextArg(); int w, h; - boolean scale = true; if (size == null) { Point initialSize = new Point(); Point baseSize = new Point(); @@ -181,7 +207,6 @@ public class Wm extends BaseCommand { private void runDisplayOverscan() throws Exception { String overscanStr = nextArgRequired(); Rect rect = new Rect(); - int density; if ("reset".equals(overscanStr)) { rect.set(0, 0, 0, 0); } else { diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 993b53d17d70..3001c2c9ef0f 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -209,7 +209,8 @@ public class AccountManager { /** * Bundle key used to supply the last time the credentials of the account * were authenticated successfully. Time is specified in milliseconds since - * epoch. + * epoch. Associated time is updated on successful authentication of account + * on adding account, confirming credentials, or updating credentials. */ public static final String KEY_LAST_AUTHENTICATED_TIME = "lastAuthenticatedTime"; @@ -651,18 +652,25 @@ public class AccountManager { } /** - * Adds an account directly to the AccountManager. Normally used by sign-up + * Adds an account directly to the AccountManager. Normally used by sign-up * wizards associated with authenticators, not directly by applications. - * + * <p>Calling this method does not update the last authenticated timestamp, + * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call + * {@link #notifyAccountAuthenticated(Account)} after getting success. + * However, if this method is called when it is triggered by addAccount() or + * addAccountAsUser() or similar functions, then there is no need to update + * timestamp manually as it is updated automatically by framework on + * successful completion of the mentioned functions. * <p>It is safe to call this method from the main thread. * <p>This method requires the caller to have a signature match with the * authenticator that owns the specified account. * * @param account The {@link Account} to add * @param password The password to associate with the account, null for none - * @param userdata String values to use for the account's userdata, null for none + * @param userdata String values to use for the account's userdata, null for + * none * @return True if the account was successfully added, false if the account - * already exists, the account is null, or another error occurs. + * already exists, the account is null, or another error occurs. */ public boolean addAccountExplicitly(Account account, String password, Bundle userdata) { if (account == null) throw new IllegalArgumentException("account is null"); @@ -976,17 +984,19 @@ public class AccountManager { } /** - * Sets or forgets a saved password. This modifies the local copy of the - * password used to automatically authenticate the user; it does - * not change the user's account password on the server. Intended for use - * by the authenticator, not directly by applications. - * + * Sets or forgets a saved password. This modifies the local copy of the + * password used to automatically authenticate the user; it does not change + * the user's account password on the server. Intended for use by the + * authenticator, not directly by applications. + * <p>Calling this method does not update the last authenticated timestamp, + * referred by {@link #KEY_LAST_AUTHENTICATED_TIME}. To update it, call + * {@link #notifyAccountAuthenticated(Account)} after getting success. * <p>It is safe to call this method from the main thread. - * * <p>This method requires the caller to have a signature match with the * authenticator that manages the specified account. * - * @param account The account whose password is to be set. Cannot be {@code null}. + * @param account The account whose password is to be set. Cannot be + * {@code null}. * @param password The password to set, null to clear the password */ public void setPassword(final Account account, final String password) { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 1b4ee2ede395..e8ab109f992e 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2075,6 +2075,9 @@ public class Activity extends ContextThemeWrapper "by the window decor. Do not request Window.FEATURE_ACTION_BAR and set " + "android:windowActionBar to false in your theme to use a Toolbar instead."); } + // Clear out the MenuInflater to make sure that it is valid for the new Action Bar + mMenuInflater = null; + ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this); mActionBar = tbab; mWindow.setCallback(tbab.getWrappedWindowCallback()); diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java deleted file mode 100644 index ad2ba39761da..000000000000 --- a/core/java/android/app/AssistContent.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2015 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.app; - -import android.content.ClipData; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Holds information about the content an application is viewing, to hand to an - * assistant at the user's request. This is filled in by - * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. - * @deprecated use {@link android.app.assist.AssistContent}. - */ -@Deprecated -public class AssistContent { - private boolean mIsAppProvidedIntent = false; - private Intent mIntent; - private String mStructuredData; - private ClipData mClipData; - private Uri mUri; - private final Bundle mExtras; - - /** - * @hide - * Key name this data structure is stored in the Bundle generated by - * {@link android.app.Activity#onProvideAssistData}. - */ - public static final String ASSIST_KEY = "android:assist_content"; - - /** - * @hide - * Retrieve the framework-generated AssistContent that is stored within - * the Bundle filled in by {@link android.app.Activity#onProvideAssistContent}. - */ - public static android.app.assist.AssistContent getAssistContent(Bundle assistBundle) { - return assistBundle.getParcelable(ASSIST_KEY); - } - - public AssistContent() { - mExtras = new Bundle(); - } - - /** - * @hide - * Called by {@link android.app.ActivityThread} to set the default Intent based on - * {@link android.app.Activity#getIntent Activity.getIntent}. - * - * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW} - * of a web (http or https scheme) URI.</p> - */ - public void setDefaultIntent(Intent intent) { - mIntent = intent; - setWebUri(null); - if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) { - Uri uri = intent.getData(); - if (uri != null) { - if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) { - setWebUri(uri); - } - } - } - } - - /** - * Sets the Intent associated with the content, describing the current top-level context of - * the activity. If this contains a reference to a piece of data related to the activity, - * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility - * service can access it. - */ - public void setIntent(Intent intent) { - mIsAppProvidedIntent = true; - mIntent = intent; - } - - /** - * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from - * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place. - * @hide - */ - public Intent getIntent() { - return mIntent; - } - - /** - * Returns whether or not the current Intent was explicitly provided in - * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not, - * the Intent was automatically set based on - * {@link android.app.Activity#getIntent Activity.getIntent}. - */ - public boolean isAppProvidedIntent() { - return mIsAppProvidedIntent; - } - - /** - * Optional additional content items that are involved with - * the current UI. Access to this content will be granted to the assistant as if you - * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}. - */ - public void setClipData(ClipData clip) { - mClipData = clip; - } - - /** - * Return the current {@link #setClipData}, which you can modify in-place. - */ - public ClipData getClipData() { - return mClipData; - } - - /** - * Sets optional structured data regarding the content being viewed. The provided data - * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the - * <a href="http://schema.org/">schema.org</a> vocabulary. - */ - public void setStructuredData(String structuredData) { - mStructuredData = structuredData; - } - - /** - * Returns the current {@link #setStructuredData}. - */ - public String getStructuredData() { - return mStructuredData; - } - - /** - * Set a web URI associated with the current data being shown to the user. - * This URI could be opened in a web browser, or in the app as an - * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently - * being displayed by it. The URI here should be something that is transportable - * off the device into other environments to acesss the same data as is currently - * being shown in the app; if the app does not have such a representation, it should - * leave the null and only report the local intent and clip data. - */ - public void setWebUri(Uri uri) { - mUri = uri; - } - - /** - * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if - * there is none. - */ - public Uri getWebUri() { - return mUri; - } - - /** - * Return Bundle for extra vendor-specific data that can be modified and examined. - */ - public Bundle getExtras() { - return mExtras; - } - - /** @hide */ - public AssistContent(Parcel in) { - if (in.readInt() != 0) { - mIntent = Intent.CREATOR.createFromParcel(in); - } - if (in.readInt() != 0) { - mClipData = ClipData.CREATOR.createFromParcel(in); - } - if (in.readInt() != 0) { - mUri = Uri.CREATOR.createFromParcel(in); - } - if (in.readInt() != 0) { - mStructuredData = in.readString(); - } - mIsAppProvidedIntent = in.readInt() == 1; - mExtras = in.readBundle(); - } - - /** @hide */ - public void writeToParcelInternal(Parcel dest, int flags) { - if (mIntent != null) { - dest.writeInt(1); - mIntent.writeToParcel(dest, flags); - } else { - dest.writeInt(0); - } - if (mClipData != null) { - dest.writeInt(1); - mClipData.writeToParcel(dest, flags); - } else { - dest.writeInt(0); - } - if (mUri != null) { - dest.writeInt(1); - mUri.writeToParcel(dest, flags); - } else { - dest.writeInt(0); - } - if (mStructuredData != null) { - dest.writeInt(1); - dest.writeString(mStructuredData); - } else { - dest.writeInt(0); - } - dest.writeInt(mIsAppProvidedIntent ? 1 : 0); - dest.writeBundle(mExtras); - } -} diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java deleted file mode 100644 index 7f6dae5aa585..000000000000 --- a/core/java/android/app/AssistStructure.java +++ /dev/null @@ -1,1075 +0,0 @@ -/* - * Copyright (C) 2015 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.app; - -import android.content.ComponentName; -import android.graphics.Rect; -import android.os.Binder; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.PooledStringReader; -import android.os.PooledStringWriter; -import android.os.RemoteException; -import android.os.SystemClock; -import android.text.TextUtils; -import android.util.Log; -import android.view.View; -import android.view.ViewAssistStructure; -import android.view.ViewRootImpl; -import android.view.WindowManager; -import android.view.WindowManagerGlobal; - -import java.util.ArrayList; - -/** - * Assist data automatically created by the platform's implementation - * of {@link android.app.Activity#onProvideAssistData}. - * @deprecated use {@link android.app.assist.AssistStructure}. - */ -@Deprecated -public class AssistStructure { - static final String TAG = "AssistStructure"; - - /** - * @hide - * Key name this data structure is stored in the Bundle generated by - * {@link android.app.Activity#onProvideAssistData}. - */ - public static final String ASSIST_KEY = "android:assist_structure"; - - /** @hide */ - public boolean mHaveData; - - ComponentName mActivityComponent; - - final ArrayList<WindowNode> mWindowNodes = new ArrayList<>(); - - final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>(); - - /** @hide */ - public SendChannel mSendChannel; - /** @hide */ - public IBinder mReceiveChannel; - - Rect mTmpRect = new Rect(); - - static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1; - static final String DESCRIPTOR = "android.app.AssistStructure"; - - /** @hide */ - public final class SendChannel extends Binder { - @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) - throws RemoteException { - if (code == TRANSACTION_XFER) { - data.enforceInterface(DESCRIPTOR); - writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); - return true; - } else { - return super.onTransact(code, data, reply, flags); - } - } - } - - final static class ViewNodeText { - CharSequence mText; - int mTextSelectionStart; - int mTextSelectionEnd; - int mTextColor; - int mTextBackgroundColor; - float mTextSize; - int mTextStyle; - String mHint; - - ViewNodeText() { - } - - ViewNodeText(Parcel in) { - mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - mTextSelectionStart = in.readInt(); - mTextSelectionEnd = in.readInt(); - mTextColor = in.readInt(); - mTextBackgroundColor = in.readInt(); - mTextSize = in.readFloat(); - mTextStyle = in.readInt(); - mHint = in.readString(); - } - - void writeToParcel(Parcel out) { - TextUtils.writeToParcel(mText, out, 0); - out.writeInt(mTextSelectionStart); - out.writeInt(mTextSelectionEnd); - out.writeInt(mTextColor); - out.writeInt(mTextBackgroundColor); - out.writeFloat(mTextSize); - out.writeInt(mTextStyle); - out.writeString(mHint); - } - } - - /** - * Describes a window in the assist data. - */ - static public class WindowNode { - final int mX; - final int mY; - final int mWidth; - final int mHeight; - final CharSequence mTitle; - final int mDisplayId; - final ViewNode mRoot; - - WindowNode(AssistStructure assist, ViewRootImpl root) { - View view = root.getView(); - Rect rect = new Rect(); - view.getBoundsOnScreen(rect); - mX = rect.left - view.getLeft(); - mY = rect.top - view.getTop(); - mWidth = rect.width(); - mHeight = rect.height(); - mTitle = root.getTitle(); - mDisplayId = root.getDisplayId(); - mRoot = new ViewNode(); - ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false); - if ((root.getWindowFlags()&WindowManager.LayoutParams.FLAG_SECURE) != 0) { - // This is a secure window, so it doesn't want a screenshot, and that - // means we should also not copy out its view hierarchy. - view.onProvideStructure(builder); - builder.setAssistBlocked(true); - return; - } - view.dispatchProvideStructure(builder); - } - - WindowNode(Parcel in, PooledStringReader preader) { - mX = in.readInt(); - mY = in.readInt(); - mWidth = in.readInt(); - mHeight = in.readInt(); - mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - mDisplayId = in.readInt(); - mRoot = new ViewNode(in, preader); - } - - void writeToParcel(Parcel out, PooledStringWriter pwriter) { - out.writeInt(mX); - out.writeInt(mY); - out.writeInt(mWidth); - out.writeInt(mHeight); - TextUtils.writeToParcel(mTitle, out, 0); - out.writeInt(mDisplayId); - mRoot.writeToParcel(out, pwriter); - } - - /** - * Returns the left edge of the window, in pixels, relative to the left - * edge of the screen. - */ - public int getLeft() { - return mX; - } - - /** - * Returns the top edge of the window, in pixels, relative to the top - * edge of the screen. - */ - public int getTop() { - return mY; - } - - /** - * Returns the total width of the window in pixels. - */ - public int getWidth() { - return mWidth; - } - - /** - * Returns the total height of the window in pixels. - */ - public int getHeight() { - return mHeight; - } - - /** - * Returns the title associated with the window, if it has one. - */ - public CharSequence getTitle() { - return mTitle; - } - - /** - * Returns the ID of the display this window is on, for use with - * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}. - */ - public int getDisplayId() { - return mDisplayId; - } - - /** - * Returns the {@link ViewNode} containing the root content of the window. - */ - public ViewNode getRootViewNode() { - return mRoot; - } - } - - /** - * Describes a single view in the assist data. - */ - static public class ViewNode { - /** - * Magic value for text color that has not been defined, which is very unlikely - * to be confused with a real text color. - */ - public static final int TEXT_COLOR_UNDEFINED = 1; - - public static final int TEXT_STYLE_BOLD = 1<<0; - public static final int TEXT_STYLE_ITALIC = 1<<1; - public static final int TEXT_STYLE_UNDERLINE = 1<<2; - public static final int TEXT_STYLE_STRIKE_THRU = 1<<3; - - int mId; - String mIdPackage; - String mIdType; - String mIdEntry; - int mX; - int mY; - int mScrollX; - int mScrollY; - int mWidth; - int mHeight; - - static final int FLAGS_DISABLED = 0x00000001; - static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE; - static final int FLAGS_FOCUSABLE = 0x00000010; - static final int FLAGS_FOCUSED = 0x00000020; - static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000; - static final int FLAGS_SELECTED = 0x00000040; - static final int FLAGS_ASSIST_BLOCKED = 0x00000080; - static final int FLAGS_ACTIVATED = 0x40000000; - static final int FLAGS_CHECKABLE = 0x00000100; - static final int FLAGS_CHECKED = 0x00000200; - static final int FLAGS_CLICKABLE = 0x00004000; - static final int FLAGS_LONG_CLICKABLE = 0x00200000; - static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000; - - int mFlags; - - String mClassName; - CharSequence mContentDescription; - - ViewNodeText mText; - Bundle mExtras; - - ViewNode[] mChildren; - - ViewNode() { - } - - ViewNode(Parcel in, PooledStringReader preader) { - mId = in.readInt(); - if (mId != 0) { - mIdEntry = preader.readString(); - if (mIdEntry != null) { - mIdType = preader.readString(); - mIdPackage = preader.readString(); - } else { - mIdPackage = mIdType = null; - } - } else { - mIdPackage = mIdType = mIdEntry = null; - } - mX = in.readInt(); - mY = in.readInt(); - mScrollX = in.readInt(); - mScrollY = in.readInt(); - mWidth = in.readInt(); - mHeight = in.readInt(); - mFlags = in.readInt(); - mClassName = preader.readString(); - mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - if (in.readInt() != 0) { - mText = new ViewNodeText(in); - } else { - mText = null; - } - mExtras = in.readBundle(); - final int NCHILDREN = in.readInt(); - if (NCHILDREN > 0) { - mChildren = new ViewNode[NCHILDREN]; - for (int i=0; i<NCHILDREN; i++) { - mChildren[i] = new ViewNode(in, preader); - } - } else { - mChildren = null; - } - } - - void writeToParcel(Parcel out, PooledStringWriter pwriter) { - out.writeInt(mId); - if (mId != 0) { - pwriter.writeString(mIdEntry); - if (mIdEntry != null) { - pwriter.writeString(mIdType); - pwriter.writeString(mIdPackage); - } - } - out.writeInt(mX); - out.writeInt(mY); - out.writeInt(mScrollX); - out.writeInt(mScrollY); - out.writeInt(mWidth); - out.writeInt(mHeight); - out.writeInt(mFlags); - pwriter.writeString(mClassName); - TextUtils.writeToParcel(mContentDescription, out, 0); - if (mText != null) { - out.writeInt(1); - mText.writeToParcel(out); - } else { - out.writeInt(0); - } - out.writeBundle(mExtras); - if (mChildren != null) { - final int NCHILDREN = mChildren.length; - out.writeInt(NCHILDREN); - for (int i=0; i<NCHILDREN; i++) { - mChildren[i].writeToParcel(out, pwriter); - } - } else { - out.writeInt(0); - } - } - - /** - * Returns the ID associated with this view, as per {@link View#getId() View.getId()}. - */ - public int getId() { - return mId; - } - - /** - * If {@link #getId()} is a resource identifier, this is the package name of that - * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} - * for more information. - */ - public String getIdPackage() { - return mIdPackage; - } - - /** - * If {@link #getId()} is a resource identifier, this is the type name of that - * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} - * for more information. - */ - public String getIdType() { - return mIdType; - } - - /** - * If {@link #getId()} is a resource identifier, this is the entry name of that - * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} - * for more information. - */ - public String getIdEntry() { - return mIdEntry; - } - - /** - * Returns the left edge of this view, in pixels, relative to the left edge of its parent. - */ - public int getLeft() { - return mX; - } - - /** - * Returns the top edge of this view, in pixels, relative to the top edge of its parent. - */ - public int getTop() { - return mY; - } - - /** - * Returns the current X scroll offset of this view, as per - * {@link android.view.View#getScrollX() View.getScrollX()}. - */ - public int getScrollX() { - return mScrollX; - } - - /** - * Returns the current Y scroll offset of this view, as per - * {@link android.view.View#getScrollX() View.getScrollY()}. - */ - public int getScrollY() { - return mScrollY; - } - - /** - * Returns the width of this view, in pixels. - */ - public int getWidth() { - return mWidth; - } - - /** - * Returns the height of this view, in pixels. - */ - public int getHeight() { - return mHeight; - } - - /** - * Returns the visibility mode of this view, as per - * {@link android.view.View#getVisibility() View.getVisibility()}. - */ - public int getVisibility() { - return mFlags&ViewNode.FLAGS_VISIBILITY_MASK; - } - - /** - * Returns true if assist data has been blocked starting at this node in the hierarchy. - */ - public boolean isAssistBlocked() { - return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0; - } - - /** - * Returns true if this node is in an enabled state. - */ - public boolean isEnabled() { - return (mFlags&ViewNode.FLAGS_DISABLED) == 0; - } - - /** - * Returns true if this node is clickable by the user. - */ - public boolean isClickable() { - return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0; - } - - /** - * Returns true if this node can take input focus. - */ - public boolean isFocusable() { - return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0; - } - - /** - * Returns true if this node currently had input focus at the time that the - * structure was collected. - */ - public boolean isFocused() { - return (mFlags&ViewNode.FLAGS_FOCUSED) != 0; - } - - /** - * Returns true if this node currently had accessibility focus at the time that the - * structure was collected. - */ - public boolean isAccessibilityFocused() { - return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0; - } - - /** - * Returns true if this node represents something that is checkable by the user. - */ - public boolean isCheckable() { - return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0; - } - - /** - * Returns true if this node is currently in a checked state. - */ - public boolean isChecked() { - return (mFlags&ViewNode.FLAGS_CHECKED) != 0; - } - - /** - * Returns true if this node has currently been selected by the user. - */ - public boolean isSelected() { - return (mFlags&ViewNode.FLAGS_SELECTED) != 0; - } - - /** - * Returns true if this node has currently been activated by the user. - */ - public boolean isActivated() { - return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0; - } - - /** - * Returns true if this node is something the user can perform a long click/press on. - */ - public boolean isLongClickable() { - return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0; - } - - /** - * Returns true if this node is something the user can perform a context click on. - */ - public boolean isContextClickable() { - return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0; - } - - /** - * Returns the class name of the node's implementation, indicating its behavior. - * For example, a button will report "android.widget.Button" meaning it behaves - * like a {@link android.widget.Button}. - */ - public String getClassName() { - return mClassName; - } - - /** - * Returns any content description associated with the node, which semantically describes - * its purpose for accessibility and other uses. - */ - public CharSequence getContentDescription() { - return mContentDescription; - } - - /** - * Returns any text associated with the node that is displayed to the user, or null - * if there is none. - */ - public CharSequence getText() { - return mText != null ? mText.mText : null; - } - - /** - * If {@link #getText()} is non-null, this is where the current selection starts. - */ - public int getTextSelectionStart() { - return mText != null ? mText.mTextSelectionStart : -1; - } - - /** - * If {@link #getText()} is non-null, this is where the current selection starts. - * If there is no selection, returns the same value as {@link #getTextSelectionStart()}, - * indicating the cursor position. - */ - public int getTextSelectionEnd() { - return mText != null ? mText.mTextSelectionEnd : -1; - } - - /** - * If {@link #getText()} is non-null, this is the main text color associated with it. - * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned. - * Note that the text may also contain style spans that modify the color of specific - * parts of the text. - */ - public int getTextColor() { - return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED; - } - - /** - * If {@link #getText()} is non-null, this is the main text background color associated - * with it. - * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned. - * Note that the text may also contain style spans that modify the color of specific - * parts of the text. - */ - public int getTextBackgroundColor() { - return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED; - } - - /** - * If {@link #getText()} is non-null, this is the main text size (in pixels) associated - * with it. - * Note that the text may also contain style spans that modify the size of specific - * parts of the text. - */ - public float getTextSize() { - return mText != null ? mText.mTextSize : 0; - } - - /** - * If {@link #getText()} is non-null, this is the main text style associated - * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD}, - * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or - * {@link #TEXT_STYLE_UNDERLINE}. - * Note that the text may also contain style spans that modify the style of specific - * parts of the text. - */ - public int getTextStyle() { - return mText != null ? mText.mTextStyle : 0; - } - - /** - * Return additional hint text associated with the node; this is typically used with - * a node that takes user input, describing to the user what the input means. - */ - public String getHint() { - return mText != null ? mText.mHint : null; - } - - /** - * Return a Bundle containing optional vendor-specific extension information. - */ - public Bundle getExtras() { - return mExtras; - } - - /** - * Return the number of children this node has. - */ - public int getChildCount() { - return mChildren != null ? mChildren.length : 0; - } - - /** - * Return a child of this node, given an index value from 0 to - * {@link #getChildCount()}-1. - */ - public ViewNode getChildAt(int index) { - return mChildren[index]; - } - } - - static class ViewNodeBuilder extends ViewAssistStructure { - final AssistStructure mAssist; - final ViewNode mNode; - final boolean mAsync; - - ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) { - mAssist = assist; - mNode = node; - mAsync = async; - } - - @Override - public void setId(int id, String packageName, String typeName, String entryName) { - mNode.mId = id; - mNode.mIdPackage = packageName; - mNode.mIdType = typeName; - mNode.mIdEntry = entryName; - } - - @Override - public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) { - mNode.mX = left; - mNode.mY = top; - mNode.mScrollX = scrollX; - mNode.mScrollY = scrollY; - mNode.mWidth = width; - mNode.mHeight = height; - } - - @Override - public void setVisibility(int visibility) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility; - } - - @Override - public void setAssistBlocked(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED) - | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED); - } - - @Override - public void setEnabled(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED) - | (state ? 0 : ViewNode.FLAGS_DISABLED); - } - - @Override - public void setClickable(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE) - | (state ? ViewNode.FLAGS_CLICKABLE : 0); - } - - @Override - public void setLongClickable(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE) - | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0); - } - - @Override - public void setContextClickable(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE) - | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0); - } - - @Override - public void setFocusable(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE) - | (state ? ViewNode.FLAGS_FOCUSABLE : 0); - } - - @Override - public void setFocused(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED) - | (state ? ViewNode.FLAGS_FOCUSED : 0); - } - - @Override - public void setAccessibilityFocused(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) - | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0); - } - - @Override - public void setCheckable(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE) - | (state ? ViewNode.FLAGS_CHECKABLE : 0); - } - - @Override - public void setChecked(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED) - | (state ? ViewNode.FLAGS_CHECKED : 0); - } - - @Override - public void setSelected(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED) - | (state ? ViewNode.FLAGS_SELECTED : 0); - } - - @Override - public void setActivated(boolean state) { - mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED) - | (state ? ViewNode.FLAGS_ACTIVATED : 0); - } - - @Override - public void setClassName(String className) { - mNode.mClassName = className; - } - - @Override - public void setContentDescription(CharSequence contentDescription) { - mNode.mContentDescription = contentDescription; - } - - private final ViewNodeText getNodeText() { - if (mNode.mText != null) { - return mNode.mText; - } - mNode.mText = new ViewNodeText(); - return mNode.mText; - } - - @Override - public void setText(CharSequence text) { - ViewNodeText t = getNodeText(); - t.mText = text; - t.mTextSelectionStart = t.mTextSelectionEnd = -1; - } - - @Override - public void setText(CharSequence text, int selectionStart, int selectionEnd) { - ViewNodeText t = getNodeText(); - t.mText = text; - t.mTextSelectionStart = selectionStart; - t.mTextSelectionEnd = selectionEnd; - } - - @Override - public void setTextStyle(float size, int fgColor, int bgColor, int style) { - ViewNodeText t = getNodeText(); - t.mTextColor = fgColor; - t.mTextBackgroundColor = bgColor; - t.mTextSize = size; - t.mTextStyle = style; - } - - @Override - public void setHint(CharSequence hint) { - getNodeText().mHint = hint != null ? hint.toString() : null; - } - - @Override - public CharSequence getText() { - return mNode.mText != null ? mNode.mText.mText : null; - } - - @Override - public int getTextSelectionStart() { - return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1; - } - - @Override - public int getTextSelectionEnd() { - return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1; - } - - @Override - public CharSequence getHint() { - return mNode.mText != null ? mNode.mText.mHint : null; - } - - @Override - public Bundle getExtras() { - if (mNode.mExtras != null) { - return mNode.mExtras; - } - mNode.mExtras = new Bundle(); - return mNode.mExtras; - } - - @Override - public boolean hasExtras() { - return mNode.mExtras != null; - } - - @Override - public void setChildCount(int num) { - mNode.mChildren = new ViewNode[num]; - } - - @Override - public int addChildCount(int num) { - if (mNode.mChildren == null) { - setChildCount(num); - return 0; - } - final int start = mNode.mChildren.length; - ViewNode[] newArray = new ViewNode[start + num]; - System.arraycopy(mNode.mChildren, 0, newArray, 0, start); - mNode.mChildren = newArray; - return start; - } - - @Override - public int getChildCount() { - return mNode.mChildren != null ? mNode.mChildren.length : 0; - } - - @Override - public ViewAssistStructure newChild(int index) { - ViewNode node = new ViewNode(); - mNode.mChildren[index] = node; - return new ViewNodeBuilder(mAssist, node, false); - } - - @Override - public ViewAssistStructure asyncNewChild(int index) { - synchronized (mAssist) { - ViewNode node = new ViewNode(); - mNode.mChildren[index] = node; - ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true); - mAssist.mPendingAsyncChildren.add(builder); - return builder; - } - } - - @Override - public void asyncCommit() { - synchronized (mAssist) { - if (!mAsync) { - throw new IllegalStateException("Child " + this - + " was not created with ViewAssistStructure.asyncNewChild"); - } - if (!mAssist.mPendingAsyncChildren.remove(this)) { - throw new IllegalStateException("Child " + this + " already committed"); - } - mAssist.notifyAll(); - } - } - - @Override - public Rect getTempRect() { - return mAssist.mTmpRect; - } - } - - /** @hide */ - public AssistStructure(Activity activity) { - mHaveData = true; - mActivityComponent = activity.getComponentName(); - ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( - activity.getActivityToken()); - for (int i=0; i<views.size(); i++) { - ViewRootImpl root = views.get(i); - mWindowNodes.add(new WindowNode(this, root)); - } - } - - public AssistStructure() { - mHaveData = true; - mActivityComponent = null; - } - - /** @hide */ - public AssistStructure(Parcel in) { - mReceiveChannel = in.readStrongBinder(); - } - - /** @hide */ - public void dump() { - Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString()); - final int N = getWindowNodeCount(); - for (int i=0; i<N; i++) { - WindowNode node = getWindowNodeAt(i); - Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop() - + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle()); - dump(" ", node.getRootViewNode()); - } - } - - void dump(String prefix, ViewNode node) { - Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop() - + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName()); - int id = node.getId(); - if (id != 0) { - StringBuilder sb = new StringBuilder(); - sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id)); - String entry = node.getIdEntry(); - if (entry != null) { - String type = node.getIdType(); - String pkg = node.getIdPackage(); - sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type); - sb.append("/"); sb.append(entry); - } - Log.i(TAG, sb.toString()); - } - int scrollX = node.getScrollX(); - int scrollY = node.getScrollY(); - if (scrollX != 0 || scrollY != 0) { - Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY); - } - CharSequence contentDescription = node.getContentDescription(); - if (contentDescription != null) { - Log.i(TAG, prefix + " Content description: " + contentDescription); - } - CharSequence text = node.getText(); - if (text != null) { - Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-" - + node.getTextSelectionEnd() + "): " + text); - Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #" - + node.getTextStyle()); - Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor()) - + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor())); - } - String hint = node.getHint(); - if (hint != null) { - Log.i(TAG, prefix + " Hint: " + hint); - } - Bundle extras = node.getExtras(); - if (extras != null) { - Log.i(TAG, prefix + " Extras: " + extras); - } - final int NCHILDREN = node.getChildCount(); - if (NCHILDREN > 0) { - Log.i(TAG, prefix + " Children:"); - String cprefix = prefix + " "; - for (int i=0; i<NCHILDREN; i++) { - ViewNode cnode = node.getChildAt(i); - dump(cprefix, cnode); - } - } - } - - /** - * @hide - * Retrieve the framework-generated AssistStructure that is stored within - * the Bundle filled in by {@link Activity#onProvideAssistData}. - */ - public static android.app.assist.AssistStructure getAssistStructure(Bundle assistBundle) { - return assistBundle.getParcelable(ASSIST_KEY); - } - - /** - * Return the activity this AssistStructure came from. - */ - public ComponentName getActivityComponent() { - ensureData(); - return mActivityComponent; - } - - /** - * Return the number of window contents that have been collected in this assist data. - */ - public int getWindowNodeCount() { - ensureData(); - return mWindowNodes.size(); - } - - /** - * Return one of the windows in the assist data. - * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1. - * @hide - */ - public WindowNode getWindowNodeAt(int index) { - ensureData(); - return mWindowNodes.get(index); - } - - /** @hide */ - public void ensureData() { - if (mHaveData) { - return; - } - mHaveData = true; - Parcel data = Parcel.obtain(); - Parcel reply = Parcel.obtain(); - data.writeInterfaceToken(DESCRIPTOR); - try { - mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0); - } catch (RemoteException e) { - Log.w(TAG, "Failure reading AssistStructure data", e); - return; - } - readContentFromParcel(reply); - data.recycle(); - reply.recycle(); - } - - void writeContentToParcel(Parcel out, int flags) { - // First make sure all content has been created. - boolean skipStructure = false; - synchronized (this) { - long endTime = SystemClock.uptimeMillis() + 5000; - long now; - while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) { - try { - wait(endTime-now); - } catch (InterruptedException e) { - } - } - if (mPendingAsyncChildren.size() > 0) { - // We waited too long, assume none of the assist structure is valid. - skipStructure = true; - } - } - int start = out.dataPosition(); - PooledStringWriter pwriter = new PooledStringWriter(out); - ComponentName.writeToParcel(mActivityComponent, out); - final int N = skipStructure ? 0 : mWindowNodes.size(); - out.writeInt(N); - for (int i=0; i<N; i++) { - mWindowNodes.get(i).writeToParcel(out, pwriter); - } - pwriter.finish(); - Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes"); - } - - void readContentFromParcel(Parcel in) { - PooledStringReader preader = new PooledStringReader(in); - mActivityComponent = ComponentName.readFromParcel(in); - final int N = in.readInt(); - for (int i=0; i<N; i++) { - mWindowNodes.add(new WindowNode(in, preader)); - } - //dump(); - } -} diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 5a0d246afc64..aa6834532a3c 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3586,12 +3586,19 @@ public class Notification implements Parcelable * object. */ public Notification build() { + if (mSmallIcon != null) { + mSmallIcon.convertToAshmem(); + } + if (mLargeIcon != null) { + mLargeIcon.convertToAshmem(); + } mOriginatingUserId = mContext.getUserId(); mHasThreeLines = hasThreeLines(); Notification n = buildUnstyled(); if (mStyle != null) { + mStyle.purgeResources(); n = mStyle.buildStyled(n); } @@ -3790,6 +3797,11 @@ public class Notification implements Parcelable return wip; } + /** + * @hide + */ + public void purgeResources() {} + // The following methods are split out so we can re-create notification partially. /** * @hide @@ -3901,8 +3913,21 @@ public class Notification implements Parcelable return this; } - private RemoteViews makeBigContentView() { + /** + * @hide + */ + @Override + public void purgeResources() { + super.purgeResources(); + if (mPicture != null && mPicture.isMutable()) { + mPicture = mPicture.createAshmemBitmap(); + } + if (mBigLargeIcon != null) { + mBigLargeIcon.convertToAshmem(); + } + } + private RemoteViews makeBigContentView() { // Replace mLargeIcon with mBigLargeIcon if mBigLargeIconSet // This covers the following cases: // 1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java index 9cc399da2580..abb82444675d 100644 --- a/core/java/android/app/VoiceInteractor.java +++ b/core/java/android/app/VoiceInteractor.java @@ -225,6 +225,9 @@ public final class VoiceInteractor { * Cancel this active request. */ public void cancel() { + if (mRequestInterface == null) { + throw new IllegalStateException("Request " + this + " is no longer active"); + } try { mRequestInterface.cancel(); } catch (RemoteException e) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 125708a66249..4d1cff58714a 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -3972,6 +3972,7 @@ public class DevicePolicyManager { * <li>{@link Settings.Global#STAY_ON_WHILE_PLUGGED_IN} * This setting is only available from {@link android.os.Build.VERSION_CODES#MNC} onwards * and can only be set if {@link #setMaximumTimeToLock} is not used to set a timeout.</li> + * <li>{@link Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li> * </ul> * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. @@ -4349,6 +4350,12 @@ public class DevicePolicyManager { * group that the runtime permission belongs to. This method can only be called * by a profile or device owner. * + * <p/>Setting the grant state to {@link #PERMISSION_GRANT_STATE_DEFAULT default} does not + * revoke the permission. It retains the previous grant, if any. + * + * <p/>Permissions can be granted or revoked only for applications built with a + * {@code targetSdkVersion} of {@link android.os.Build.VERSION_CODES#MNC} or later. + * * @param admin Which profile or device owner this request is associated with. * @param packageName The application to grant or revoke a permission to. * @param permission The permission to grant or revoke. diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java index c7e7330efa87..07b2d575261c 100644 --- a/core/java/android/app/assist/AssistContent.java +++ b/core/java/android/app/assist/AssistContent.java @@ -1,24 +1,184 @@ package android.app.assist; +import android.content.ClipData; import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; /** - * New home for AssistContent. + * Holds information about the content an application is viewing, to hand to an + * assistant at the user's request. This is filled in by + * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. */ -public final class AssistContent extends android.app.AssistContent implements Parcelable { +@Deprecated +public class AssistContent implements Parcelable { + private boolean mIsAppProvidedIntent = false; + private Intent mIntent; + private String mStructuredData; + private ClipData mClipData; + private Uri mUri; + private final Bundle mExtras; - /** @hide */ public AssistContent() { + mExtras = new Bundle(); } - public AssistContent(Parcel in) { - super(in); + /** + * @hide + * Called by {@link android.app.ActivityThread} to set the default Intent based on + * {@link android.app.Activity#getIntent Activity.getIntent}. + * + * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW} + * of a web (http or https scheme) URI.</p> + */ + public void setDefaultIntent(Intent intent) { + mIntent = intent; + setWebUri(null); + if (intent != null && Intent.ACTION_VIEW.equals(intent.getAction())) { + Uri uri = intent.getData(); + if (uri != null) { + if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) { + setWebUri(uri); + } + } + } + } + + /** + * Sets the Intent associated with the content, describing the current top-level context of + * the activity. If this contains a reference to a piece of data related to the activity, + * be sure to set {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} so the accessibility + * service can access it. + */ + public void setIntent(Intent intent) { + mIsAppProvidedIntent = true; + mIntent = intent; } + /** + * Returns the current {@link #setIntent} if one is set, else the default Intent obtained from + * {@link android.app.Activity#getIntent Activity.getIntent}. Can be modified in-place. + */ public Intent getIntent() { - return super.getIntent(); + return mIntent; + } + + /** + * Returns whether or not the current Intent was explicitly provided in + * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. If not, + * the Intent was automatically set based on + * {@link android.app.Activity#getIntent Activity.getIntent}. + */ + public boolean isAppProvidedIntent() { + return mIsAppProvidedIntent; + } + + /** + * Optional additional content items that are involved with + * the current UI. Access to this content will be granted to the assistant as if you + * are sending it through an Intent with {@link Intent#FLAG_GRANT_READ_URI_PERMISSION}. + */ + public void setClipData(ClipData clip) { + mClipData = clip; + } + + /** + * Return the current {@link #setClipData}, which you can modify in-place. + */ + public ClipData getClipData() { + return mClipData; + } + + /** + * Sets optional structured data regarding the content being viewed. The provided data + * must be a string represented with <a href="http://json-ld.org/">JSON-LD</a> using the + * <a href="http://schema.org/">schema.org</a> vocabulary. + */ + public void setStructuredData(String structuredData) { + mStructuredData = structuredData; + } + + /** + * Returns the current {@link #setStructuredData}. + */ + public String getStructuredData() { + return mStructuredData; + } + + /** + * Set a web URI associated with the current data being shown to the user. + * This URI could be opened in a web browser, or in the app as an + * {@link Intent#ACTION_VIEW} Intent, to show the same data that is currently + * being displayed by it. The URI here should be something that is transportable + * off the device into other environments to acesss the same data as is currently + * being shown in the app; if the app does not have such a representation, it should + * leave the null and only report the local intent and clip data. + */ + public void setWebUri(Uri uri) { + mUri = uri; + } + + /** + * Return the content's web URI as per {@link #setWebUri(android.net.Uri)}, or null if + * there is none. + */ + public Uri getWebUri() { + return mUri; + } + + /** + * Return Bundle for extra vendor-specific data that can be modified and examined. + */ + public Bundle getExtras() { + return mExtras; + } + + AssistContent(Parcel in) { + if (in.readInt() != 0) { + mIntent = Intent.CREATOR.createFromParcel(in); + } + if (in.readInt() != 0) { + mClipData = ClipData.CREATOR.createFromParcel(in); + } + if (in.readInt() != 0) { + mUri = Uri.CREATOR.createFromParcel(in); + } + if (in.readInt() != 0) { + mStructuredData = in.readString(); + } + mIsAppProvidedIntent = in.readInt() == 1; + mExtras = in.readBundle(); + } + + void writeToParcelInternal(Parcel dest, int flags) { + if (mIntent != null) { + dest.writeInt(1); + mIntent.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + if (mClipData != null) { + dest.writeInt(1); + mClipData.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + if (mUri != null) { + dest.writeInt(1); + mUri.writeToParcel(dest, flags); + } else { + dest.writeInt(0); + } + if (mStructuredData != null) { + dest.writeInt(1); + dest.writeString(mStructuredData); + } else { + dest.writeInt(0); + } + dest.writeInt(mIsAppProvidedIntent ? 1 : 0); + dest.writeBundle(mExtras); } @Override diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 1677e9576b6e..284dfd62173a 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -1,28 +1,1038 @@ package android.app.assist; import android.app.Activity; +import android.content.ComponentName; +import android.graphics.Rect; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; +import android.os.PooledStringReader; +import android.os.PooledStringWriter; +import android.os.RemoteException; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.view.ViewStructure; +import android.view.ViewRootImpl; +import android.view.WindowManager; +import android.view.WindowManagerGlobal; + +import java.util.ArrayList; /** - * New home for AssistStructure. + * Assist data automatically created by the platform's implementation + * of {@link android.app.Activity#onProvideAssistData}. */ -public final class AssistStructure extends android.app.AssistStructure implements Parcelable { +public class AssistStructure implements Parcelable { + static final String TAG = "AssistStructure"; - public AssistStructure() { + boolean mHaveData; + + ComponentName mActivityComponent; + + final ArrayList<WindowNode> mWindowNodes = new ArrayList<>(); + + final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>(); + + SendChannel mSendChannel; + IBinder mReceiveChannel; + + Rect mTmpRect = new Rect(); + + static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1; + static final String DESCRIPTOR = "android.app.AssistStructure"; + + final class SendChannel extends Binder { + @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) + throws RemoteException { + if (code == TRANSACTION_XFER) { + data.enforceInterface(DESCRIPTOR); + writeContentToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); + return true; + } else { + return super.onTransact(code, data, reply, flags); + } + } + } + + final static class ViewNodeText { + CharSequence mText; + int mTextSelectionStart; + int mTextSelectionEnd; + int mTextColor; + int mTextBackgroundColor; + float mTextSize; + int mTextStyle; + String mHint; + + ViewNodeText() { + } + + ViewNodeText(Parcel in) { + mText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + mTextSelectionStart = in.readInt(); + mTextSelectionEnd = in.readInt(); + mTextColor = in.readInt(); + mTextBackgroundColor = in.readInt(); + mTextSize = in.readFloat(); + mTextStyle = in.readInt(); + mHint = in.readString(); + } + + void writeToParcel(Parcel out) { + TextUtils.writeToParcel(mText, out, 0); + out.writeInt(mTextSelectionStart); + out.writeInt(mTextSelectionEnd); + out.writeInt(mTextColor); + out.writeInt(mTextBackgroundColor); + out.writeFloat(mTextSize); + out.writeInt(mTextStyle); + out.writeString(mHint); + } + } + + /** + * Describes a window in the assist data. + */ + static public class WindowNode { + final int mX; + final int mY; + final int mWidth; + final int mHeight; + final CharSequence mTitle; + final int mDisplayId; + final ViewNode mRoot; + + WindowNode(AssistStructure assist, ViewRootImpl root) { + View view = root.getView(); + Rect rect = new Rect(); + view.getBoundsOnScreen(rect); + mX = rect.left - view.getLeft(); + mY = rect.top - view.getTop(); + mWidth = rect.width(); + mHeight = rect.height(); + mTitle = root.getTitle(); + mDisplayId = root.getDisplayId(); + mRoot = new ViewNode(); + ViewNodeBuilder builder = new ViewNodeBuilder(assist, mRoot, false); + if ((root.getWindowFlags()& WindowManager.LayoutParams.FLAG_SECURE) != 0) { + // This is a secure window, so it doesn't want a screenshot, and that + // means we should also not copy out its view hierarchy. + view.onProvideStructure(builder); + builder.setAssistBlocked(true); + return; + } + view.dispatchProvideStructure(builder); + } + + WindowNode(Parcel in, PooledStringReader preader) { + mX = in.readInt(); + mY = in.readInt(); + mWidth = in.readInt(); + mHeight = in.readInt(); + mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + mDisplayId = in.readInt(); + mRoot = new ViewNode(in, preader); + } + + void writeToParcel(Parcel out, PooledStringWriter pwriter) { + out.writeInt(mX); + out.writeInt(mY); + out.writeInt(mWidth); + out.writeInt(mHeight); + TextUtils.writeToParcel(mTitle, out, 0); + out.writeInt(mDisplayId); + mRoot.writeToParcel(out, pwriter); + } + + /** + * Returns the left edge of the window, in pixels, relative to the left + * edge of the screen. + */ + public int getLeft() { + return mX; + } + + /** + * Returns the top edge of the window, in pixels, relative to the top + * edge of the screen. + */ + public int getTop() { + return mY; + } + + /** + * Returns the total width of the window in pixels. + */ + public int getWidth() { + return mWidth; + } + + /** + * Returns the total height of the window in pixels. + */ + public int getHeight() { + return mHeight; + } + + /** + * Returns the title associated with the window, if it has one. + */ + public CharSequence getTitle() { + return mTitle; + } + + /** + * Returns the ID of the display this window is on, for use with + * {@link android.hardware.display.DisplayManager#getDisplay DisplayManager.getDisplay()}. + */ + public int getDisplayId() { + return mDisplayId; + } + + /** + * Returns the {@link ViewNode} containing the root content of the window. + */ + public ViewNode getRootViewNode() { + return mRoot; + } + } + + /** + * Describes a single view in the assist data. + */ + static public class ViewNode { + /** + * Magic value for text color that has not been defined, which is very unlikely + * to be confused with a real text color. + */ + public static final int TEXT_COLOR_UNDEFINED = 1; + + public static final int TEXT_STYLE_BOLD = 1<<0; + public static final int TEXT_STYLE_ITALIC = 1<<1; + public static final int TEXT_STYLE_UNDERLINE = 1<<2; + public static final int TEXT_STYLE_STRIKE_THRU = 1<<3; + + int mId; + String mIdPackage; + String mIdType; + String mIdEntry; + int mX; + int mY; + int mScrollX; + int mScrollY; + int mWidth; + int mHeight; + + static final int FLAGS_DISABLED = 0x00000001; + static final int FLAGS_VISIBILITY_MASK = View.VISIBLE|View.INVISIBLE|View.GONE; + static final int FLAGS_FOCUSABLE = 0x00000010; + static final int FLAGS_FOCUSED = 0x00000020; + static final int FLAGS_ACCESSIBILITY_FOCUSED = 0x04000000; + static final int FLAGS_SELECTED = 0x00000040; + static final int FLAGS_ASSIST_BLOCKED = 0x00000080; + static final int FLAGS_ACTIVATED = 0x40000000; + static final int FLAGS_CHECKABLE = 0x00000100; + static final int FLAGS_CHECKED = 0x00000200; + static final int FLAGS_CLICKABLE = 0x00004000; + static final int FLAGS_LONG_CLICKABLE = 0x00200000; + static final int FLAGS_CONTEXT_CLICKABLE = 0x00400000; + + int mFlags; + + String mClassName; + CharSequence mContentDescription; + + ViewNodeText mText; + Bundle mExtras; + + ViewNode[] mChildren; + + ViewNode() { + } + + ViewNode(Parcel in, PooledStringReader preader) { + mId = in.readInt(); + if (mId != 0) { + mIdEntry = preader.readString(); + if (mIdEntry != null) { + mIdType = preader.readString(); + mIdPackage = preader.readString(); + } else { + mIdPackage = mIdType = null; + } + } else { + mIdPackage = mIdType = mIdEntry = null; + } + mX = in.readInt(); + mY = in.readInt(); + mScrollX = in.readInt(); + mScrollY = in.readInt(); + mWidth = in.readInt(); + mHeight = in.readInt(); + mFlags = in.readInt(); + mClassName = preader.readString(); + mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); + if (in.readInt() != 0) { + mText = new ViewNodeText(in); + } else { + mText = null; + } + mExtras = in.readBundle(); + final int NCHILDREN = in.readInt(); + if (NCHILDREN > 0) { + mChildren = new ViewNode[NCHILDREN]; + for (int i=0; i<NCHILDREN; i++) { + mChildren[i] = new ViewNode(in, preader); + } + } else { + mChildren = null; + } + } + + void writeToParcel(Parcel out, PooledStringWriter pwriter) { + out.writeInt(mId); + if (mId != 0) { + pwriter.writeString(mIdEntry); + if (mIdEntry != null) { + pwriter.writeString(mIdType); + pwriter.writeString(mIdPackage); + } + } + out.writeInt(mX); + out.writeInt(mY); + out.writeInt(mScrollX); + out.writeInt(mScrollY); + out.writeInt(mWidth); + out.writeInt(mHeight); + out.writeInt(mFlags); + pwriter.writeString(mClassName); + TextUtils.writeToParcel(mContentDescription, out, 0); + if (mText != null) { + out.writeInt(1); + mText.writeToParcel(out); + } else { + out.writeInt(0); + } + out.writeBundle(mExtras); + if (mChildren != null) { + final int NCHILDREN = mChildren.length; + out.writeInt(NCHILDREN); + for (int i=0; i<NCHILDREN; i++) { + mChildren[i].writeToParcel(out, pwriter); + } + } else { + out.writeInt(0); + } + } + + /** + * Returns the ID associated with this view, as per {@link View#getId() View.getId()}. + */ + public int getId() { + return mId; + } + + /** + * If {@link #getId()} is a resource identifier, this is the package name of that + * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} + * for more information. + */ + public String getIdPackage() { + return mIdPackage; + } + + /** + * If {@link #getId()} is a resource identifier, this is the type name of that + * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} + * for more information. + */ + public String getIdType() { + return mIdType; + } + + /** + * If {@link #getId()} is a resource identifier, this is the entry name of that + * identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId} + * for more information. + */ + public String getIdEntry() { + return mIdEntry; + } + + /** + * Returns the left edge of this view, in pixels, relative to the left edge of its parent. + */ + public int getLeft() { + return mX; + } + + /** + * Returns the top edge of this view, in pixels, relative to the top edge of its parent. + */ + public int getTop() { + return mY; + } + + /** + * Returns the current X scroll offset of this view, as per + * {@link android.view.View#getScrollX() View.getScrollX()}. + */ + public int getScrollX() { + return mScrollX; + } + + /** + * Returns the current Y scroll offset of this view, as per + * {@link android.view.View#getScrollX() View.getScrollY()}. + */ + public int getScrollY() { + return mScrollY; + } + + /** + * Returns the width of this view, in pixels. + */ + public int getWidth() { + return mWidth; + } + + /** + * Returns the height of this view, in pixels. + */ + public int getHeight() { + return mHeight; + } + + /** + * Returns the visibility mode of this view, as per + * {@link android.view.View#getVisibility() View.getVisibility()}. + */ + public int getVisibility() { + return mFlags&ViewNode.FLAGS_VISIBILITY_MASK; + } + + /** + * Returns true if assist data has been blocked starting at this node in the hierarchy. + */ + public boolean isAssistBlocked() { + return (mFlags&ViewNode.FLAGS_ASSIST_BLOCKED) == 0; + } + + /** + * Returns true if this node is in an enabled state. + */ + public boolean isEnabled() { + return (mFlags&ViewNode.FLAGS_DISABLED) == 0; + } + + /** + * Returns true if this node is clickable by the user. + */ + public boolean isClickable() { + return (mFlags&ViewNode.FLAGS_CLICKABLE) != 0; + } + + /** + * Returns true if this node can take input focus. + */ + public boolean isFocusable() { + return (mFlags&ViewNode.FLAGS_FOCUSABLE) != 0; + } + + /** + * Returns true if this node currently had input focus at the time that the + * structure was collected. + */ + public boolean isFocused() { + return (mFlags&ViewNode.FLAGS_FOCUSED) != 0; + } + + /** + * Returns true if this node currently had accessibility focus at the time that the + * structure was collected. + */ + public boolean isAccessibilityFocused() { + return (mFlags&ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) != 0; + } + + /** + * Returns true if this node represents something that is checkable by the user. + */ + public boolean isCheckable() { + return (mFlags&ViewNode.FLAGS_CHECKABLE) != 0; + } + + /** + * Returns true if this node is currently in a checked state. + */ + public boolean isChecked() { + return (mFlags&ViewNode.FLAGS_CHECKED) != 0; + } + + /** + * Returns true if this node has currently been selected by the user. + */ + public boolean isSelected() { + return (mFlags&ViewNode.FLAGS_SELECTED) != 0; + } + + /** + * Returns true if this node has currently been activated by the user. + */ + public boolean isActivated() { + return (mFlags&ViewNode.FLAGS_ACTIVATED) != 0; + } + + /** + * Returns true if this node is something the user can perform a long click/press on. + */ + public boolean isLongClickable() { + return (mFlags&ViewNode.FLAGS_LONG_CLICKABLE) != 0; + } + + /** + * Returns true if this node is something the user can perform a context click on. + */ + public boolean isContextClickable() { + return (mFlags&ViewNode.FLAGS_CONTEXT_CLICKABLE) != 0; + } + + /** + * Returns the class name of the node's implementation, indicating its behavior. + * For example, a button will report "android.widget.Button" meaning it behaves + * like a {@link android.widget.Button}. + */ + public String getClassName() { + return mClassName; + } + + /** + * Returns any content description associated with the node, which semantically describes + * its purpose for accessibility and other uses. + */ + public CharSequence getContentDescription() { + return mContentDescription; + } + + /** + * Returns any text associated with the node that is displayed to the user, or null + * if there is none. + */ + public CharSequence getText() { + return mText != null ? mText.mText : null; + } + + /** + * If {@link #getText()} is non-null, this is where the current selection starts. + */ + public int getTextSelectionStart() { + return mText != null ? mText.mTextSelectionStart : -1; + } + + /** + * If {@link #getText()} is non-null, this is where the current selection starts. + * If there is no selection, returns the same value as {@link #getTextSelectionStart()}, + * indicating the cursor position. + */ + public int getTextSelectionEnd() { + return mText != null ? mText.mTextSelectionEnd : -1; + } + + /** + * If {@link #getText()} is non-null, this is the main text color associated with it. + * If there is no text color, {@link #TEXT_COLOR_UNDEFINED} is returned. + * Note that the text may also contain style spans that modify the color of specific + * parts of the text. + */ + public int getTextColor() { + return mText != null ? mText.mTextColor : TEXT_COLOR_UNDEFINED; + } + + /** + * If {@link #getText()} is non-null, this is the main text background color associated + * with it. + * If there is no text background color, {@link #TEXT_COLOR_UNDEFINED} is returned. + * Note that the text may also contain style spans that modify the color of specific + * parts of the text. + */ + public int getTextBackgroundColor() { + return mText != null ? mText.mTextBackgroundColor : TEXT_COLOR_UNDEFINED; + } + + /** + * If {@link #getText()} is non-null, this is the main text size (in pixels) associated + * with it. + * Note that the text may also contain style spans that modify the size of specific + * parts of the text. + */ + public float getTextSize() { + return mText != null ? mText.mTextSize : 0; + } + + /** + * If {@link #getText()} is non-null, this is the main text style associated + * with it, containing a bit mask of {@link #TEXT_STYLE_BOLD}, + * {@link #TEXT_STYLE_BOLD}, {@link #TEXT_STYLE_STRIKE_THRU}, and/or + * {@link #TEXT_STYLE_UNDERLINE}. + * Note that the text may also contain style spans that modify the style of specific + * parts of the text. + */ + public int getTextStyle() { + return mText != null ? mText.mTextStyle : 0; + } + + /** + * Return additional hint text associated with the node; this is typically used with + * a node that takes user input, describing to the user what the input means. + */ + public String getHint() { + return mText != null ? mText.mHint : null; + } + + /** + * Return a Bundle containing optional vendor-specific extension information. + */ + public Bundle getExtras() { + return mExtras; + } + + /** + * Return the number of children this node has. + */ + public int getChildCount() { + return mChildren != null ? mChildren.length : 0; + } + + /** + * Return a child of this node, given an index value from 0 to + * {@link #getChildCount()}-1. + */ + public ViewNode getChildAt(int index) { + return mChildren[index]; + } + } + + static class ViewNodeBuilder extends ViewStructure { + final AssistStructure mAssist; + final ViewNode mNode; + final boolean mAsync; + + ViewNodeBuilder(AssistStructure assist, ViewNode node, boolean async) { + mAssist = assist; + mNode = node; + mAsync = async; + } + + @Override + public void setId(int id, String packageName, String typeName, String entryName) { + mNode.mId = id; + mNode.mIdPackage = packageName; + mNode.mIdType = typeName; + mNode.mIdEntry = entryName; + } + + @Override + public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) { + mNode.mX = left; + mNode.mY = top; + mNode.mScrollX = scrollX; + mNode.mScrollY = scrollY; + mNode.mWidth = width; + mNode.mHeight = height; + } + + @Override + public void setVisibility(int visibility) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_VISIBILITY_MASK) | visibility; + } + + @Override + public void setAssistBlocked(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ASSIST_BLOCKED) + | (state ? 0 : ViewNode.FLAGS_ASSIST_BLOCKED); + } + + @Override + public void setEnabled(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_DISABLED) + | (state ? 0 : ViewNode.FLAGS_DISABLED); + } + + @Override + public void setClickable(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CLICKABLE) + | (state ? ViewNode.FLAGS_CLICKABLE : 0); + } + + @Override + public void setLongClickable(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_LONG_CLICKABLE) + | (state ? ViewNode.FLAGS_LONG_CLICKABLE : 0); + } + + @Override + public void setContextClickable(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CONTEXT_CLICKABLE) + | (state ? ViewNode.FLAGS_CONTEXT_CLICKABLE : 0); + } + + @Override + public void setFocusable(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSABLE) + | (state ? ViewNode.FLAGS_FOCUSABLE : 0); + } + + @Override + public void setFocused(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_FOCUSED) + | (state ? ViewNode.FLAGS_FOCUSED : 0); + } + + @Override + public void setAccessibilityFocused(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACCESSIBILITY_FOCUSED) + | (state ? ViewNode.FLAGS_ACCESSIBILITY_FOCUSED : 0); + } + + @Override + public void setCheckable(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKABLE) + | (state ? ViewNode.FLAGS_CHECKABLE : 0); + } + + @Override + public void setChecked(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_CHECKED) + | (state ? ViewNode.FLAGS_CHECKED : 0); + } + + @Override + public void setSelected(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_SELECTED) + | (state ? ViewNode.FLAGS_SELECTED : 0); + } + + @Override + public void setActivated(boolean state) { + mNode.mFlags = (mNode.mFlags&~ViewNode.FLAGS_ACTIVATED) + | (state ? ViewNode.FLAGS_ACTIVATED : 0); + } + + @Override + public void setClassName(String className) { + mNode.mClassName = className; + } + + @Override + public void setContentDescription(CharSequence contentDescription) { + mNode.mContentDescription = contentDescription; + } + + private final ViewNodeText getNodeText() { + if (mNode.mText != null) { + return mNode.mText; + } + mNode.mText = new ViewNodeText(); + return mNode.mText; + } + + @Override + public void setText(CharSequence text) { + ViewNodeText t = getNodeText(); + t.mText = text; + t.mTextSelectionStart = t.mTextSelectionEnd = -1; + } + + @Override + public void setText(CharSequence text, int selectionStart, int selectionEnd) { + ViewNodeText t = getNodeText(); + t.mText = text; + t.mTextSelectionStart = selectionStart; + t.mTextSelectionEnd = selectionEnd; + } + + @Override + public void setTextStyle(float size, int fgColor, int bgColor, int style) { + ViewNodeText t = getNodeText(); + t.mTextColor = fgColor; + t.mTextBackgroundColor = bgColor; + t.mTextSize = size; + t.mTextStyle = style; + } + + @Override + public void setHint(CharSequence hint) { + getNodeText().mHint = hint != null ? hint.toString() : null; + } + + @Override + public CharSequence getText() { + return mNode.mText != null ? mNode.mText.mText : null; + } + + @Override + public int getTextSelectionStart() { + return mNode.mText != null ? mNode.mText.mTextSelectionStart : -1; + } + + @Override + public int getTextSelectionEnd() { + return mNode.mText != null ? mNode.mText.mTextSelectionEnd : -1; + } + + @Override + public CharSequence getHint() { + return mNode.mText != null ? mNode.mText.mHint : null; + } + + @Override + public Bundle getExtras() { + if (mNode.mExtras != null) { + return mNode.mExtras; + } + mNode.mExtras = new Bundle(); + return mNode.mExtras; + } + + @Override + public boolean hasExtras() { + return mNode.mExtras != null; + } + + @Override + public void setChildCount(int num) { + mNode.mChildren = new ViewNode[num]; + } + + @Override + public int addChildCount(int num) { + if (mNode.mChildren == null) { + setChildCount(num); + return 0; + } + final int start = mNode.mChildren.length; + ViewNode[] newArray = new ViewNode[start + num]; + System.arraycopy(mNode.mChildren, 0, newArray, 0, start); + mNode.mChildren = newArray; + return start; + } + + @Override + public int getChildCount() { + return mNode.mChildren != null ? mNode.mChildren.length : 0; + } + + @Override + public ViewStructure newChild(int index) { + ViewNode node = new ViewNode(); + mNode.mChildren[index] = node; + return new ViewNodeBuilder(mAssist, node, false); + } + + @Override + public ViewStructure asyncNewChild(int index) { + synchronized (mAssist) { + ViewNode node = new ViewNode(); + mNode.mChildren[index] = node; + ViewNodeBuilder builder = new ViewNodeBuilder(mAssist, node, true); + mAssist.mPendingAsyncChildren.add(builder); + return builder; + } + } + + @Override + public void asyncCommit() { + synchronized (mAssist) { + if (!mAsync) { + throw new IllegalStateException("Child " + this + + " was not created with ViewStructure.asyncNewChild"); + } + if (!mAssist.mPendingAsyncChildren.remove(this)) { + throw new IllegalStateException("Child " + this + " already committed"); + } + mAssist.notifyAll(); + } + } + + @Override + public Rect getTempRect() { + return mAssist.mTmpRect; + } } /** @hide */ public AssistStructure(Activity activity) { - super(activity); + mHaveData = true; + mActivityComponent = activity.getComponentName(); + ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( + activity.getActivityToken()); + for (int i=0; i<views.size(); i++) { + ViewRootImpl root = views.get(i); + mWindowNodes.add(new WindowNode(this, root)); + } + } + + public AssistStructure() { + mHaveData = true; + mActivityComponent = null; } - AssistStructure(Parcel in) { - super(in); + /** @hide */ + public AssistStructure(Parcel in) { + mReceiveChannel = in.readStrongBinder(); } + /** @hide */ + public void dump() { + Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString()); + final int N = getWindowNodeCount(); + for (int i=0; i<N; i++) { + WindowNode node = getWindowNodeAt(i); + Log.i(TAG, "Window #" + i + " [" + node.getLeft() + "," + node.getTop() + + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getTitle()); + dump(" ", node.getRootViewNode()); + } + } + + void dump(String prefix, ViewNode node) { + Log.i(TAG, prefix + "View [" + node.getLeft() + "," + node.getTop() + + " " + node.getWidth() + "x" + node.getHeight() + "]" + " " + node.getClassName()); + int id = node.getId(); + if (id != 0) { + StringBuilder sb = new StringBuilder(); + sb.append(prefix); sb.append(" ID: #"); sb.append(Integer.toHexString(id)); + String entry = node.getIdEntry(); + if (entry != null) { + String type = node.getIdType(); + String pkg = node.getIdPackage(); + sb.append(" "); sb.append(pkg); sb.append(":"); sb.append(type); + sb.append("/"); sb.append(entry); + } + Log.i(TAG, sb.toString()); + } + int scrollX = node.getScrollX(); + int scrollY = node.getScrollY(); + if (scrollX != 0 || scrollY != 0) { + Log.i(TAG, prefix + " Scroll: " + scrollX + "," + scrollY); + } + CharSequence contentDescription = node.getContentDescription(); + if (contentDescription != null) { + Log.i(TAG, prefix + " Content description: " + contentDescription); + } + CharSequence text = node.getText(); + if (text != null) { + Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-" + + node.getTextSelectionEnd() + "): " + text); + Log.i(TAG, prefix + " Text size: " + node.getTextSize() + " , style: #" + + node.getTextStyle()); + Log.i(TAG, prefix + " Text color fg: #" + Integer.toHexString(node.getTextColor()) + + ", bg: #" + Integer.toHexString(node.getTextBackgroundColor())); + } + String hint = node.getHint(); + if (hint != null) { + Log.i(TAG, prefix + " Hint: " + hint); + } + Bundle extras = node.getExtras(); + if (extras != null) { + Log.i(TAG, prefix + " Extras: " + extras); + } + final int NCHILDREN = node.getChildCount(); + if (NCHILDREN > 0) { + Log.i(TAG, prefix + " Children:"); + String cprefix = prefix + " "; + for (int i=0; i<NCHILDREN; i++) { + ViewNode cnode = node.getChildAt(i); + dump(cprefix, cnode); + } + } + } + + /** + * Return the activity this AssistStructure came from. + */ + public ComponentName getActivityComponent() { + ensureData(); + return mActivityComponent; + } + + /** + * Return the number of window contents that have been collected in this assist data. + */ + public int getWindowNodeCount() { + ensureData(); + return mWindowNodes.size(); + } + + /** + * Return one of the windows in the assist data. + * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1. + */ public WindowNode getWindowNodeAt(int index) { - return super.getWindowNodeAt(index); + ensureData(); + return mWindowNodes.get(index); + } + + /** @hide */ + public void ensureData() { + if (mHaveData) { + return; + } + mHaveData = true; + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(DESCRIPTOR); + try { + mReceiveChannel.transact(TRANSACTION_XFER, data, reply, 0); + } catch (RemoteException e) { + Log.w(TAG, "Failure reading AssistStructure data", e); + return; + } + readContentFromParcel(reply); + data.recycle(); + reply.recycle(); + } + + void writeContentToParcel(Parcel out, int flags) { + // First make sure all content has been created. + boolean skipStructure = false; + synchronized (this) { + long endTime = SystemClock.uptimeMillis() + 5000; + long now; + while (mPendingAsyncChildren.size() > 0 && (now=SystemClock.uptimeMillis()) < endTime) { + try { + wait(endTime-now); + } catch (InterruptedException e) { + } + } + if (mPendingAsyncChildren.size() > 0) { + // We waited too long, assume none of the assist structure is valid. + skipStructure = true; + } + } + int start = out.dataPosition(); + PooledStringWriter pwriter = new PooledStringWriter(out); + ComponentName.writeToParcel(mActivityComponent, out); + final int N = skipStructure ? 0 : mWindowNodes.size(); + out.writeInt(N); + for (int i=0; i<N; i++) { + mWindowNodes.get(i).writeToParcel(out, pwriter); + } + pwriter.finish(); + Log.i(TAG, "Flattened assist data: " + (out.dataPosition() - start) + " bytes"); + } + + void readContentFromParcel(Parcel in) { + PooledStringReader preader = new PooledStringReader(in); + mActivityComponent = ComponentName.readFromParcel(in); + final int N = in.readInt(); + for (int i=0; i<N; i++) { + mWindowNodes.add(new WindowNode(in, preader)); + } + //dump(); } public int describeContents() { diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java index 8a31390dbf26..9113426da129 100644 --- a/core/java/android/app/usage/UsageStatsManagerInternal.java +++ b/core/java/android/app/usage/UsageStatsManagerInternal.java @@ -77,6 +77,12 @@ public abstract class UsageStatsManagerInternal { public abstract boolean isAppIdle(String packageName, int userId); /** + * @return True if currently app idle parole mode is on. This means all idle apps are allow to + * run for a short period of time. + */ + public abstract boolean isAppIdleParoleOn(); + + /** * Sets up a listener for changes to packages being accessed. * @param listener A listener within the system process. */ @@ -90,8 +96,9 @@ public abstract class UsageStatsManagerInternal { public abstract void removeAppIdleStateChangeListener( AppIdleStateChangeListener listener); - public interface AppIdleStateChangeListener { - void onAppIdleStateChanged(String packageName, int userId, boolean idle); + public static abstract class AppIdleStateChangeListener { + public abstract void onAppIdleStateChanged(String packageName, int userId, boolean idle); + public abstract void onParoleStateChanged(boolean isParoleOn); } } diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java index 809f900222c5..58bd5cda825d 100644 --- a/core/java/android/content/AbstractThreadedSyncAdapter.java +++ b/core/java/android/content/AbstractThreadedSyncAdapter.java @@ -28,13 +28,26 @@ import java.util.concurrent.atomic.AtomicInteger; /** * An abstract implementation of a SyncAdapter that spawns a thread to invoke a sync operation. - * If a sync operation is already in progress when a startSync() request is received then an error - * will be returned to the new request and the existing request will be allowed to continue. - * When a startSync() is received and there is no sync operation in progress then a thread - * will be started to run the operation and {@link #onPerformSync} will be invoked on that thread. - * If a cancelSync() is received that matches an existing sync operation then the thread - * that is running that sync operation will be interrupted, which will indicate to the thread - * that the sync has been canceled. + * If a sync operation is already in progress when a sync request is received, an error will be + * returned to the new request and the existing request will be allowed to continue. + * However if there is no sync in progress then a thread will be spawned and {@link #onPerformSync} + * will be invoked on that thread. + * <p> + * Syncs can be cancelled at any time by the framework. For example a sync that was not + * user-initiated and lasts longer than 30 minutes will be considered timed-out and cancelled. + * Similarly the framework will attempt to determine whether or not an adapter is making progress + * by monitoring its network activity over the course of a minute. If the network traffic over this + * window is close enough to zero the sync will be cancelled. You can also request the sync be + * cancelled via {@link ContentResolver#cancelSync(Account, String)} or + * {@link ContentResolver#cancelSync(SyncRequest)}. + * <p> + * A sync is cancelled by issuing a {@link Thread#interrupt()} on the syncing thread. <strong>Either + * your code in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)} + * must check {@link Thread#interrupted()}, or you you must override one of + * {@link #onSyncCanceled(Thread)}/{@link #onSyncCanceled()}</strong> (depending on whether or not + * your adapter supports syncing of multiple accounts in parallel). If your adapter does not + * respect the cancel issued by the framework you run the risk of your app's entire process being + * killed. * <p> * In order to be a sync adapter one must extend this class, provide implementations for the * abstract methods and write a service that returns the result of {@link #getSyncAdapterBinder()} @@ -261,6 +274,10 @@ public abstract class AbstractThreadedSyncAdapter { } else { syncResult.databaseError = true; } + } catch (SecurityException e) { + AbstractThreadedSyncAdapter.this.onSecurityException(mAccount, mExtras, + mAuthority, syncResult); + syncResult.databaseError = true; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER); @@ -306,6 +323,20 @@ public abstract class AbstractThreadedSyncAdapter { String authority, ContentProviderClient provider, SyncResult syncResult); /** + * Report that there was a security exception when opening the content provider + * prior to calling {@link #onPerformSync}. This will be treated as a sync + * database failure. + * + * @param account the account that attempted to sync + * @param extras SyncAdapter-specific parameters + * @param authority the authority of the failed sync request + * @param syncResult SyncAdapter-specific parameters + */ + public void onSecurityException(Account account, Bundle extras, + String authority, SyncResult syncResult) { + } + + /** * Indicates that a sync operation has been canceled. This will be invoked on a separate * thread than the sync thread and so you must consider the multi-threaded implications * of the work that you do in this method. diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 0c07bc3ed105..cb68d74eff90 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -31,6 +31,7 @@ import android.content.pm.IPackageDeleteObserver2; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; +import android.content.pm.IPackagesProvider; import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.InstrumentationInfo; @@ -106,6 +107,8 @@ interface IPackageManager { void updatePermissionFlags(String permissionName, String packageName, int flagMask, int flagValues, int userId); + void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId); + boolean shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId); @@ -282,6 +285,10 @@ interface IPackageManager { */ byte[] getPreferredActivityBackup(int userId); void restorePreferredActivities(in byte[] backup, int userId); + byte[] getDefaultAppsBackup(int userId); + void restoreDefaultApps(in byte[] backup, int userId); + byte[] getIntentFilterVerificationBackup(int userId); + void restoreIntentFilterVerification(in byte[] backup, int userId); /** * Report the set of 'Home' activity candidates, plus (if any) which of them @@ -299,18 +306,18 @@ interface IPackageManager { * As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}. */ int getComponentEnabledSetting(in ComponentName componentName, int userId); - + /** * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}. */ void setApplicationEnabledSetting(in String packageName, in int newState, int flags, int userId, String callingPackage); - + /** * As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}. */ int getApplicationEnabledSetting(in String packageName, int userId); - + /** * Set whether the given package should be considered stopped, making * it not visible to implicit intents that filter out stopped packages. @@ -363,7 +370,7 @@ interface IPackageManager { */ void freeStorage(in String volumeUuid, in long freeStorageSize, in IntentSender pi); - + /** * Delete all the cache files in an applications cache directory * @param packageName The package name of the application whose cache @@ -371,7 +378,7 @@ interface IPackageManager { * @param observer a callback used to notify when the deletion is finished. */ void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer); - + /** * Clear the user data directory of an application. * @param packageName The package name of the application whose cache @@ -379,7 +386,7 @@ interface IPackageManager { * @param observer a callback used to notify when the operation is completed. */ void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId); - + /** * Get package statistics including the code, data and cache size for * an already installed package @@ -389,7 +396,7 @@ interface IPackageManager { * retrieval of information is complete. */ void getPackageSizeInfo(in String packageName, int userHandle, IPackageStatsObserver observer); - + /** * Get a list of shared libraries that are available on the * system. @@ -403,7 +410,7 @@ interface IPackageManager { FeatureInfo[] getSystemAvailableFeatures(); boolean hasSystemFeature(String name); - + void enterSafeMode(); boolean isSafeMode(); void systemReady(); @@ -494,4 +501,7 @@ interface IPackageManager { void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); + + void grantDefaultPermissions(int userId); + void setCarrierAppPackagesProvider(in IPackagesProvider provider); } diff --git a/core/java/android/view/ViewAssistStructure.java b/core/java/android/content/pm/IPackagesProvider.aidl index a66d93c8cc05..7d76c88d0027 100644 --- a/core/java/android/view/ViewAssistStructure.java +++ b/core/java/android/content/pm/IPackagesProvider.aidl @@ -14,11 +14,9 @@ * limitations under the License. */ -package android.view; +package android.content.pm; -/** - * @deprecated Temporary until old apps can move off this. - */ -@Deprecated -public abstract class ViewAssistStructure extends ViewStructure { +/** {@hide} */ +interface IPackagesProvider { + String[] getPackages(int userId); } diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java index 4e7da48b4c9a..04dbff24b143 100644 --- a/core/java/android/content/pm/PermissionInfo.java +++ b/core/java/android/content/pm/PermissionInfo.java @@ -109,6 +109,14 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_COSTS_MONEY = 1<<0; /** + * Flag for {@link #protectionLevel}, corresponding + * to the <code>hide</code> value of + * {@link android.R.attr#permissionFlags}. + * @hide + */ + public static final int PROTECTION_FLAG_HIDE = 1<<1; + + /** * Additional flags about this permission as given by * {@link android.R.attr#permissionFlags}. */ diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 27d14b3bbae5..a88b71c07a9d 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -628,7 +628,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri /** * <p>List of available high speed video size, fps range and max batch size configurations * supported by the camera device, in the format of (width, height, fps_min, fps_max, batch_size_max).</p> - * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in android.control.availableCapabilities, + * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}, * this metadata will list the supported high speed video size, fps range and max batch size * configurations. All the sizes listed in this configuration will be a subset of the sizes * reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } @@ -675,6 +675,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> * * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES * @hide */ public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS = @@ -2679,9 +2680,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <p>Camera devices will come in three flavors: LEGACY, LIMITED and FULL.</p> * <p>A FULL device will support below capabilities:</p> * <ul> - * <li>30fps operation at maximum resolution (== sensor resolution) is preferred, more than - * 20fps is required, for at least uncompressed YUV - * output. ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li> + * <li>BURST_CAPTURE capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains BURST_CAPTURE)</li> * <li>Per frame control ({@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} <code>==</code> PER_FRAME_CONTROL)</li> * <li>Manual sensor control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR)</li> * <li>Manual post-processing control ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains @@ -2689,7 +2688,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>Arbitrary cropping region ({@link CameraCharacteristics#SCALER_CROPPING_TYPE android.scaler.croppingType} <code>==</code> FREEFORM)</li> * <li>At least 3 processed (but not stalling) format output streams * ({@link CameraCharacteristics#REQUEST_MAX_NUM_OUTPUT_PROC android.request.maxNumOutputProc} <code>>=</code> 3)</li> - * <li>The required stream configuration defined in android.scaler.availableStreamConfigurations</li> + * <li>The required stream configurations defined in android.scaler.availableStreamConfigurations</li> * <li>The required exposure time range defined in {@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li> * <li>The required maxFrameDuration defined in {@link CameraCharacteristics#SENSOR_INFO_MAX_FRAME_DURATION android.sensor.info.maxFrameDuration}</li> * </ul> @@ -2709,23 +2708,11 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * post-processing, arbitrary cropping regions, and has relaxed performance constraints.</p> * <p>Each higher level supports everything the lower level supports * in this order: FULL <code>></code> LIMITED <code>></code> LEGACY.</p> - * <p>A HIGH_RESOLUTION device is equivalent to a FULL device, except that:</p> - * <ul> - * <li>At least one output resolution of 8 megapixels or higher in uncompressed YUV is - * supported at <code>>=</code> 20 fps.</li> - * <li>Maximum-size (sensor resolution) uncompressed YUV is supported at <code>>=</code> 10 - * fps.</li> - * <li>For devices that list the RAW capability and support either RAW10 or RAW12 output, - * maximum-resolution RAW10 or RAW12 capture will operate at least at the rate of - * maximum-resolution YUV capture, and at least one supported output resolution of - * 8 megapixels or higher in RAW10 or RAW12 is supported <code>>=</code> 20 fps.</li> - * </ul> * <p><b>Possible values:</b> * <ul> * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}</li> * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}</li> * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY LEGACY}</li> - * <li>{@link #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION HIGH_RESOLUTION}</li> * </ul></p> * <p>This key is available on all devices.</p> * @@ -2743,7 +2730,6 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED * @see #INFO_SUPPORTED_HARDWARE_LEVEL_FULL * @see #INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY - * @see #INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION */ @PublicKey public static final Key<Integer> INFO_SUPPORTED_HARDWARE_LEVEL = diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index c656fb8b8352..5a80585cf55e 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -531,37 +531,32 @@ public abstract class CameraMetadata<TKey> { public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; /** - * <p>The camera device supports capturing maximum-resolution - * images at >= 20 frames per second, in at least the - * uncompressed YUV format, when post-processing settings - * are set to FAST.</p> - * <p>More specifically, this means that a size matching the - * camera device's active array size is listed as a - * supported size for the YUV_420_888 format in - * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap}, the minimum frame - * duration for that format and size is <= 1/20 s, and - * the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry - * lists at least one FPS range where the minimum FPS is</p> - * <blockquote> - * <p>= 1 / minimumFrameDuration for the maximum-size - * YUV_420_888 format.</p> - * </blockquote> - * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is - * guaranted to have a value between 0 and 4, inclusive. - * {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and - * {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable} are also guaranteed - * to be <code>true</code> so burst capture with these two locks ON - * yields consistent image output.</p> - * <p>On a camera device that reports the HIGH_RESOLUTION hardware - * level, meaning the device supports very large capture sizes, - * BURST_CAPTURE means that at least 8-megapixel images can be - * captured at <code>>=</code> 20 fps, and maximum-resolution images can be - * captured at <code>>=</code> 10 fps.</p> + * <p>The camera device supports capturing high-resolution images at >= 20 frames per + * second, in at least the uncompressed YUV format, when post-processing settings are set + * to FAST. Additionally, maximum-resolution images can be captured at >= 10 frames + * per second. Here, 'high resolution' means at least 8 megapixels, or the maximum + * resolution of the device, whichever is smaller.</p> + * <p>More specifically, this means that a size matching the camera device's active array + * size is listed as a supported size for the {@link android.graphics.ImageFormat#YUV_420_888 } format in either {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } or {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes }, + * with a minimum frame duration for that format and size of either <= 1/20 s, or + * <= 1/10 s, respectively; and the {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges} entry + * lists at least one FPS range where the minimum FPS is >= 1 / minimumFrameDuration + * for the maximum-size YUV_420_888 format. If that maximum size is listed in {@link android.hardware.camera2.params.StreamConfigurationMap#getHighResolutionOutputSizes }, + * then the list of resolutions for YUV_420_888 from {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } contains at + * least one resolution >= 8 megapixels, with a minimum frame duration of <= 1/20 + * s.</p> + * <p>If the device supports the {@link android.graphics.ImageFormat#RAW10 }, {@link android.graphics.ImageFormat#RAW12 }, then those can also be captured at the same rate + * as the maximum-size YUV_420_888 resolution is.</p> + * <p>If the device supports the PRIVATE_REPROCESSING capability, then the same guarantees + * as for the YUV_420_888 format also apply to the {@link android.graphics.ImageFormat#PRIVATE } format.</p> + * <p>In addition, the {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} field is guaranted to have a value between 0 + * and 4, inclusive. {@link CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE android.control.aeLockAvailable} and {@link CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE android.control.awbLockAvailable} + * are also guaranteed to be <code>true</code> so burst capture with these two locks ON yields + * consistent image output.</p> * * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES * @see CameraCharacteristics#CONTROL_AE_LOCK_AVAILABLE * @see CameraCharacteristics#CONTROL_AWB_LOCK_AVAILABLE - * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP * @see CameraCharacteristics#SYNC_MAX_LATENCY * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES */ @@ -954,13 +949,6 @@ public abstract class CameraMetadata<TKey> { */ public static final int INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY = 2; - /** - * <p>This camera device is capable of supporting advanced imaging applications at full rate, - * and additional high-resolution outputs at lower rates.</p> - * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL - */ - public static final int INFO_SUPPORTED_HARDWARE_LEVEL_HIGH_RESOLUTION = 3; - // // Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY // diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 9fa66879629d..75289f762162 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -398,7 +398,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> @Override public int hashCode() { - return HashCodeHelpers.hashCode(mSettings, mSurfaceSet, mUserTag); + return HashCodeHelpers.hashCodeGeneric(mSettings, mSurfaceSet, mUserTag); } public static final Parcelable.Creator<CaptureRequest> CREATOR = @@ -1759,11 +1759,24 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to * generate the thumbnail image. The thumbnail image will always have a smaller Field * Of View (FOV) than the primary image when aspect ratios differ.</p> + * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested, + * the camera device will handle thumbnail rotation in one of the following ways:</p> + * <ul> + * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag} + * and keep jpeg and thumbnail image data unrotated.</li> + * <li>Rotate the jpeg and thumbnail image data and not set + * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this + * case, LIMITED or FULL hardware level devices will report rotated thumnail size in + * capture result, so the width and height will be interchanged if 90 or 270 degree + * orientation is requested. LEGACY device will always report unrotated thumbnail + * size.</li> + * </ul> * <p><b>Range of valid values:</b><br> * {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p> * <p>This key is available on all devices.</p> * * @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES + * @see CaptureRequest#JPEG_ORIENTATION */ @PublicKey public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE = diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index b1fb615821c7..1d31109a1e87 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -2314,11 +2314,24 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * 16:9 aspect ratio, the primary image will be cropped vertically (letterbox) to * generate the thumbnail image. The thumbnail image will always have a smaller Field * Of View (FOV) than the primary image when aspect ratios differ.</p> + * <p>When an {@link CaptureRequest#JPEG_ORIENTATION android.jpeg.orientation} of non-zero degree is requested, + * the camera device will handle thumbnail rotation in one of the following ways:</p> + * <ul> + * <li>Set the {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag} + * and keep jpeg and thumbnail image data unrotated.</li> + * <li>Rotate the jpeg and thumbnail image data and not set + * {@link android.media.ExifInterface#TAG_ORIENTATION EXIF orientation flag}. In this + * case, LIMITED or FULL hardware level devices will report rotated thumnail size in + * capture result, so the width and height will be interchanged if 90 or 270 degree + * orientation is requested. LEGACY device will always report unrotated thumbnail + * size.</li> + * </ul> * <p><b>Range of valid values:</b><br> * {@link CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES android.jpeg.availableThumbnailSizes}</p> * <p>This key is available on all devices.</p> * * @see CameraCharacteristics#JPEG_AVAILABLE_THUMBNAIL_SIZES + * @see CaptureRequest#JPEG_ORIENTATION */ @PublicKey public static final Key<android.util.Size> JPEG_THUMBNAIL_SIZE = diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java index 70afe5bb0222..57a080b9346b 100644 --- a/core/java/android/hardware/camera2/DngCreator.java +++ b/core/java/android/hardware/camera2/DngCreator.java @@ -284,6 +284,8 @@ public final class DngCreator implements AutoCloseable { * {@code offset + 2 * width * height)} bytes. The width and height of * the input are taken from the width and height set in the {@link DngCreator} metadata tags, * and will typically be equal to the width and height of + * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}. Prior to + * API level 23, this was always the same as * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}. * The pixel layout in the input is determined from the reported color filter arrangement (CFA) * set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}. If insufficient @@ -332,6 +334,8 @@ public final class DngCreator implements AutoCloseable { * {@code offset + 2 * width * height)} bytes. The width and height of * the input are taken from the width and height set in the {@link DngCreator} metadata tags, * and will typically be equal to the width and height of + * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE}. Prior to + * API level 23, this was always the same as * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE}. * The pixel layout in the input is determined from the reported color filter arrangement (CFA) * set in {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}. If insufficient diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java index 10dd8aed631e..7e50fd9f623a 100644 --- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java +++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java @@ -842,11 +842,19 @@ public class CameraMetadataNative implements Parcelable { CameraCharacteristics.CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS); ReprocessFormatsMap inputOutputFormatsMap = getBase( CameraCharacteristics.SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP); - + int[] capabilities = getBase(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES); + boolean listHighResolution = false; + for (int capability : capabilities) { + if (capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE) { + listHighResolution = true; + break; + } + } return new StreamConfigurationMap( configurations, minFrameDurations, stallDurations, depthConfigurations, depthMinFrameDurations, depthStallDurations, - highSpeedVideoConfigurations, inputOutputFormatsMap); + highSpeedVideoConfigurations, inputOutputFormatsMap, + listHighResolution); } private <T> Integer getMaxRegions(Key<T> key) { diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index 2fb3203973bc..e786707c383d 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -605,6 +605,14 @@ public class LegacyCameraDevice implements AutoCloseable { return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceType(surface)); } + /** + * Query the surface for its currently configured dataspace + */ + public static int detectSurfaceDataspace(Surface surface) throws BufferQueueAbandonedException { + checkNotNull(surface); + return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface)); + } + static void configureSurface(Surface surface, int width, int height, int pixelFormat) throws BufferQueueAbandonedException { checkNotNull(surface); @@ -702,6 +710,8 @@ public class LegacyCameraDevice implements AutoCloseable { private static native int nativeDetectSurfaceType(Surface surface); + private static native int nativeDetectSurfaceDataspace(Surface surface); + private static native int nativeDetectSurfaceDimens(Surface surface, /*out*/int[/*2*/] dimens); diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java index c6ea4883f188..639ad6054a32 100644 --- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java +++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java @@ -20,14 +20,16 @@ import android.graphics.ImageFormat; import android.graphics.PixelFormat; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.utils.HashCodeHelpers; +import android.hardware.camera2.utils.SurfaceUtils; import android.hardware.camera2.legacy.LegacyCameraDevice; import android.hardware.camera2.legacy.LegacyMetadataMapper; -import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException; import android.view.Surface; import android.util.Range; import android.util.Size; +import android.util.SparseIntArray; import java.util.Arrays; import java.util.HashMap; @@ -79,7 +81,8 @@ public final class StreamConfigurationMap { * @param stallDurations a non-{@code null} array of {@link StreamConfigurationDuration} * @param highSpeedVideoConfigurations an array of {@link HighSpeedVideoConfiguration}, null if * camera device does not support high speed video recording - * + * @param listHighResolution a flag indicating whether the device supports BURST_CAPTURE + * and thus needs a separate list of slow high-resolution output sizes * @throws NullPointerException if any of the arguments except highSpeedVideoConfigurations * were {@code null} or any subelements were {@code null} * @@ -93,10 +96,12 @@ public final class StreamConfigurationMap { StreamConfigurationDuration[] depthMinFrameDurations, StreamConfigurationDuration[] depthStallDurations, HighSpeedVideoConfiguration[] highSpeedVideoConfigurations, - ReprocessFormatsMap inputOutputFormatsMap) { + ReprocessFormatsMap inputOutputFormatsMap, + boolean listHighResolution) { mConfigurations = checkArrayElementsNotNull(configurations, "configurations"); mMinFrameDurations = checkArrayElementsNotNull(minFrameDurations, "minFrameDurations"); mStallDurations = checkArrayElementsNotNull(stallDurations, "stallDurations"); + mListHighResolution = listHighResolution; if (depthConfigurations == null) { mDepthConfigurations = new StreamConfiguration[0]; @@ -120,15 +125,27 @@ public final class StreamConfigurationMap { // For each format, track how many sizes there are available to configure for (StreamConfiguration config : configurations) { - HashMap<Integer, Integer> map = config.isOutput() ? mOutputFormats : mInputFormats; - - Integer count = map.get(config.getFormat()); - - if (count == null) { - count = 0; + int fmt = config.getFormat(); + SparseIntArray map = null; + if (config.isOutput()) { + mAllOutputFormats.put(fmt, mAllOutputFormats.get(fmt) + 1); + long duration = 0; + if (mListHighResolution) { + for (StreamConfigurationDuration configurationDuration : mMinFrameDurations) { + if (configurationDuration.getFormat() == fmt && + configurationDuration.getWidth() == config.getSize().getWidth() && + configurationDuration.getHeight() == config.getSize().getHeight()) { + duration = configurationDuration.getDuration(); + break; + } + } + } + map = duration <= DURATION_20FPS_NS ? + mOutputFormats : mHighResOutputFormats; + } else { + map = mInputFormats; } - - map.put(config.getFormat(), count + 1); + map.put(fmt, map.get(fmt) + 1); } // For each depth format, track how many sizes there are available to configure @@ -138,16 +155,11 @@ public final class StreamConfigurationMap { continue; } - Integer count = mDepthOutputFormats.get(config.getFormat()); - - if (count == null) { - count = 0; - } - - mDepthOutputFormats.put(config.getFormat(), count + 1); + mDepthOutputFormats.put(config.getFormat(), + mDepthOutputFormats.get(config.getFormat()) + 1); } - if (!mOutputFormats.containsKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)) { + if (mOutputFormats.indexOfKey(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) < 0) { throw new AssertionError( "At least one stream configuration for IMPLEMENTATION_DEFINED must exist"); } @@ -241,7 +253,7 @@ public final class StreamConfigurationMap { * @return a non-empty array of sizes, or {@code null} if the format was not available. */ public Size[] getInputSizes(final int format) { - return getPublicFormatSizes(format, /*output*/false); + return getPublicFormatSizes(format, /*output*/false, /*highRes*/false); } /** @@ -274,9 +286,9 @@ public final class StreamConfigurationMap { int internalFormat = imageFormatToInternal(format); int dataspace = imageFormatToDataspace(format); if (dataspace == HAL_DATASPACE_DEPTH) { - return mDepthOutputFormats.containsKey(internalFormat); + return mDepthOutputFormats.indexOfKey(internalFormat) >= 0; } else { - return getFormatsMap(/*output*/true).containsKey(internalFormat); + return getFormatsMap(/*output*/true).indexOfKey(internalFormat) >= 0; } } @@ -378,27 +390,24 @@ public final class StreamConfigurationMap { public boolean isOutputSupportedFor(Surface surface) { checkNotNull(surface, "surface must not be null"); - Size surfaceSize; - int surfaceFormat = -1; - try { - surfaceSize = LegacyCameraDevice.getSurfaceSize(surface); - surfaceFormat = LegacyCameraDevice.detectSurfaceType(surface); - } catch(BufferQueueAbandonedException e) { - throw new IllegalArgumentException("Abandoned surface", e); - } + Size surfaceSize = SurfaceUtils.getSurfaceSize(surface); + int surfaceFormat = SurfaceUtils.getSurfaceFormat(surface); + int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface); // See if consumer is flexible. - boolean isFlexible = LegacyCameraDevice.isFlexibleConsumer(surface); + boolean isFlexible = SurfaceUtils.isFlexibleConsumer(surface); // Override RGB formats to IMPLEMENTATION_DEFINED, b/9487482 if ((surfaceFormat >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 && surfaceFormat <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) { - surfaceFormat = LegacyMetadataMapper.HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; + surfaceFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; } - for (StreamConfiguration config : mConfigurations) { + StreamConfiguration[] configs = + surfaceDataspace != HAL_DATASPACE_DEPTH ? mConfigurations : mDepthConfigurations; + for (StreamConfiguration config : configs) { if (config.getFormat() == surfaceFormat && config.isOutput()) { - // Mathing format, either need exact size match, or a flexible consumer + // Matching format, either need exact size match, or a flexible consumer // and a size no bigger than MAX_DIMEN_FOR_ROUNDING if (config.getSize().equals(surfaceSize)) { return true; @@ -414,12 +423,12 @@ public final class StreamConfigurationMap { /** * Get a list of sizes compatible with {@code klass} to use as an output. * - * <p>Since some of the supported classes may support additional formats beyond + * <p>Some of the supported classes may support additional formats beyond * {@link ImageFormat#PRIVATE}; this function only returns * sizes for {@link ImageFormat#PRIVATE}. For example, {@link android.media.ImageReader} * supports {@link ImageFormat#YUV_420_888} and {@link ImageFormat#PRIVATE}, this method will * only return the sizes for {@link ImageFormat#PRIVATE} for {@link android.media.ImageReader} - * class .</p> + * class.</p> * * <p>If a well-defined format such as {@code NV21} is required, use * {@link #getOutputSizes(int)} instead.</p> @@ -444,7 +453,7 @@ public final class StreamConfigurationMap { } return getInternalFormatSizes(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, - HAL_DATASPACE_UNKNOWN,/*output*/true); + HAL_DATASPACE_UNKNOWN,/*output*/true, /*highRes*/false); } /** @@ -453,6 +462,14 @@ public final class StreamConfigurationMap { * <p>The {@code format} should be a supported format (one of the formats returned by * {@link #getOutputFormats}).</p> * + * As of API level 23, the {@link #getHighResolutionOutputSizes} method can be used on devices + * that support the + * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE} + * capability to get a list of high-resolution output sizes that cannot operate at the preferred + * 20fps rate. This means that for some supported formats, this method will return an empty + * list, if all the supported resolutions operate at below 20fps. For devices that do not + * support the BURST_CAPTURE capability, all output resolutions are listed through this method. + * * @param format an image format from {@link ImageFormat} or {@link PixelFormat} * @return * an array of supported sizes, @@ -463,36 +480,40 @@ public final class StreamConfigurationMap { * @see #getOutputFormats */ public Size[] getOutputSizes(int format) { - return getPublicFormatSizes(format, /*output*/true); + return getPublicFormatSizes(format, /*output*/true, /*highRes*/ false); } /** * Get a list of supported high speed video recording sizes. - * - * <p> When HIGH_SPEED_VIDEO is supported in - * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this - * method will list the supported high speed video size configurations. All the sizes listed - * will be a subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling - * formats (typically ImageFormat#YUV_420_888, ImageFormat#NV21, ImageFormat#YV12)</p> - * - * <p> To enable high speed video recording, application must set - * {@link CaptureRequest#CONTROL_SCENE_MODE} to - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture - * requests and select the video size from this method and + * <p> + * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is + * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will + * list the supported high speed video size configurations. All the sizes listed will be a + * subset of the sizes reported by {@link #getOutputSizes} for processed non-stalling formats + * (typically {@link ImageFormat#PRIVATE} {@link ImageFormat#YUV_420_888}, etc.) + * </p> + * <p> + * To enable high speed video recording, application must create a constrained create high speed + * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit + * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList} + * to this session. The application must select the video size from this method and * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from - * {@link #getHighSpeedVideoFpsRangesFor} to configure the recording and preview streams and - * setup the recording requests. For example, if the application intends to do high speed - * recording, it can select the maximum size reported by this method to configure output - * streams. Note that for the use case of multiple output streams, application must select one - * unique size from this method to use. Otherwise a request error might occur. Once the size is + * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and + * generate the high speed request list. For example, if the application intends to do high + * speed recording, it can select the maximum size reported by this method to create high speed + * capture session. Note that for the use case of multiple output streams, application must + * select one unique size from this method to use (e.g., preview and recording streams must have + * the same size). Otherwise, the high speed session creation will fail. Once the size is * selected, application can get the supported FPS ranges by * {@link #getHighSpeedVideoFpsRangesFor}, and use these FPS ranges to setup the recording - * requests.</p> - * - * @return - * an array of supported high speed video recording sizes + * request lists via {@link CameraDevice#createConstrainedHighSpeedRequestList}. + * </p> * + * @return an array of supported high speed video recording sizes * @see #getHighSpeedVideoFpsRangesFor(Size) + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + * @see CameraDevice#createConstrainedHighSpeedCaptureSession + * @see CameraDevice#createConstrainedHighSpeedRequestList */ public Size[] getHighSpeedVideoSizes() { Set<Size> keySet = mHighSpeedVideoSizeMap.keySet(); @@ -501,26 +522,25 @@ public final class StreamConfigurationMap { /** * Get the frame per second ranges (fpsMin, fpsMax) for input high speed video size. - * - * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p> - * - * <p> For normal video recording use case, where some application will NOT set - * {@link CaptureRequest#CONTROL_SCENE_MODE} to - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture - * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in - * this method must not be used to setup capture requests, or it will cause request error.</p> + * <p> + * See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording. + * </p> + * <p> + * The {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in this method + * must not be used to setup capture requests that are submitted to unconstrained capture + * sessions, or it will result in {@link IllegalArgumentException IllegalArgumentExceptions}. + * </p> + * <p> + * See {@link #getHighSpeedVideoFpsRanges} for the characteristics of the returned FPS ranges. + * </p> * * @param size one of the sizes returned by {@link #getHighSpeedVideoSizes()} - * @return - * An array of FPS range to use with - * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE TARGET_FPS_RANGE} when using - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene - * mode. - * The upper bound of returned ranges is guaranteed to be larger or equal to 60. - * + * @return an array of supported high speed video recording FPS ranges The upper bound of + * returned ranges is guaranteed to be greater than or equal to 120. * @throws IllegalArgumentException if input size does not exist in the return value of - * getHighSpeedVideoSizes + * getHighSpeedVideoSizes * @see #getHighSpeedVideoSizes() + * @see #getHighSpeedVideoFpsRanges() */ public Range<Integer>[] getHighSpeedVideoFpsRangesFor(Size size) { Integer fpsRangeCount = mHighSpeedVideoSizeMap.get(size); @@ -542,34 +562,46 @@ public final class StreamConfigurationMap { /** * Get a list of supported high speed video recording FPS ranges. - * - * <p> When HIGH_SPEED_VIDEO is supported in - * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES available scene modes}, this - * method will list the supported high speed video FPS range configurations. Application can - * then use {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned - * FPS range.</p> - * - * <p> To enable high speed video recording, application must set - * {@link CaptureRequest#CONTROL_SCENE_MODE} to - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture - * requests and select the video size from {@link #getHighSpeedVideoSizesFor} and + * <p> + * When {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} is + * supported in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}, this method will + * list the supported high speed video FPS range configurations. Application can then use + * {@link #getHighSpeedVideoSizesFor} to query available sizes for one of returned FPS range. + * </p> + * <p> + * To enable high speed video recording, application must create a constrained create high speed + * capture session via {@link CameraDevice#createConstrainedHighSpeedCaptureSession}, and submit + * a CaptureRequest list created by {@link CameraDevice#createConstrainedHighSpeedRequestList} + * to this session. The application must select the video size from this method and * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} from - * this method to configure the recording and preview streams and setup the recording requests. - * For example, if the application intends to do high speed recording, it can select one FPS - * range reported by this method, query the video sizes corresponding to this FPS range by - * {@link #getHighSpeedVideoSizesFor} and select one of reported sizes to configure output - * streams. Note that for the use case of multiple output streams, application must select one - * unique size from {@link #getHighSpeedVideoSizesFor}, and use it for all output streams. - * Otherwise a request error might occur when attempting to enable - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO}. - * Once the stream is configured, application can set the FPS range in the recording requests. + * {@link #getHighSpeedVideoFpsRangesFor} to configure the constrained high speed session and + * generate the high speed request list. For example, if the application intends to do high + * speed recording, it can select one FPS range reported by this method, query the video sizes + * corresponding to this FPS range by {@link #getHighSpeedVideoSizesFor} and use one of reported + * sizes to create a high speed capture session. Note that for the use case of multiple output + * streams, application must select one unique size from this method to use (e.g., preview and + * recording streams must have the same size). Otherwise, the high speed session creation will + * fail. Once the high speed capture session is created, the application can set the FPS range + * in the recording request lists via + * {@link CameraDevice#createConstrainedHighSpeedRequestList}. + * </p> + * <p> + * The FPS ranges reported by this method will have below characteristics: + * <li>The fpsMin and fpsMax will be a multiple 30fps.</li> + * <li>The fpsMin will be no less than 30fps, the fpsMax will be no less than 120fps.</li> + * <li>At least one range will be a fixed FPS range where fpsMin == fpsMax.</li> + * <li>For each fixed FPS range, there will be one corresponding variable FPS range [30, + * fps_max]. These kinds of FPS ranges are suitable for preview-only use cases where the + * application doesn't want the camera device always produce higher frame rate than the display + * refresh rate.</li> * </p> * - * @return - * an array of supported high speed video recording FPS ranges - * The upper bound of returned ranges is guaranteed to be larger or equal to 60. - * + * @return an array of supported high speed video recording FPS ranges The upper bound of + * returned ranges is guaranteed to be larger or equal to 120. * @see #getHighSpeedVideoSizesFor + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + * @see CameraDevice#createConstrainedHighSpeedCaptureSession + * @see CameraDevice#createConstrainedHighSpeedRequestList */ @SuppressWarnings("unchecked") public Range<Integer>[] getHighSpeedVideoFpsRanges() { @@ -578,21 +610,13 @@ public final class StreamConfigurationMap { } /** - * Get the supported video sizes for input FPS range. + * Get the supported video sizes for an input high speed FPS range. * - * <p> See {@link #getHighSpeedVideoFpsRanges} for how to enable high speed recording.</p> - * - * <p> For normal video recording use case, where the application will NOT set - * {@link CaptureRequest#CONTROL_SCENE_MODE} to - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} in capture - * requests, the {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS ranges} reported in - * this method must not be used to setup capture requests, or it will cause request error.</p> + * <p> See {@link #getHighSpeedVideoSizes} for how to enable high speed recording.</p> * * @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()} - * @return - * An array of video sizes to configure output stream when using - * {@link CaptureRequest#CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO HIGH_SPEED_VIDEO} scene - * mode. + * @return An array of video sizes to create high speed capture sessions for high speed streaming + * use cases. * * @throws IllegalArgumentException if input FPS range does not exist in the return value of * getHighSpeedVideoFpsRanges @@ -616,6 +640,32 @@ public final class StreamConfigurationMap { } /** + * Get a list of supported high resolution sizes, which cannot operate at full BURST_CAPTURE + * rate. + * + * <p>This includes all output sizes that cannot meet the 20 fps frame rate requirements for the + * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE} + * capability. This does not include the stall duration, so for example, a JPEG or RAW16 output + * resolution with a large stall duration but a minimum frame duration that's above 20 fps will + * still be listed in the regular {@link #getOutputSizes} list. All the sizes on this list are + * still guaranteed to operate at a rate of at least 10 fps, not including stall duration.</p> + * + * <p>For a device that does not support the BURST_CAPTURE capability, this list will be + * {@code null}, since resolutions in the {@link #getOutputSizes} list are already not + * guaranteed to meet >= 20 fps rate requirements. For a device that does support the + * BURST_CAPTURE capability, this list may be empty, if all supported resolutions meet the 20 + * fps requirement.</p> + * + * @return an array of supported slower high-resolution sizes, or {@code null} if the + * BURST_CAPTURE capability is not supported + */ + public Size[] getHighResolutionOutputSizes(int format) { + if (!mListHighResolution) return null; + + return getPublicFormatSizes(format, /*output*/true, /*highRes*/ true); + } + + /** * Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration} * for the format/size combination (in nanoseconds). * @@ -867,6 +917,7 @@ public final class StreamConfigurationMap { return Arrays.equals(mConfigurations, other.mConfigurations) && Arrays.equals(mMinFrameDurations, other.mMinFrameDurations) && Arrays.equals(mStallDurations, other.mStallDurations) && + Arrays.equals(mDepthConfigurations, other.mDepthConfigurations) && Arrays.equals(mHighSpeedVideoConfigurations, other.mHighSpeedVideoConfigurations); } @@ -879,18 +930,31 @@ public final class StreamConfigurationMap { @Override public int hashCode() { // XX: do we care about order? - return HashCodeHelpers.hashCode( + return HashCodeHelpers.hashCodeGeneric( mConfigurations, mMinFrameDurations, - mStallDurations, mHighSpeedVideoConfigurations); + mStallDurations, + mDepthConfigurations, mHighSpeedVideoConfigurations); } // Check that the argument is supported by #getOutputFormats or #getInputFormats private int checkArgumentFormatSupported(int format, boolean output) { checkArgumentFormat(format); - int[] formats = output ? getOutputFormats() : getInputFormats(); - for (int i = 0; i < formats.length; ++i) { - if (format == formats[i]) { + int internalFormat = imageFormatToInternal(format); + int internalDataspace = imageFormatToDataspace(format); + + if (output) { + if (internalDataspace == HAL_DATASPACE_DEPTH) { + if (mDepthOutputFormats.indexOfKey(internalFormat) >= 0) { + return format; + } + } else { + if (mAllOutputFormats.indexOfKey(internalFormat) >= 0) { + return format; + } + } + } else { + if (mInputFormats.indexOfKey(internalFormat) >= 0) { return format; } } @@ -1175,7 +1239,7 @@ public final class StreamConfigurationMap { return formats; } - private Size[] getPublicFormatSizes(int format, boolean output) { + private Size[] getPublicFormatSizes(int format, boolean output, boolean highRes) { try { checkArgumentFormatSupported(format, output); } catch (IllegalArgumentException e) { @@ -1185,36 +1249,57 @@ public final class StreamConfigurationMap { int internalFormat = imageFormatToInternal(format); int dataspace = imageFormatToDataspace(format); - return getInternalFormatSizes(internalFormat, dataspace, output); + return getInternalFormatSizes(internalFormat, dataspace, output, highRes); } - private Size[] getInternalFormatSizes(int format, int dataspace, boolean output) { - - HashMap<Integer, Integer> formatsMap = - (dataspace == HAL_DATASPACE_DEPTH) ? mDepthOutputFormats : getFormatsMap(output); - - Integer sizesCount = formatsMap.get(format); - if (sizesCount == null) { + private Size[] getInternalFormatSizes(int format, int dataspace, + boolean output, boolean highRes) { + SparseIntArray formatsMap = + !output ? mInputFormats : + dataspace == HAL_DATASPACE_DEPTH ? mDepthOutputFormats : + highRes ? mHighResOutputFormats : + mOutputFormats; + + int sizesCount = formatsMap.get(format); + if ( ((!output || dataspace == HAL_DATASPACE_DEPTH) && sizesCount == 0) || + (output && dataspace != HAL_DATASPACE_DEPTH && mAllOutputFormats.get(format) == 0)) { + // Only throw if this is really not supported at all throw new IllegalArgumentException("format not available"); } - int len = sizesCount; - Size[] sizes = new Size[len]; + Size[] sizes = new Size[sizesCount]; int sizeIndex = 0; StreamConfiguration[] configurations = (dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations; - for (StreamConfiguration config : configurations) { - if (config.getFormat() == format && config.isOutput() == output) { + int fmt = config.getFormat(); + if (fmt == format && config.isOutput() == output) { + if (output) { + // Filter slow high-res output formats; include for + // highRes, remove for !highRes + long duration = 0; + for (int i = 0; i < mMinFrameDurations.length; i++) { + StreamConfigurationDuration d = mMinFrameDurations[i]; + if (d.getFormat() == fmt && + d.getWidth() == config.getSize().getWidth() && + d.getHeight() == config.getSize().getHeight()) { + duration = d.getDuration(); + break; + } + } + if (highRes != (duration > DURATION_20FPS_NS)) { + continue; + } + } sizes[sizeIndex++] = config.getSize(); } } - if (sizeIndex != len) { + if (sizeIndex != sizesCount) { throw new AssertionError( - "Too few sizes (expected " + len + ", actual " + sizeIndex + ")"); + "Too few sizes (expected " + sizesCount + ", actual " + sizeIndex + ")"); } return sizes; @@ -1226,14 +1311,16 @@ public final class StreamConfigurationMap { int i = 0; - for (int format : getFormatsMap(output).keySet()) { + SparseIntArray map = getFormatsMap(output); + for (int j = 0; j < map.size(); j++) { + int format = map.keyAt(j); if (format != HAL_PIXEL_FORMAT_RAW_OPAQUE) { formats[i++] = imageFormatToPublic(format); } } if (output) { - for (int format : mDepthOutputFormats.keySet()) { - formats[i++] = depthFormatToPublic(format); + for (int j = 0; j < mDepthOutputFormats.size(); j++) { + formats[i++] = depthFormatToPublic(mDepthOutputFormats.keyAt(j)); } } if (formats.length != i) { @@ -1244,14 +1331,14 @@ public final class StreamConfigurationMap { } /** Get the format -> size count map for either output or input formats */ - private HashMap<Integer, Integer> getFormatsMap(boolean output) { - return output ? mOutputFormats : mInputFormats; + private SparseIntArray getFormatsMap(boolean output) { + return output ? mAllOutputFormats : mInputFormats; } private long getInternalFormatDuration(int format, int dataspace, Size size, int duration) { // assume format is already checked, since its internal - if (!arrayContains(getInternalFormatSizes(format, dataspace, /*output*/true), size)) { + if (!isSupportedInternalConfiguration(format, dataspace, size)) { throw new IllegalArgumentException("size was not supported"); } @@ -1289,10 +1376,9 @@ public final class StreamConfigurationMap { /** Count the number of publicly-visible output formats */ private int getPublicFormatCount(boolean output) { - HashMap<Integer, Integer> formatsMap = getFormatsMap(output); - + SparseIntArray formatsMap = getFormatsMap(output); int size = formatsMap.size(); - if (formatsMap.containsKey(HAL_PIXEL_FORMAT_RAW_OPAQUE)) { + if (formatsMap.indexOfKey(HAL_PIXEL_FORMAT_RAW_OPAQUE) >= 0) { size -= 1; } if (output) { @@ -1316,6 +1402,21 @@ public final class StreamConfigurationMap { return false; } + private boolean isSupportedInternalConfiguration(int format, int dataspace, + Size size) { + StreamConfiguration[] configurations = + (dataspace == HAL_DATASPACE_DEPTH) ? mDepthConfigurations : mConfigurations; + + for (int i = 0; i < configurations.length; i++) { + if (configurations[i].getFormat() == format && + configurations[i].getSize().equals(size)) { + return true; + } + } + + return false; + } + /** * Return this {@link StreamConfigurationMap} as a string representation. * @@ -1351,6 +1452,8 @@ public final class StreamConfigurationMap { StringBuilder sb = new StringBuilder("StreamConfiguration("); appendOutputsString(sb); sb.append(", "); + appendHighResOutputsString(sb); + sb.append(", "); appendInputsString(sb); sb.append(", "); appendValidOutputFormatsForInputString(sb); @@ -1381,6 +1484,27 @@ public final class StreamConfigurationMap { sb.append(")"); } + private void appendHighResOutputsString(StringBuilder sb) { + sb.append("HighResolutionOutputs("); + int[] formats = getOutputFormats(); + for (int format : formats) { + Size[] sizes = getHighResolutionOutputSizes(format); + if (sizes == null) continue; + for (Size size : sizes) { + long minFrameDuration = getOutputMinFrameDuration(format, size); + long stallDuration = getOutputStallDuration(format, size); + sb.append(String.format("[w:%d, h:%d, format:%s(%d), min_duration:%d, " + + "stall:%d], ", size.getWidth(), size.getHeight(), formatToString(format), + format, minFrameDuration, stallDuration)); + } + } + // Remove the pending ", " + if (sb.charAt(sb.length() - 1) == ' ') { + sb.delete(sb.length() - 2, sb.length()); + } + sb.append(")"); + } + private void appendInputsString(StringBuilder sb) { sb.append("Inputs("); int[] formats = getInputFormats(); @@ -1479,15 +1603,21 @@ public final class StreamConfigurationMap { } // from system/core/include/system/graphics.h + private static final int HAL_PIXEL_FORMAT_RAW16 = 0x20; private static final int HAL_PIXEL_FORMAT_BLOB = 0x21; private static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22; + private static final int HAL_PIXEL_FORMAT_YCbCr_420_888 = 0x23; private static final int HAL_PIXEL_FORMAT_RAW_OPAQUE = 0x24; + private static final int HAL_PIXEL_FORMAT_RAW10 = 0x25; + private static final int HAL_PIXEL_FORMAT_RAW12 = 0x26; private static final int HAL_PIXEL_FORMAT_Y16 = 0x20363159; + private static final int HAL_DATASPACE_UNKNOWN = 0x0; private static final int HAL_DATASPACE_JFIF = 0x101; private static final int HAL_DATASPACE_DEPTH = 0x1000; + private static final long DURATION_20FPS_NS = 50000000L; /** * @see #getDurations(int, int) */ @@ -1505,15 +1635,20 @@ public final class StreamConfigurationMap { private final HighSpeedVideoConfiguration[] mHighSpeedVideoConfigurations; private final ReprocessFormatsMap mInputOutputFormatsMap; - /** ImageFormat -> num output sizes mapping */ - private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mOutputFormats = - new HashMap<Integer, Integer>(); - /** ImageFormat -> num input sizes mapping */ - private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mInputFormats = - new HashMap<Integer, Integer>(); - /** ImageFormat -> num depth output sizes mapping */ - private final HashMap</*ImageFormat*/Integer, /*Count*/Integer> mDepthOutputFormats = - new HashMap<Integer, Integer>(); + private final boolean mListHighResolution; + + /** internal format -> num output sizes mapping, not including slow high-res sizes, for + * non-depth dataspaces */ + private final SparseIntArray mOutputFormats = new SparseIntArray(); + /** internal format -> num output sizes mapping for slow high-res sizes, for non-depth + * dataspaces */ + private final SparseIntArray mHighResOutputFormats = new SparseIntArray(); + /** internal format -> num output sizes mapping for all non-depth dataspaces */ + private final SparseIntArray mAllOutputFormats = new SparseIntArray(); + /** internal format -> num input sizes mapping, for input reprocessing formats */ + private final SparseIntArray mInputFormats = new SparseIntArray(); + /** internal format -> num depth output sizes mapping, for HAL_DATASPACE_DEPTH */ + private final SparseIntArray mDepthOutputFormats = new SparseIntArray(); /** High speed video Size -> FPS range count mapping*/ private final HashMap</*HighSpeedVideoSize*/Size, /*Count*/Integer> mHighSpeedVideoSizeMap = new HashMap<Size, Integer>(); @@ -1522,4 +1657,3 @@ public final class StreamConfigurationMap { mHighSpeedVideoFpsRangeMap = new HashMap<Range<Integer>, Integer>(); } - diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java index 398a7e91a53d..2d7bbaa21c54 100644 --- a/core/java/android/hardware/camera2/params/TonemapCurve.java +++ b/core/java/android/hardware/camera2/params/TonemapCurve.java @@ -277,7 +277,7 @@ public final class TonemapCurve { return mHashCode; } - mHashCode = HashCodeHelpers.hashCode(mRed, mGreen, mBlue); + mHashCode = HashCodeHelpers.hashCodeGeneric(mRed, mGreen, mBlue); mHashCalculated = true; return mHashCode; diff --git a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java index 7b4aa09f86ff..731da8b6a721 100644 --- a/core/java/android/hardware/camera2/utils/HashCodeHelpers.java +++ b/core/java/android/hardware/camera2/utils/HashCodeHelpers.java @@ -30,7 +30,7 @@ public final class HashCodeHelpers { * * @return the numeric hash code */ - public static int hashCode(int[] array) { + public static int hashCode(int... array) { if (array == null) { return 0; } @@ -60,7 +60,7 @@ public final class HashCodeHelpers { * * @return the numeric hash code */ - public static int hashCode(float[] array) { + public static int hashCode(float... array) { if (array == null) { return 0; } @@ -83,7 +83,7 @@ public final class HashCodeHelpers { * * @return the numeric hash code */ - public static <T> int hashCode(T[] array) { + public static <T> int hashCodeGeneric(T... array) { if (array == null) { return 0; } @@ -97,56 +97,4 @@ public final class HashCodeHelpers { return h; } - public static <T> int hashCode(T a) { - return (a == null) ? 0 : a.hashCode(); - } - - public static <T> int hashCode(T a, T b) { - int h = hashCode(a); - - int x = (b == null) ? 0 : b.hashCode(); - h = ((h << 5) - h) ^ x; // (h * 31) XOR x - - return h; - } - - public static <T> int hashCode(T a, T b, T c) { - int h = hashCode(a, b); - - int x = (c == null) ? 0 : c.hashCode(); - h = ((h << 5) - h) ^ x; // (h * 31) XOR x - - return h; - } - - public static <T> int hashCode(T a, T b, T c, T d) { - int h = hashCode(a, b, c); - - int x = (d == null) ? 0 : d.hashCode(); - h = ((h << 5) - h) ^ x; // (h * 31) XOR x - - return h; - } - - public static int hashCode(int x) { - return hashCode(new int[] { x } ); - } - - public static int hashCode(int x, int y) { - return hashCode(new int[] { x, y } ); - } - - public static int hashCode(int x, int y, int z) { - return hashCode(new int[] { x, y, z } ); - } - - public static int hashCode(int x, int y, int z, int w) { - return hashCode(new int[] { x, y, z, w } ); - } - - public static int hashCode(int x, int y, int z, int w, int t) { - return hashCode(new int[] { x, y, z, w, t } ); - } - - } diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java index 40005a5be0f3..064b21a4254c 100644 --- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java +++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java @@ -79,4 +79,30 @@ public class SurfaceUtils { throw new IllegalArgumentException("Surface was abandoned", e); } } + + /** + * Get the Surface dataspace. + * + * @param surface The surface to be queried for dataspace. + * @return dataspace of the surface. + * + * @throws IllegalArgumentException if the surface is already abandoned. + */ + public static int getSurfaceDataspace(Surface surface) { + try { + return LegacyCameraDevice.detectSurfaceDataspace(surface); + } catch (BufferQueueAbandonedException e) { + throw new IllegalArgumentException("Surface was abandoned", e); + } + } + + /** + * Return true is the consumer is one of the consumers that can accept + * producer overrides of the default dimensions and format. + * + */ + public static boolean isFlexibleConsumer(Surface output) { + return LegacyCameraDevice.isFlexibleConsumer(output); + } + } diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index b9f7365d8ce5..80476ea6d844 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2110,6 +2110,8 @@ public class ConnectivityManager { * can automatically log in to a captive portal without user intervention. * * @param network The {@link Network} of the network that is being evaluated. + * + * @hide */ public void onPreCheck(Network network) {} @@ -2379,6 +2381,14 @@ public class ConnectivityManager { * Status of the request can be followed by listening to the various * callbacks described in {@link NetworkCallback}. The {@link Network} * can be used to direct traffic to the network. + * <p>It is presently unsupported to request a network with mutable + * {@link NetworkCapabilities} such as + * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or + * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} + * as these {@code NetworkCapabilities} represent states that a particular + * network may never attain, and whether a network will attain these states + * is unknown prior to bringing up the network so the framework does not + * know how to go about satisfing a request with these capabilities. * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. * @@ -2386,6 +2396,8 @@ public class ConnectivityManager { * @param networkCallback The {@link NetworkCallback} to be utilized for this * request. Note the callback must not be shared - they * uniquely specify this request. + * @throws IllegalArgumentException if {@code request} specifies any mutable + * {@code NetworkCapabilities}. */ public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) { sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, @@ -2467,12 +2479,22 @@ public class ConnectivityManager { * <p> * The request may be released normally by calling * {@link #releaseNetworkRequest(android.app.PendingIntent)}. + * <p>It is presently unsupported to request a network with either + * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or + * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL} + * as these {@code NetworkCapabilities} represent states that a particular + * network may never attain, and whether a network will attain these states + * is unknown prior to bringing up the network so the framework does not + * know how to go about satisfing a request with these capabilities. * <p>This method requires the caller to hold the permission * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}. * @param request {@link NetworkRequest} describing this request. * @param operation Action to perform when the network is available (corresponds * to the {@link NetworkCallback#onAvailable} call. Typically * comes from {@link PendingIntent#getBroadcast}. Cannot be null. + * @throws IllegalArgumentException if {@code request} contains either + * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or + * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}. */ public void requestNetwork(NetworkRequest request, PendingIntent operation) { checkPendingIntent(operation); diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index cf747cf0379f..658051c9ebf1 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -173,12 +173,17 @@ public final class NetworkCapabilities implements Parcelable { * Indicates that connectivity on this network was successfully validated. For example, for a * network with NET_CAPABILITY_INTERNET, it means that Internet connectivity was successfully * detected. - * @hide */ public static final int NET_CAPABILITY_VALIDATED = 16; + /** + * Indicates that this network was found to have a captive portal in place last time it was + * probed. + */ + public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; + private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS; - private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED; + private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL; /** * Adds the given capability to this {@code NetworkCapability} instance. diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 87e8c5e6f8ee..97b85e2531d0 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -1469,13 +1469,30 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo * </tr> * <tr> * <td>art.gc.gc-count-rate-histogram</td> - * <td>The histogram of the number of garbage collection runs per 10 seconds.</td> + * <td>Every 10 seconds, the gc-count-rate is computed as the number of garbage + * collection runs that have occurred over the last 10 + * seconds. art.gc.gc-count-rate-histogram is a histogram of the gc-count-rate + * samples taken since the process began. The histogram can be used to identify + * instances of high rates of garbage collection runs. For example, a histogram + * of "0:34503,1:45350,2:11281,3:8088,4:43,5:8" shows that most of the time + * there are between 0 and 2 garbage collection runs every 10 seconds, but there + * were 8 distinct 10-second intervals in which 5 garbage collection runs + * occurred.</td> * <td>{@code 0:34503,1:45350,2:11281,3:8088,4:43,5:8}</td> * <td>23</td> * </tr> * <tr> * <td>art.gc.blocking-gc-count-rate-histogram</td> - * <td>The histogram of the number of garbage collection runs per 10 seconds.</td> + * <td>Every 10 seconds, the blocking-gc-count-rate is computed as the number of + * blocking garbage collection runs that have occurred over the last 10 + * seconds. art.gc.blocking-gc-count-rate-histogram is a histogram of the + * blocking-gc-count-rate samples taken since the process began. The histogram + * can be used to identify instances of high rates of blocking garbage + * collection runs. For example, a histogram of "0:99269,1:1,2:1" shows that + * most of the time there are zero blocking garbage collection runs every 10 + * seconds, but there was one 10-second interval in which one blocking garbage + * collection run occurred, and there was one interval in which two blocking + * garbage collection runs occurred.</td> * <td>{@code 0:99269,1:1,2:1}</td> * <td>23</td> * </tr> diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 1cc2d334c477..f10b982af750 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -1919,9 +1919,9 @@ public final class StrictMode { for (int i = 0; i < numViolations; ++i) { if (LOG_V) Log.d(TAG, "strict mode violation stacks read from binder call. i=" + i); ViolationInfo info = new ViolationInfo(p, !currentlyGathering); - if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 10000) { + if (info.crashInfo.stackTrace != null && info.crashInfo.stackTrace.length() > 30000) { String front = info.crashInfo.stackTrace.substring(256); - // 10000 characters is way too large for this to be any sane kind of + // 30000 characters is way too large for this to be any sane kind of // strict mode collection of stacks. We've had a problem where we leave // strict mode violations associated with the thread, and it keeps tacking // more and more stacks on to the violations. Looks like we're in this casse, diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 00350ec92a36..9770941babc4 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -449,6 +449,22 @@ public class UserManager { public static final String DISALLOW_RECORD_AUDIO = "no_record_audio"; /** + * This user restriction has an effect only in a managed profile. + * If set: + * Intent filters of activities in the parent profile with action + * {@link android.content.Intent#ACTION_VIEW}, + * category {@link android.content.Intent#CATEGORY_BROWSABLE}, scheme http or https, and which + * define a host can handle intents from the managed profile. + * The default value is <code>false</code>. + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean + * @see #setUserRestrictions(Bundle) + * @see #getUserRestrictions() + */ + public static final String ALLOW_PARENT_APP_LINKING = "allow_parent_app_linking"; + + /** * Application restriction key that is used to indicate the pending arrival * of real restrictions for the app. * diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 8d115279291b..e33baa9ebdda 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -137,6 +137,7 @@ public class VolumeInfo implements Parcelable { public final String id; public final int type; public final DiskInfo disk; + public final String partGuid; public int mountFlags = 0; public int mountUserId = -1; public int state = STATE_UNMOUNTED; @@ -149,10 +150,11 @@ public class VolumeInfo implements Parcelable { /** Framework state */ public final int mtpIndex; - public VolumeInfo(String id, int type, DiskInfo disk, int mtpIndex) { + public VolumeInfo(String id, int type, DiskInfo disk, String partGuid, int mtpIndex) { this.id = Preconditions.checkNotNull(id); this.type = type; this.disk = disk; + this.partGuid = partGuid; this.mtpIndex = mtpIndex; } @@ -164,6 +166,7 @@ public class VolumeInfo implements Parcelable { } else { disk = null; } + partGuid = parcel.readString(); mountFlags = parcel.readInt(); mountUserId = parcel.readInt(); state = parcel.readInt(); @@ -385,6 +388,7 @@ public class VolumeInfo implements Parcelable { pw.increaseIndent(); pw.printPair("type", DebugUtils.valueToString(getClass(), "TYPE_", type)); pw.printPair("diskId", getDiskId()); + pw.printPair("partGuid", partGuid); pw.printPair("mountFlags", DebugUtils.flagsToString(getClass(), "MOUNT_FLAG_", mountFlags)); pw.printPair("mountUserId", mountUserId); pw.printPair("state", DebugUtils.valueToString(getClass(), "STATE_", state)); @@ -453,6 +457,7 @@ public class VolumeInfo implements Parcelable { } else { parcel.writeInt(0); } + parcel.writeString(partGuid); parcel.writeInt(mountFlags); parcel.writeInt(mountUserId); parcel.writeInt(state); diff --git a/core/java/android/os/storage/VolumeRecord.java b/core/java/android/os/storage/VolumeRecord.java index 096e2dd30cea..cb1630516a27 100644 --- a/core/java/android/os/storage/VolumeRecord.java +++ b/core/java/android/os/storage/VolumeRecord.java @@ -39,6 +39,7 @@ public class VolumeRecord implements Parcelable { public final int type; public final String fsUuid; + public String partGuid; public String nickname; public int userFlags; @@ -50,6 +51,7 @@ public class VolumeRecord implements Parcelable { public VolumeRecord(Parcel parcel) { type = parcel.readInt(); fsUuid = parcel.readString(); + partGuid = parcel.readString(); nickname = parcel.readString(); userFlags = parcel.readInt(); } @@ -79,6 +81,8 @@ public class VolumeRecord implements Parcelable { pw.increaseIndent(); pw.printPair("type", DebugUtils.valueToString(VolumeInfo.class, "TYPE_", type)); pw.printPair("fsUuid", fsUuid); + pw.printPair("partGuid", partGuid); + pw.println(); pw.printPair("nickname", nickname); pw.printPair("userFlags", DebugUtils.flagsToString(VolumeRecord.class, "USER_FLAG_", userFlags)); @@ -133,6 +137,7 @@ public class VolumeRecord implements Parcelable { public void writeToParcel(Parcel parcel, int flags) { parcel.writeInt(type); parcel.writeString(fsUuid); + parcel.writeString(partGuid); parcel.writeString(nickname); parcel.writeInt(userFlags); } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index aebe7f10d523..8ce1cbf43f7d 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -1743,6 +1743,9 @@ public final class ContactsContract { * * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated public static final class StreamItems implements StreamItemsColumns { @@ -2831,6 +2834,9 @@ public final class ContactsContract { * * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated public static final class StreamItems implements BaseColumns, StreamItemsColumns { @@ -3267,6 +3273,9 @@ public final class ContactsContract { * * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated public static final class StreamItems implements BaseColumns, StreamItemsColumns { @@ -3365,6 +3374,9 @@ public final class ContactsContract { * * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated public static final class StreamItemPhotos @@ -3415,6 +3427,9 @@ public final class ContactsContract { * @see ContactsContract.StreamItems * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated protected interface StreamItemsColumns { @@ -3805,6 +3820,9 @@ public final class ContactsContract { * * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns { @@ -3843,6 +3861,9 @@ public final class ContactsContract { * @see ContactsContract.StreamItemPhotos * @deprecated - Do not use. This will not be supported in the future. In the future, * cursors returned from related queries will be empty. + * + * @hide + * @removed */ @Deprecated protected interface StreamItemPhotosColumns { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 56cd1a741f10..9b5fbfaf562a 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6685,6 +6685,17 @@ public final class Settings { "wifi_mobile_data_transition_wakelock_timeout_ms"; /** + * This setting controls whether WiFi configurations created by a Device Owner app + * should be locked down (that is, be editable or removable only by the Device Owner App, + * not even by Settings app). + * This setting takes integer values. Non-zero values mean DO created configurations + * are locked down. Value of zero means they are not. Default value in the absence of + * actual value to this setting is 0. + */ + public static final String WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN = + "wifi_device_owner_configs_lockdown"; + + /** * The operational wifi frequency band * Set to one of {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO}, * {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ} or diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java index 82f65c72a6f0..363376cb3d6b 100644 --- a/core/java/android/security/keymaster/KeymasterArguments.java +++ b/core/java/android/security/keymaster/KeymasterArguments.java @@ -85,6 +85,12 @@ public class KeymasterArguments implements Parcelable { mArguments.add(new KeymasterDateArgument(tag, value)); } + public void addDateIfNotNull(int tag, Date value) { + if (value != null) { + mArguments.add(new KeymasterDateArgument(tag, value)); + } + } + private KeymasterArgument getArgumentByTag(int tag) { for (KeymasterArgument arg : mArguments) { if (arg.tag == tag) { diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index 225e70d5fc77..455e1b25df18 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -29,8 +29,8 @@ import com.android.internal.telephony.ITelephonyRegistry; * <p> * To extend this class, you must declare the service in your manifest file to require the * {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent - * filter with the {@link #CONFIG_SERVICE_INTERFACE} action if the service exposes carrier config - * and the {@link #BIND_SERVICE_INTERFACE} action if the service should have a long-lived binding. + * filter with the {@link #CARRIER_SERVICE_INTERFACE}. If the service should have a long-lived + * binding, set android.service.carrier.LONG_LIVED_BINDING to true in the service's metadata. * For example: * </p> * @@ -39,16 +39,16 @@ import com.android.internal.telephony.ITelephonyRegistry; * android:label="@string/service_name" * android:permission="android.permission.BIND_CARRIER_SERVICES"> * <intent-filter> - * <action android:name="android.service.carrier.ConfigService" /> - * <action android:name="android.service.carrier.BindService" /> + * <action android:name="android.service.carrier.CarrierService" /> * </intent-filter> + * <meta-data android:name="android.service.carrier.LONG_LIVED_BINDING" + * android:value="true" /> * </service> * }</pre> */ public abstract class CarrierService extends Service { - public static final String CONFIG_SERVICE_INTERFACE = "android.service.carrier.ConfigService"; - public static final String BIND_SERVICE_INTERFACE = "android.service.carrier.BindService"; + public static final String CARRIER_SERVICE_INTERFACE = "android.service.carrier.CarrierService"; private static ITelephonyRegistry sRegistry; @@ -127,13 +127,7 @@ public abstract class CarrierService extends Service { @Override @CallSuper public IBinder onBind(Intent intent) { - switch (intent.getAction()) { - case CONFIG_SERVICE_INTERFACE: - case BIND_SERVICE_INTERFACE: - return mStubWrapper; - default: - return null; - } + return mStubWrapper; } /** diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 39dd29b671a6..f9e216a2de5b 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -1146,20 +1146,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall mContentFrame.requestApplyInsets(); } - /** @hide */ - public void onHandleAssist(Bundle assistBundle) { - } - public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { - if (data != null) { - Bundle assistContext = data.getBundle(Intent.EXTRA_ASSIST_CONTEXT); - if (assistContext != null) { - assistContext.putParcelable(AssistStructure.ASSIST_KEY, structure); - assistContext.putParcelable(AssistContent.ASSIST_KEY, content); - data.putBundle(Intent.EXTRA_ASSIST_CONTEXT, assistContext); - } - } - onHandleAssist(data); } public void onHandleScreenshot(Bitmap screenshot) { diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index d51aa7939c3d..d8f7158cb69d 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -465,6 +465,11 @@ public class TextUtils { return false; } + /** {@hide} */ + public static String nullIfEmpty(@Nullable String str) { + return isEmpty(str) ? null : str; + } + /** * Returns the length that the specified CharSequence would have if * spaces and control characters were trimmed from the start and end, diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java index 13a959e6fcdd..47d5c7982d0a 100644 --- a/core/java/android/text/format/Formatter.java +++ b/core/java/android/text/format/Formatter.java @@ -16,6 +16,7 @@ package android.text.format; +import android.annotation.Nullable; import android.content.Context; import android.content.res.Resources; import android.net.NetworkUtils; @@ -52,7 +53,10 @@ public final class Formatter { * @param sizeBytes size value to be formatted, in bytes * @return formatted string with the number */ - public static String formatFileSize(Context context, long sizeBytes) { + public static String formatFileSize(@Nullable Context context, long sizeBytes) { + if (context == null) { + return ""; + } final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0); return context.getString(com.android.internal.R.string.fileSizeSuffix, res.value, res.units); @@ -62,7 +66,10 @@ public final class Formatter { * Like {@link #formatFileSize}, but trying to generate shorter numbers * (showing fewer digits of precision). */ - public static String formatShortFileSize(Context context, long sizeBytes) { + public static String formatShortFileSize(@Nullable Context context, long sizeBytes) { + if (context == null) { + return ""; + } final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER); return context.getString(com.android.internal.R.string.fileSizeSuffix, res.value, res.units); diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java index 8b74a1e24a0d..585fc4e82583 100644 --- a/core/java/android/transition/Visibility.java +++ b/core/java/android/transition/Visibility.java @@ -504,13 +504,20 @@ public abstract class Visibility extends Transition { private final boolean mIsForcedVisibility; private final View mView; private final int mFinalVisibility; + private final ViewGroup mParent; + private boolean mEnded; boolean mCanceled = false; public DisappearListener(View view, int finalVisibility, boolean isForcedVisibility) { this.mView = view; this.mIsForcedVisibility = isForcedVisibility; this.mFinalVisibility = finalVisibility; + this.mParent = (ViewGroup) view.getParent(); + if (!isForcedVisibility && mParent != null) { + // Prevent a layout from including mView in its calculation. + mParent.suppressLayout(true); + } } @Override @@ -552,13 +559,39 @@ public abstract class Visibility extends Transition { hideViewWhenNotCanceled(); } + @Override + public void onTransitionPause(Transition transition) { + if (mParent != null && !mIsForcedVisibility) { + mParent.suppressLayout(false); + } + } + + @Override + public void onTransitionResume(Transition transition) { + if (mParent != null && !mIsForcedVisibility) { + mParent.suppressLayout(true); + } + } + private void hideViewWhenNotCanceled() { - if (!mCanceled) { - if (mIsForcedVisibility) { - mView.setTransitionAlpha(0); - } else { - mView.setVisibility(mFinalVisibility); + if (!mEnded) { + if (!mCanceled) { + if (mIsForcedVisibility) { + mView.setTransitionAlpha(0); + } else { + // Recreate the parent's display list in case it includes mView. + mView.setTransitionVisibility(mFinalVisibility); + if (mParent != null) { + mParent.invalidate(); + } + } + } + if (!mIsForcedVisibility && mParent != null) { + // Layout is allowed now that the View is in its final state + mParent.suppressLayout(false); } + // Do this only once + mEnded = true; } } } diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java index 211d01a9e2ef..55245065c082 100644 --- a/core/java/android/util/Range.java +++ b/core/java/android/util/Range.java @@ -350,7 +350,7 @@ public final class Range<T extends Comparable<? super T>> { */ @Override public int hashCode() { - return HashCodeHelpers.hashCode(mLower, mUpper); + return HashCodeHelpers.hashCodeGeneric(mLower, mUpper); } private final T mLower; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 4394cd8dea30..6026d04a1f21 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1399,6 +1399,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { private static native int nativeGetButtonState(long nativePtr); private static native void nativeSetButtonState(long nativePtr, int buttonState); private static native int nativeGetActionButton(long nativePtr); + private static native void nativeSetActionButton(long nativePtr, int actionButton); private static native void nativeOffsetLocation(long nativePtr, float deltaX, float deltaY); private static native float nativeGetXOffset(long nativePtr); private static native float nativeGetYOffset(long nativePtr); @@ -2284,6 +2285,16 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** + * Sets the action button for the event. + * + * @see #getActionButton() + * @hide + */ + public final void setActionButton(int button) { + nativeSetActionButton(mNativePtr, button); + } + + /** * Returns the original raw X coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 40745292542e..5970c3f738a0 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -453,6 +453,19 @@ public class SurfaceControl { } } + /** + * Sets the security of the surface. Setting the flag is equivalent to creating the + * Surface with the {@link #SECURE} flag. + */ + public void setSecure(boolean isSecure) { + checkNotReleased(); + if (isSecure) { + nativeSetFlags(mNativeObject, SECURE, SECURE); + } else { + nativeSetFlags(mNativeObject, 0, SECURE); + } + } + /* * set display parameters. * needs to be inside open/closeTransaction block diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index fd3ee4f84654..502a6bc3cff5 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -6032,7 +6032,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, public AccessibilityNodeInfo createAccessibilityNodeInfoInternal() { AccessibilityNodeProvider provider = getAccessibilityNodeProvider(); if (provider != null) { - return provider.createAccessibilityNodeInfo(View.NO_ID); + return provider.createAccessibilityNodeInfo(AccessibilityNodeProvider.HOST_VIEW_ID); } else { AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(this); onInitializeAccessibilityNodeInfo(info); @@ -6326,6 +6326,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { + if (mAttachInfo == null) { + return; + } + Rect bounds = mAttachInfo.mTmpInvalRect; getDrawingRect(bounds); @@ -8774,7 +8778,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void notifyViewAccessibilityStateChangedIfNeeded(int changeType) { - if (!AccessibilityManager.getInstance(mContext).isEnabled()) { + if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) { return; } if (mSendViewStateChangedAccessibilityEvent == null) { @@ -8796,7 +8800,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void notifySubtreeAccessibilityStateChangedIfNeeded() { - if (!AccessibilityManager.getInstance(mContext).isEnabled()) { + if (!AccessibilityManager.getInstance(mContext).isEnabled() || mAttachInfo == null) { return; } if ((mPrivateFlags2 & PFLAG2_SUBTREE_ACCESSIBILITY_STATE_CHANGED) == 0) { @@ -21037,6 +21041,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { + if (size < 0) { + throw new IllegalArgumentException("Measure spec size must be >= 0"); + } return (size & ~MODE_MASK) | (mode & MODE_MASK); } } diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index d06cd83479c3..9ab0ace4d7e0 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -150,7 +150,7 @@ public abstract class ViewStructure { * @param size The size, in pixels, of the text. * @param fgColor The foreground color, packed as 0xAARRGGBB. * @param bgColor The background color, packed as 0xAARRGGBB. - * @param style Style flags, as defined by {@link android.app.AssistStructure.ViewNode}. + * @param style Style flags, as defined by {@link android.app.assist.AssistStructure.ViewNode}. */ public abstract void setTextStyle(float size, int fgColor, int bgColor, int style); @@ -221,7 +221,7 @@ public abstract class ViewStructure { * children at <var>index</var>. * @return Returns an fresh {@link ViewStructure} ready to be filled in. */ - public abstract ViewAssistStructure newChild(int index); + public abstract ViewStructure newChild(int index); /** * Like {@link #newChild}, but allows the caller to asynchronously populate the returned @@ -231,7 +231,7 @@ public abstract class ViewStructure { * population is done. * @return Returns an fresh {@link ViewStructure} ready to be filled in. */ - public abstract ViewAssistStructure asyncNewChild(int index); + public abstract ViewStructure asyncNewChild(int index); /** * Call when done populating a {@link ViewStructure} returned by diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index ab793e038675..87706ef64a55 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -1115,7 +1115,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par record.mParcelableData = parcel.readParcelable(null); parcel.readList(record.mText, null); record.mSourceWindowId = parcel.readInt(); - record.mSourceNodeId = parcel.readLong(); + record.mSourceNode = parcel.readParcelable(null); record.mSealed = (parcel.readInt() == 1); } @@ -1167,7 +1167,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par parcel.writeParcelable(record.mParcelableData, flags); parcel.writeList(record.mText); parcel.writeInt(record.mSourceWindowId); - parcel.writeLong(record.mSourceNodeId); + // create copy of the node here because the node would be recycled just after it is written + // to parcel + parcel.writeParcelable(record.mSourceNode != null ? + AccessibilityNodeInfo.obtain(record.mSourceNode) : null, flags); parcel.writeInt(record.mSealed ? 1 : 0); } @@ -1191,7 +1194,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par builder.append("\n"); builder.append("; ContentChangeTypes: ").append(mContentChangeTypes); builder.append("; sourceWindowId: ").append(mSourceWindowId); - builder.append("; mSourceNodeId: ").append(mSourceNodeId); + if (mSourceNode != null) { + builder.append("; mSourceNodeId: ").append(mSourceNode.getSourceNodeId()); + } for (int i = 0; i < getRecordCount(); i++) { final AccessibilityRecord record = getRecord(i); builder.append(" Record "); diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 36de8f3689bf..86ed499cabc0 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -2821,7 +2821,7 @@ public class AccessibilityNodeInfo implements Parcelable { * @param parcel A parcel containing the state of a {@link AccessibilityNodeInfo}. */ private void initFromParcel(Parcel parcel) { - mSealed = (parcel.readInt() == 1); + final boolean sealed = (parcel.readInt() == 1); mSourceNodeId = parcel.readLong(); mWindowId = parcel.readInt(); mParentNodeId = parcel.readLong(); @@ -2911,6 +2911,8 @@ public class AccessibilityNodeInfo implements Parcelable { parcel.readInt() == 1, parcel.readInt() == 1); } + + mSealed = sealed; } /** diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index cc6a71d1250b..f99690adcffa 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -90,7 +90,7 @@ public class AccessibilityRecord { int mAddedCount= UNDEFINED; int mRemovedCount = UNDEFINED; - long mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED); + AccessibilityNodeInfo mSourceNode; int mSourceWindowId = UNDEFINED; CharSequence mClassName; @@ -135,16 +135,24 @@ public class AccessibilityRecord { */ public void setSource(View root, int virtualDescendantId) { enforceNotSealed(); - final boolean important; - if (virtualDescendantId == UNDEFINED) { - important = (root != null) ? root.isImportantForAccessibility() : true; - } else { - important = true; + boolean important = true; + mSourceWindowId = UNDEFINED; + clearSourceNode(); + if (root != null) { + if (virtualDescendantId == UNDEFINED || + virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + important = root.isImportantForAccessibility(); + mSourceNode = root.createAccessibilityNodeInfo(); + } else { + AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider(); + if (provider != null) { + mSourceNode = provider.createAccessibilityNodeInfo(virtualDescendantId); + } + } + + mSourceWindowId = root.getAccessibilityWindowId(); } setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important); - mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED; - final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED; - mSourceNodeId = AccessibilityNodeInfo.makeNodeId(rootViewId, virtualDescendantId); } /** @@ -158,13 +166,11 @@ public class AccessibilityRecord { */ public AccessibilityNodeInfo getSource() { enforceSealed(); - if (mConnectionId == UNDEFINED || mSourceWindowId == UNDEFINED - || AccessibilityNodeInfo.getAccessibilityViewId(mSourceNodeId) == UNDEFINED) { - return null; + if (mSourceNode != null) { + return AccessibilityNodeInfo.obtain(mSourceNode); } - AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); - return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, mSourceWindowId, - mSourceNodeId, false, GET_SOURCE_PREFETCH_FLAGS); + + return null; } /** @@ -619,7 +625,7 @@ public class AccessibilityRecord { * @hide */ public long getSourceNodeId() { - return mSourceNodeId; + return mSourceNode != null ? mSourceNode.getSourceNodeId() : UNDEFINED; } /** @@ -633,6 +639,9 @@ public class AccessibilityRecord { public void setConnectionId(int connectionId) { enforceNotSealed(); mConnectionId = connectionId; + if (mSourceNode != null) { + mSourceNode.setConnectionId(mConnectionId); + } } /** @@ -644,6 +653,9 @@ public class AccessibilityRecord { */ public void setSealed(boolean sealed) { mSealed = sealed; + if (mSourceNode != null) { + mSourceNode.setSealed(sealed); + } } /** @@ -782,7 +794,9 @@ public class AccessibilityRecord { mParcelableData = record.mParcelableData; mText.addAll(record.mText); mSourceWindowId = record.mSourceWindowId; - mSourceNodeId = record.mSourceNodeId; + if (record.mSourceNode != null) { + mSourceNode = AccessibilityNodeInfo.obtain(record.mSourceNode); + } mConnectionId = record.mConnectionId; } @@ -807,11 +821,18 @@ public class AccessibilityRecord { mBeforeText = null; mParcelableData = null; mText.clear(); - mSourceNodeId = AccessibilityNodeInfo.makeNodeId(UNDEFINED, UNDEFINED); + clearSourceNode(); mSourceWindowId = UNDEFINED; mConnectionId = UNDEFINED; } + private void clearSourceNode() { + if (mSourceNode != null) { + mSourceNode.recycle(); + mSourceNode = null; + } + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java index 410d39cb18c4..14f0b0a06218 100644 --- a/core/java/android/view/accessibility/CaptioningManager.java +++ b/core/java/android/view/accessibility/CaptioningManager.java @@ -266,11 +266,19 @@ public class CaptioningManager { * background colors, edge properties, and typeface. */ public static final class CaptionStyle { - /** Packed value for a color of 'none' and a cached opacity of 100%. */ + /** + * Packed value for a color of 'none' and a cached opacity of 100%. + * + * @hide + */ private static final int COLOR_NONE_OPAQUE = 0x000000FF; - /** Packed value for an unspecified color and opacity. */ - private static final int COLOR_UNSPECIFIED = 0x000001FF; + /** + * Packed value for a color of 'default' and opacity of 100%. + * + * @hide + */ + public static final int COLOR_UNSPECIFIED = 0x00FFFFFF; private static final CaptionStyle WHITE_ON_BLACK; private static final CaptionStyle BLACK_ON_WHITE; @@ -350,11 +358,11 @@ public class CaptioningManager { private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor, int windowColor, String rawTypeface) { - mHasForegroundColor = foregroundColor != COLOR_UNSPECIFIED; - mHasBackgroundColor = backgroundColor != COLOR_UNSPECIFIED; + mHasForegroundColor = hasColor(foregroundColor); + mHasBackgroundColor = hasColor(backgroundColor); mHasEdgeType = edgeType != EDGE_TYPE_UNSPECIFIED; - mHasEdgeColor = edgeColor != COLOR_UNSPECIFIED; - mHasWindowColor = windowColor != COLOR_UNSPECIFIED; + mHasEdgeColor = hasColor(edgeColor); + mHasWindowColor = hasColor(windowColor); // Always use valid colors, even when no override is specified, to // ensure backwards compatibility with apps targeting KitKat MR2. @@ -368,6 +376,20 @@ public class CaptioningManager { } /** + * Returns whether a packed color indicates a non-default value. + * + * @param packedColor the packed color value + * @return {@code true} if a non-default value is specified + * @hide + */ + public static boolean hasColor(int packedColor) { + // Matches the color packing code from Settings. "Default" packed + // colors are indicated by zero alpha and non-zero red/blue. The + // cached alpha value used by Settings is stored in green. + return (packedColor >>> 24) != 0 || (packedColor & 0xFFFF00) == 0; + } + + /** * Applies a caption style, overriding any properties that are specified * in the overlay caption. * diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index e050bdab63f6..a916887c513a 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -4517,34 +4517,39 @@ public class Editor { final float eventY = event.getY(); switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: + if (extractedTextModeWillBeStarted()) { + // Prevent duplicating the selection handles until the mode starts. + hide(); + } else { + // Remember finger down position, to be able to start selection from there. + mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition( + eventX, eventY); - // Remember finger down position, to be able to start selection from there. - mMinTouchOffset = mMaxTouchOffset = mTextView.getOffsetForPosition( - eventX, eventY); - - // Double tap detection - if (mGestureStayedInTapRegion) { - if (mDoubleTap) { - final float deltaX = eventX - mDownPositionX; - final float deltaY = eventY - mDownPositionY; - final float distanceSquared = deltaX * deltaX + deltaY * deltaY; - - ViewConfiguration viewConfiguration = ViewConfiguration.get( - mTextView.getContext()); - int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop(); - boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop; - - if (stayedInArea && isPositionOnText(eventX, eventY)) { - selectCurrentWordAndStartDrag(); - mDiscardNextActionUp = true; + // Double tap detection + if (mGestureStayedInTapRegion) { + if (mDoubleTap) { + final float deltaX = eventX - mDownPositionX; + final float deltaY = eventY - mDownPositionY; + final float distanceSquared = deltaX * deltaX + deltaY * deltaY; + + ViewConfiguration viewConfiguration = ViewConfiguration.get( + mTextView.getContext()); + int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop(); + boolean stayedInArea = + distanceSquared < doubleTapSlop * doubleTapSlop; + + if (stayedInArea && isPositionOnText(eventX, eventY)) { + selectCurrentWordAndStartDrag(); + mDiscardNextActionUp = true; + } } } - } - mDownPositionX = eventX; - mDownPositionY = eventY; - mGestureStayedInTapRegion = true; - mHaventMovedEnoughToStartDrag = true; + mDownPositionX = eventX; + mDownPositionY = eventY; + mGestureStayedInTapRegion = true; + mHaventMovedEnoughToStartDrag = true; + } break; case MotionEvent.ACTION_POINTER_DOWN: diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index affc5daa35f7..339038eddf3f 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup { View baselineView = null; LayoutParams baselineParams = null; for (int i = 0; i < count; i++) { - final View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { final LayoutParams childParams = (LayoutParams) child.getLayoutParams(); if (baselineView == null || baselineParams == null @@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup { if (offsetHorizontalAxis) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) { centerHorizontal(child, params, width); @@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup { if (offsetVerticalAxis) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) { centerVertical(child, params, height); @@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup { final int verticalOffset = contentBounds.top - top; if (horizontalOffset != 0 || verticalOffset != 0) { for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE && child != ignore) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); if (horizontalGravity) { params.mLeft += horizontalOffset; params.mRight += horizontalOffset; @@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup { if (isLayoutRtl()) { final int offsetWidth = myWidth - width; for (int i = 0; i < count; i++) { - View child = getChildAt(i); + final View child = views[i]; if (child.getVisibility() != GONE) { - LayoutParams params = (LayoutParams) child.getLayoutParams(); + final LayoutParams params = (LayoutParams) child.getLayoutParams(); params.mLeft -= offsetWidth; params.mRight -= offsetWidth; } diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index fdabe913e80a..6abd1293edd5 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -711,9 +711,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { lp = generateDefaultLayoutParams(); } - if (addChild) { - addViewInLayout(child, 0, lp); - } + addViewInLayout(child, 0, lp); child.setSelected(hasFocus()); if (mDisableChildrenWhenDisabled) { @@ -743,6 +741,10 @@ public class Spinner extends AbsSpinner implements OnClickListener { childRight = childLeft + width; child.layout(childLeft, childTop, childRight, childBottom); + + if (!addChild) { + removeViewInLayout(child); + } } @Override diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index f733eab42534..e84ba9968de7 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -25,7 +25,7 @@ import android.annotation.StringRes; import android.annotation.StyleRes; import android.annotation.XmlRes; import android.app.Activity; -import android.app.AssistStructure; +import android.app.assist.AssistStructure; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -9443,10 +9443,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public void onRtlPropertiesChanged(int layoutDirection) { super.onRtlPropertiesChanged(layoutDirection); - mTextDir = getTextDirectionHeuristic(); - - if (mLayout != null) { - checkForRelayout(); + final TextDirectionHeuristic newTextDir = getTextDirectionHeuristic(); + if (mTextDir != newTextDir) { + mTextDir = newTextDir; + if (mLayout != null) { + checkForRelayout(); + } } } diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 678e92b35db8..1b55557e8dd7 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -100,6 +100,10 @@ public class ChooserActivity extends ResolverActivity { mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets); unbindService(sri.connection); mServiceConnections.remove(sri.connection); + if (mServiceConnections.isEmpty()) { + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); + sendVoiceChoicesIfNeeded(); + } break; case CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT: @@ -107,6 +111,7 @@ public class ChooserActivity extends ResolverActivity { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } unbindRemainingServices(); + sendVoiceChoicesIfNeeded(); break; default: @@ -384,6 +389,8 @@ public class ChooserActivity extends ResolverActivity { + WATCHDOG_TIMEOUT_MILLIS + "ms"); mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT, WATCHDOG_TIMEOUT_MILLIS); + } else { + sendVoiceChoicesIfNeeded(); } } @@ -418,6 +425,10 @@ public class ChooserActivity extends ResolverActivity { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); } + void onSetupVoiceInteraction() { + // Do nothing. We'll send the voice stuff ourselves. + } + void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) { if (mRefinementResultReceiver != null) { mRefinementResultReceiver.destroy(); @@ -956,6 +967,10 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name); unbindService(this); mServiceConnections.remove(this); + if (mServiceConnections.isEmpty()) { + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); + sendVoiceChoicesIfNeeded(); + } } @Override diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index e14f0584a0b8..fe3ab9e49743 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -16,10 +16,17 @@ package com.android.internal.app; +import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityThread; +import android.app.VoiceInteractor; +import android.app.VoiceInteractor.PickOptionRequest; +import android.app.VoiceInteractor.PickOptionRequest.Option; +import android.app.VoiceInteractor.Prompt; +import android.app.VoiceInteractor.Request; import android.os.AsyncTask; import android.provider.Settings; +import android.service.chooser.ChooserTarget; import android.text.TextUtils; import android.util.Slog; import android.widget.AbsListView; @@ -96,6 +103,7 @@ public class ResolverActivity extends Activity { private int mProfileSwitchMessageId = -1; private final ArrayList<Intent> mIntents = new ArrayList<>(); private ResolverComparator mResolverComparator; + private PickTargetOptionRequest mPickOptionRequest; private boolean mRegistered; private final PackageMonitor mPackageMonitor = new PackageMonitor() { @@ -242,6 +250,9 @@ public class ResolverActivity extends Activity { finish(); } }); + if (isVoiceInteraction()) { + rdl.setCollapsed(false); + } } if (title == null) { @@ -313,6 +324,39 @@ public class ResolverActivity extends Activity { }); bindProfileView(); } + + if (isVoiceInteraction()) { + onSetupVoiceInteraction(); + } + } + + /** + * Perform any initialization needed for voice interaction. + */ + void onSetupVoiceInteraction() { + // Do it right now. Subclasses may delay this and send it later. + sendVoiceChoicesIfNeeded(); + } + + void sendVoiceChoicesIfNeeded() { + if (!isVoiceInteraction()) { + // Clearly not needed. + return; + } + + + final Option[] options = new Option[mAdapter.getCount()]; + for (int i = 0, N = options.length; i < N; i++) { + options[i] = optionForChooserTarget(mAdapter.getItem(i), i); + } + + mPickOptionRequest = new PickTargetOptionRequest( + new Prompt(getTitle()), options, null); + getVoiceInteractor().submitRequest(mPickOptionRequest); + } + + Option optionForChooserTarget(TargetInfo target, int index) { + return new Option(target.getDisplayLabel(), index); } protected final void setAdditionalTargets(Intent[] intents) { @@ -473,6 +517,14 @@ public class ResolverActivity extends Activity { } @Override + protected void onDestroy() { + super.onDestroy(); + if (!isChangingConfigurations() && mPickOptionRequest != null) { + mPickOptionRequest.cancel(); + } + } + + @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (mAlwaysUseOption) { @@ -510,16 +562,12 @@ public class ResolverActivity extends Activity { try { ApplicationInfo appInfo = getPackageManager().getApplicationInfo( resolveInfo.activityInfo.packageName, 0 /* default flags */); - return versionNumberAtLeastL(appInfo.targetSdkVersion); + return appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP; } catch (NameNotFoundException e) { return false; } } - private boolean versionNumberAtLeastL(int versionNumber) { - return versionNumber >= Build.VERSION_CODES.LOLLIPOP; - } - private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos, boolean filtered) { boolean enabled = false; @@ -1644,4 +1692,39 @@ public class ResolverActivity extends Activity { && match <= IntentFilter.MATCH_CATEGORY_PATH; } + static class PickTargetOptionRequest extends PickOptionRequest { + public PickTargetOptionRequest(@Nullable Prompt prompt, Option[] options, + @Nullable Bundle extras) { + super(prompt, options, extras); + } + + @Override + public void onCancel() { + super.onCancel(); + final ResolverActivity ra = (ResolverActivity) getActivity(); + if (ra != null) { + ra.mPickOptionRequest = null; + ra.finish(); + } + } + + @Override + public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { + super.onPickOptionResult(finished, selections, result); + if (selections.length != 1) { + // TODO In a better world we would filter the UI presented here and let the + // user refine. Maybe later. + return; + } + + final ResolverActivity ra = (ResolverActivity) getActivity(); + if (ra != null) { + final TargetInfo ti = ra.mAdapter.getItem(selections[0].getIndex()); + if (ra.onTargetSelected(ti, false)) { + ra.mPickOptionRequest = null; + ra.finish(); + } + } + } + } } diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index e4ccb4bdad7b..b78eca7a7f73 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -37,6 +37,9 @@ public class MetricsLogger implements MetricsConstants { public static final int ACTION_ACTIVITY_CHOOSER_PICKED_APP_TARGET = 215; public static final int ACTION_ACTIVITY_CHOOSER_PICKED_SERVICE_TARGET = 216; public static final int ACTION_ACTIVITY_CHOOSER_PICKED_STANDARD_TARGET = 217; + public static final int ACTION_BRIGHTNESS = 218; + public static final int ACTION_BRIGHTNESS_AUTO = 219; + public static final int BRIGHTNESS_DIALOG = 220; // Temporary constants go here, to await migration to MetricsConstants. public static void visible(Context context, int category) throws IllegalArgumentException { diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 15ed5bd0b539..0abd200ed1e5 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -23,6 +23,8 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowManager.LayoutParams.*; +import android.animation.Animator; +import android.animation.ObjectAnimator; import android.app.ActivityManagerNative; import android.app.SearchManager; import android.os.UserHandle; @@ -2216,6 +2218,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private OnPreDrawListener mFloatingToolbarPreDrawListener; private View mFloatingActionModeOriginatingView; private FloatingToolbar mFloatingToolbar; + private ObjectAnimator mFadeAnim; // View added at runtime to draw under the status bar area private View mStatusGuard; @@ -3345,6 +3348,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } private ActionMode createStandaloneActionMode(ActionMode.Callback callback) { + endOnGoingFadeAnimation(); cleanupPrimaryActionMode(); if (mPrimaryActionModeView == null) { if (isFloating()) { @@ -3384,6 +3388,32 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mPrimaryActionModePopup.showAtLocation( mPrimaryActionModeView.getApplicationWindowToken(), Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); + endOnGoingFadeAnimation(); + mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, + 0f, 1f); + mFadeAnim.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + mPrimaryActionModeView.setVisibility(VISIBLE); + } + + @Override + public void onAnimationEnd(Animator animation) { + mPrimaryActionModeView.setAlpha(1f); + mFadeAnim = null; + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + mFadeAnim.start(); } }; } else { @@ -3404,13 +3434,44 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return null; } + private void endOnGoingFadeAnimation() { + if (mFadeAnim != null) { + mFadeAnim.end(); + } + } + private void setHandledPrimaryActionMode(ActionMode mode) { + endOnGoingFadeAnimation(); mPrimaryActionMode = mode; mPrimaryActionMode.invalidate(); mPrimaryActionModeView.initForMode(mPrimaryActionMode); - mPrimaryActionModeView.setVisibility(View.VISIBLE); if (mPrimaryActionModePopup != null) { post(mShowPrimaryActionModePopup); + } else { + mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f); + mFadeAnim.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + mPrimaryActionModeView.setVisibility(View.VISIBLE); + } + + @Override + public void onAnimationEnd(Animator animation) { + mPrimaryActionModeView.setAlpha(1f); + mFadeAnim = null; + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + mFadeAnim.start(); } mPrimaryActionModeView.sendAccessibilityEvent( AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); @@ -3473,13 +3534,40 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { if (mode == mPrimaryActionMode) { if (mPrimaryActionModePopup != null) { removeCallbacks(mShowPrimaryActionModePopup); - mPrimaryActionModePopup.dismiss(); - } else if (mPrimaryActionModeView != null) { - mPrimaryActionModeView.setVisibility(GONE); } if (mPrimaryActionModeView != null) { - mPrimaryActionModeView.removeAllViews(); + endOnGoingFadeAnimation(); + mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, + 1f, 0f); + mFadeAnim.addListener(new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + mPrimaryActionModeView.setVisibility(GONE); + if (mPrimaryActionModePopup != null) { + mPrimaryActionModePopup.dismiss(); + } + mPrimaryActionModeView.removeAllViews(); + mFadeAnim = null; + } + + @Override + public void onAnimationCancel(Animator animation) { + + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + }); + mFadeAnim.start(); } + mPrimaryActionMode = null; } else if (mode == mFloatingActionMode) { cleanupFloatingActionModeViews(); diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 663c838f4b11..aea1585ae517 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -19,6 +19,7 @@ package com.android.internal.statusbar; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; +import com.android.internal.statusbar.NotificationVisibility; import android.service.notification.StatusBarNotification; /** @hide */ @@ -53,8 +54,8 @@ interface IStatusBarService int uid, int initialPid, String message, int userId); void onClearAllNotifications(int userId); void onNotificationClear(String pkg, String tag, int id, int userId); - void onNotificationVisibilityChanged( - in String[] newlyVisibleKeys, in String[] noLongerVisibleKeys); + void onNotificationVisibilityChanged( in NotificationVisibility[] newlyVisibleKeys, + in NotificationVisibility[] noLongerVisibleKeys); void onNotificationExpansionChanged(in String key, in boolean userAction, in boolean expanded); void setSystemUiVisibility(int vis, int mask, String cause); void setWindowState(int window, int state); diff --git a/core/java/com/android/internal/statusbar/NotificationVisibility.aidl b/core/java/com/android/internal/statusbar/NotificationVisibility.aidl new file mode 100644 index 000000000000..c0675511b814 --- /dev/null +++ b/core/java/com/android/internal/statusbar/NotificationVisibility.aidl @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2015, 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.statusbar; + +parcelable NotificationVisibility; + diff --git a/core/java/com/android/internal/statusbar/NotificationVisibility.java b/core/java/com/android/internal/statusbar/NotificationVisibility.java new file mode 100644 index 000000000000..2139ad02e4f3 --- /dev/null +++ b/core/java/com/android/internal/statusbar/NotificationVisibility.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015 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.statusbar; + +import android.os.Message; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.Log; + +import java.util.ArrayDeque; +import java.util.Collection; + +public class NotificationVisibility implements Parcelable { + private static final String TAG = "NoViz"; + private static final int MAX_POOL_SIZE = 25; + private static ArrayDeque<NotificationVisibility> sPool = new ArrayDeque<>(MAX_POOL_SIZE); + private static int sNexrId = 0; + + public String key; + public int rank; + public boolean visible = true; + /*package*/ int id; + + private NotificationVisibility() { + id = sNexrId++; + } + + private NotificationVisibility(String key, int rank, boolean visibile) { + this(); + this.key = key; + this.rank = rank; + this.visible = visibile; + } + + @Override + public String toString() { + return "NotificationVisibility(id=" + id + + "key=" + key + + " rank=" + rank + + (visible?" visible":"") + + " )"; + } + + @Override + public NotificationVisibility clone() { + return obtain(this.key, this.rank, this.visible); + } + + @Override + public int hashCode() { + // allow lookups by key, which _should_ never be null. + return key == null ? 0 : key.hashCode(); + } + + @Override + public boolean equals(Object that) { + // allow lookups by key, which _should_ never be null. + if (that instanceof NotificationVisibility) { + NotificationVisibility thatViz = (NotificationVisibility) that; + return (key == null && thatViz.key == null) || key.equals(thatViz.key); + } + return false; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(this.key); + out.writeInt(this.rank); + out.writeInt(this.visible ? 1 : 0); + } + + private void readFromParcel(Parcel in) { + this.key = in.readString(); + this.rank = in.readInt(); + this.visible = in.readInt() != 0; + } + + /** + * Return a new NotificationVisibility instance from the global pool. Allows us to + * avoid allocating new objects in many cases. + */ + public static NotificationVisibility obtain(String key, int rank, boolean visible) { + NotificationVisibility vo = obtain(); + vo.key = key; + vo.rank = rank; + vo.visible = visible; + return vo; + } + + private static NotificationVisibility obtain(Parcel in) { + NotificationVisibility vo = obtain(); + vo.readFromParcel(in); + return vo; + } + + private static NotificationVisibility obtain() { + synchronized (sPool) { + if (!sPool.isEmpty()) { + return sPool.poll(); + } + } + return new NotificationVisibility(); + } + + /** + * Return a NotificationVisibility instance to the global pool. + * <p> + * You MUST NOT touch the NotificationVisibility after calling this function because it has + * effectively been freed. + * </p> + */ + public void recycle() { + if (key == null) { + // do nothing on multiple recycles + return; + } + key = null; + if (sPool.size() < MAX_POOL_SIZE) { + synchronized (sPool) { + sPool.offer(this); + } + } + } + + /** + * Parcelable.Creator that instantiates NotificationVisibility objects + */ + public static final Parcelable.Creator<NotificationVisibility> CREATOR + = new Parcelable.Creator<NotificationVisibility>() + { + public NotificationVisibility createFromParcel(Parcel parcel) + { + return obtain(parcel); + } + + public NotificationVisibility[] newArray(int size) + { + return new NotificationVisibility[size]; + } + }; +} + diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 585cbc943788..1071e12cb6e3 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -144,6 +144,14 @@ public class ResolverDrawerLayout extends ViewGroup { return mCollapseOffset > 0; } + public void setCollapsed(boolean collapsed) { + if (!isLaidOut()) { + mOpenOnLayout = collapsed; + } else { + smoothScrollTo(collapsed ? mCollapsibleHeight : 0, 0); + } + } + private boolean isMoving() { return mIsDragging || !mScroller.isFinished(); } @@ -575,7 +583,13 @@ public class ResolverDrawerLayout extends ViewGroup { @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) { - smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY); + if (mOnDismissedListener != null + && velocityY < 0 && mCollapseOffset > mCollapsibleHeight) { + smoothScrollTo(mCollapsibleHeight + mUncollapsibleHeight, velocityY); + mDismissOnScrollerFinished = true; + } else { + smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY); + } return true; } return false; diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java index 26f5bf4143e6..458a2ca19d18 100644 --- a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java +++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java @@ -27,48 +27,69 @@ public class PreferredActivityBackupHelper extends BlobBackupHelper { private static final boolean DEBUG = false; // current schema of the backup state blob - private static final int STATE_VERSION = 2; + private static final int STATE_VERSION = 3; // key under which the preferred-activity state blob is committed to backup private static final String KEY_PREFERRED = "preferred-activity"; + // key for default-browser [etc] state + private static final String KEY_DEFAULT_APPS = "default-apps"; + + // intent-filter verification state + private static final String KEY_INTENT_VERIFICATION = "intent-verification"; + public PreferredActivityBackupHelper() { - super(STATE_VERSION, KEY_PREFERRED); + super(STATE_VERSION, + KEY_PREFERRED, + KEY_DEFAULT_APPS, + KEY_INTENT_VERIFICATION); } @Override protected byte[] getBackupPayload(String key) { - if (KEY_PREFERRED.equals(key)) { - if (DEBUG) { - Slog.v(TAG, "Checking whether to back up"); - } - IPackageManager pm = AppGlobals.getPackageManager(); - try { - return pm.getPreferredActivityBackup(UserHandle.USER_OWNER); - } catch (Exception e) { - Slog.e(TAG, "Unable to store backup payload", e); - // fall through to report null state + IPackageManager pm = AppGlobals.getPackageManager(); + if (DEBUG) { + Slog.d(TAG, "Handling backup of " + key); + } + try { + switch (key) { + case KEY_PREFERRED: + return pm.getPreferredActivityBackup(UserHandle.USER_OWNER); + case KEY_DEFAULT_APPS: + return pm.getDefaultAppsBackup(UserHandle.USER_OWNER); + case KEY_INTENT_VERIFICATION: + return pm.getIntentFilterVerificationBackup(UserHandle.USER_OWNER); + default: + Slog.w(TAG, "Unexpected backup key " + key); } - } else { - Slog.w(TAG, "Unexpected backup key " + key); + } catch (Exception e) { + Slog.e(TAG, "Unable to store payload " + key); } return null; } @Override protected void applyRestoredPayload(String key, byte[] payload) { - if (KEY_PREFERRED.equals(key)) { - if (DEBUG) { - Slog.v(TAG, "Restoring"); - } - IPackageManager pm = AppGlobals.getPackageManager(); - try { - pm.restorePreferredActivities(payload, UserHandle.USER_OWNER); - } catch (Exception e) { - Slog.e(TAG, "Unable to restore", e); + IPackageManager pm = AppGlobals.getPackageManager(); + if (DEBUG) { + Slog.d(TAG, "Handling restore of " + key); + } + try { + switch (key) { + case KEY_PREFERRED: + pm.restorePreferredActivities(payload, UserHandle.USER_OWNER); + break; + case KEY_DEFAULT_APPS: + pm.restoreDefaultApps(payload, UserHandle.USER_OWNER); + break; + case KEY_INTENT_VERIFICATION: + pm.restoreIntentFilterVerification(payload, UserHandle.USER_OWNER); + break; + default: + Slog.w(TAG, "Unexpected restore key " + key); } - } else { - Slog.w(TAG, "Unexpected restore key " + key); + } catch (Exception e) { + Slog.w(TAG, "Unable to restore key " + key); } } } diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp index 9b5fb3a60119..2116da0b3b51 100644 --- a/core/jni/android_graphics_Canvas.cpp +++ b/core/jni/android_graphics_Canvas.cpp @@ -175,24 +175,24 @@ static jboolean quickRejectPath(JNIEnv* env, jobject, jlong canvasHandle, jlong static jboolean clipRect(JNIEnv*, jobject, jlong canvasHandle, jfloat l, jfloat t, jfloat r, jfloat b, jint opHandle) { SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); - bool emptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op); - return emptyClip ? JNI_FALSE : JNI_TRUE; + bool nonEmptyClip = get_canvas(canvasHandle)->clipRect(l, t, r, b, op); + return nonEmptyClip ? JNI_TRUE : JNI_FALSE; } static jboolean clipPath(JNIEnv* env, jobject, jlong canvasHandle, jlong pathHandle, jint opHandle) { SkPath* path = reinterpret_cast<SkPath*>(pathHandle); SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); - bool emptyClip = get_canvas(canvasHandle)->clipPath(path, op); - return emptyClip ? JNI_FALSE : JNI_TRUE; + bool nonEmptyClip = get_canvas(canvasHandle)->clipPath(path, op); + return nonEmptyClip ? JNI_TRUE : JNI_FALSE; } static jboolean clipRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong deviceRgnHandle, jint opHandle) { SkRegion* deviceRgn = reinterpret_cast<SkRegion*>(deviceRgnHandle); SkRegion::Op op = static_cast<SkRegion::Op>(opHandle); - bool emptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op); - return emptyClip ? JNI_FALSE : JNI_TRUE; + bool nonEmptyClip = get_canvas(canvasHandle)->clipRegion(deviceRgn, op); + return nonEmptyClip ? JNI_TRUE : JNI_FALSE; } static void drawColor(JNIEnv* env, jobject, jlong canvasHandle, jint color, jint modeHandle) { diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index f5f8b1f6324d..c9d609c31537 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -257,6 +257,8 @@ private: case SENSOR_TYPE_MAGNETIC_FIELD: case SENSOR_TYPE_ACCELEROMETER: case SENSOR_TYPE_GYROSCOPE: + case SENSOR_TYPE_GRAVITY: + case SENSOR_TYPE_LINEAR_ACCELERATION: status = buffer[i].vector.status; break; case SENSOR_TYPE_HEART_RATE: diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index 7d8d151df0d2..995d39f33fbb 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -18,6 +18,8 @@ #define LOG_TAG "DngCreator_JNI" #include <inttypes.h> #include <string.h> +#include <algorithm> +#include <memory> #include <utils/Log.h> #include <utils/Errors.h> @@ -25,7 +27,6 @@ #include <utils/RefBase.h> #include <utils/Vector.h> #include <cutils/properties.h> - #include <system/camera_metadata.h> #include <camera/CameraMetadata.h> #include <img_utils/DngUtils.h> @@ -37,15 +38,6 @@ #include <img_utils/StripSource.h> #include "core_jni_helpers.h" -#include <utils/Log.h> -#include <utils/Errors.h> -#include <utils/StrongPointer.h> -#include <utils/RefBase.h> -#include <utils/Vector.h> -#include <cutils/properties.h> - -#include <string.h> -#include <inttypes.h> #include "android_runtime/AndroidRuntime.h" #include "android_runtime/android_hardware_camera2_CameraMetadata.h" @@ -63,6 +55,14 @@ using namespace img_utils; return; \ } +#define BAIL_IF_INVALID_R(expr, jnienv, tagId, writer) \ + if ((expr) != OK) { \ + jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ + "Invalid metadata for tag %s (%x)", (writer)->getTagName(tagId), (tagId)); \ + return -1; \ + } + + #define BAIL_IF_EMPTY(entry, jnienv, tagId, writer) \ if (entry.count == 0) { \ jniThrowExceptionFmt(jnienv, "java/lang/IllegalArgumentException", \ @@ -111,11 +111,14 @@ enum { class NativeContext : public LightRefBase<NativeContext> { public: - NativeContext(); + NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result); virtual ~NativeContext(); TiffWriter* getWriter(); + std::shared_ptr<const CameraMetadata> getCharacteristics() const; + std::shared_ptr<const CameraMetadata> getResult() const; + uint32_t getThumbnailWidth(); uint32_t getThumbnailHeight(); const uint8_t* getThumbnail(); @@ -125,11 +128,16 @@ public: private: Vector<uint8_t> mCurrentThumbnail; TiffWriter mWriter; + std::shared_ptr<CameraMetadata> mCharacteristics; + std::shared_ptr<CameraMetadata> mResult; uint32_t mThumbnailWidth; uint32_t mThumbnailHeight; }; -NativeContext::NativeContext() : mThumbnailWidth(0), mThumbnailHeight(0) {} +NativeContext::NativeContext(const CameraMetadata& characteristics, const CameraMetadata& result) : + mCharacteristics(std::make_shared<CameraMetadata>(characteristics)), + mResult(std::make_shared<CameraMetadata>(result)), mThumbnailWidth(0), + mThumbnailHeight(0) {} NativeContext::~NativeContext() {} @@ -137,6 +145,14 @@ TiffWriter* NativeContext::getWriter() { return &mWriter; } +std::shared_ptr<const CameraMetadata> NativeContext::getCharacteristics() const { + return mCharacteristics; +} + +std::shared_ptr<const CameraMetadata> NativeContext::getResult() const { + return mResult; +} + uint32_t NativeContext::getThumbnailWidth() { return mThumbnailWidth; } @@ -626,25 +642,92 @@ uint32_t DirectStripSource::getIfd() const { // End of DirectStripSource // ---------------------------------------------------------------------------- -static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, jint width, jint height) { - bool hasThumbnail = writer->hasIfd(TIFF_IFD_SUB1); +/** + * Given a buffer crop rectangle relative to the pixel array size, and the active array crop + * rectangle for the camera characteristics, set the default crop rectangle in the TiffWriter + * relative to the buffer crop rectangle origin. + */ +static status_t calculateAndSetCrop(JNIEnv* env, const CameraMetadata& characteristics, + uint32_t bufXMin, uint32_t bufYMin, uint32_t bufWidth, uint32_t bufHeight, + TiffWriter* writer) { + + camera_metadata_ro_entry entry = + characteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE); + uint32_t xmin = static_cast<uint32_t>(entry.data.i32[0]); + uint32_t ymin = static_cast<uint32_t>(entry.data.i32[1]); + uint32_t width = static_cast<uint32_t>(entry.data.i32[2]); + uint32_t height = static_cast<uint32_t>(entry.data.i32[3]); + + uint32_t aLeft = xmin; + uint32_t aTop = ymin; + uint32_t aRight = xmin + width; + uint32_t aBottom = ymin + height; + + const uint32_t margin = 8; // Default margin recommended by Adobe for interpolation. + + uint32_t bLeft = bufXMin + margin; + uint32_t bTop = bufYMin + margin; + uint32_t bRight = bufXMin + bufWidth - margin; + uint32_t bBottom = bufYMin + bufHeight - margin; + + uint32_t defaultCropOrigin[] = {std::max(aLeft, bLeft), std::max(aTop, bTop)}; + uint32_t defaultCropSize[] = {std::min(aRight, bRight) - defaultCropOrigin[0], + std::min(aBottom, bBottom) - defaultCropOrigin[1]}; + + BAIL_IF_INVALID_R(writer->addEntry(TAG_DEFAULTCROPORIGIN, 2, defaultCropOrigin, + TIFF_IFD_0), env, TAG_DEFAULTCROPORIGIN, writer); + BAIL_IF_INVALID_R(writer->addEntry(TAG_DEFAULTCROPSIZE, 2, defaultCropSize, + TIFF_IFD_0), env, TAG_DEFAULTCROPSIZE, writer); + + return OK; +} +static bool validateDngHeader(JNIEnv* env, TiffWriter* writer, + const CameraMetadata& characteristics, jint width, jint height) { // TODO: handle lens shading map, etc. conversions for other raw buffer sizes. - uint32_t metadataWidth = *(writer->getEntry(TAG_IMAGEWIDTH, (hasThumbnail) ? TIFF_IFD_SUB1 : - TIFF_IFD_0)->getData<uint32_t>()); - uint32_t metadataHeight = *(writer->getEntry(TAG_IMAGELENGTH, (hasThumbnail) ? TIFF_IFD_SUB1 : - TIFF_IFD_0)->getData<uint32_t>()); + if (width <= 0) { + jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \ + "Image width %d is invalid", width); + return false; + } - if (width < 0 || metadataWidth != static_cast<uint32_t>(width)) { + if (height <= 0) { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \ - "Metadata width %d doesn't match image width %d", metadataWidth, width); + "Image height %d is invalid", height); return false; } - if (height < 0 || metadataHeight != static_cast<uint32_t>(height)) { + camera_metadata_ro_entry preCorrectionEntry = + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); + camera_metadata_ro_entry pixelArrayEntry = + characteristics.find(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE); + + int pWidth = static_cast<int>(pixelArrayEntry.data.i32[0]); + int pHeight = static_cast<int>(pixelArrayEntry.data.i32[1]); + int cWidth = static_cast<int>(preCorrectionEntry.data.i32[2]); + int cHeight = static_cast<int>(preCorrectionEntry.data.i32[3]); + + bool matchesPixelArray = (pWidth == width && pHeight == height); + bool matchesPreCorrectionArray = (cWidth == width && cHeight == height); + + if (matchesPixelArray) { + if (calculateAndSetCrop(env, characteristics, 0, 0, static_cast<uint32_t>(pWidth), + static_cast<uint32_t>(pHeight), writer) != OK) { + return false; + } + } else if (matchesPreCorrectionArray) { + if (calculateAndSetCrop(env, characteristics, + static_cast<uint32_t>(preCorrectionEntry.data.i32[0]), + static_cast<uint32_t>(preCorrectionEntry.data.i32[1]), + static_cast<uint32_t>(preCorrectionEntry.data.i32[2]), + static_cast<uint32_t>(preCorrectionEntry.data.i32[3]), writer) != OK) { + return false; + } + } else { jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", \ - "Metadata height %d doesn't match image height %d", - metadataHeight, height); + "Image dimensions (w=%d,h=%d) are invalid, must match either the pixel " + "array size (w=%d, h=%d) or the pre-correction array size (w=%d, h=%d)", + width, height, pWidth, pHeight, cWidth, cHeight); return false; } @@ -854,7 +937,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt return; } - sp<NativeContext> nativeContext = new NativeContext(); + sp<NativeContext> nativeContext = new NativeContext(characteristics, results); TiffWriter* writer = nativeContext->getWriter(); writer->addIfd(TIFF_IFD_0); @@ -906,7 +989,7 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt { // Set dimensions camera_metadata_entry entry = - characteristics.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE); + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); BAIL_IF_EMPTY(entry, env, TAG_IMAGEWIDTH, writer); uint32_t width = static_cast<uint32_t>(entry.data.i32[2]); uint32_t height = static_cast<uint32_t>(entry.data.i32[3]); @@ -1356,16 +1439,16 @@ static void DngCreator_init(JNIEnv* env, jobject thiz, jobject characteristicsPt } { - // Setup default crop + crop origin tags - uint32_t margin = 8; // Default margin recommended by Adobe for interpolation. - uint32_t dimensionLimit = 128; // Smallest image dimension crop margin from. - if (imageWidth >= dimensionLimit && imageHeight >= dimensionLimit) { - uint32_t defaultCropOrigin[] = {margin, margin}; - uint32_t defaultCropSize[] = {imageWidth - 2 * margin, imageHeight - 2 * margin}; - BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPORIGIN, 2, defaultCropOrigin, - TIFF_IFD_0), env, TAG_DEFAULTCROPORIGIN, writer); - BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPSIZE, 2, defaultCropSize, - TIFF_IFD_0), env, TAG_DEFAULTCROPSIZE, writer); + // Set dimensions + camera_metadata_entry entry = + characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE); + BAIL_IF_EMPTY(entry, env, TAG_DEFAULTCROPSIZE, writer); + uint32_t xmin = static_cast<uint32_t>(entry.data.i32[0]); + uint32_t ymin = static_cast<uint32_t>(entry.data.i32[1]); + uint32_t width = static_cast<uint32_t>(entry.data.i32[2]); + uint32_t height = static_cast<uint32_t>(entry.data.i32[3]); + if (calculateAndSetCrop(env, characteristics, xmin, ymin, width, height, writer) != OK) { + return; } } @@ -1874,7 +1957,7 @@ static void DngCreator_nativeWriteImage(JNIEnv* env, jobject thiz, jobject outSt } // Validate DNG header - if (!validateDngHeader(env, writer, width, height)) { + if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) { return; } @@ -1978,7 +2061,7 @@ static void DngCreator_nativeWriteInputStream(JNIEnv* env, jobject thiz, jobject } // Validate DNG header - if (!validateDngHeader(env, writer, width, height)) { + if (!validateDngHeader(env, writer, *(context->getCharacteristics()), width, height)) { return; } diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index 5bef65370aac..63915ed1c134 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -436,6 +436,23 @@ static jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz return fmt; } +static jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) { + ALOGV("nativeDetectSurfaceDataspace"); + sp<ANativeWindow> anw; + if ((anw = getNativeWindow(env, surface)) == NULL) { + ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__); + return BAD_VALUE; + } + int32_t fmt = 0; + status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt); + if(err != NO_ERROR) { + ALOGE("%s: Error while querying surface dataspace %s (%d).", __FUNCTION__, strerror(-err), + err); + return err; + } + return fmt; +} + static jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface, jintArray dimens) { ALOGV("nativeGetSurfaceDimens"); @@ -717,6 +734,9 @@ static JNINativeMethod gCameraDeviceMethods[] = { { "nativeDetectSurfaceType", "(Landroid/view/Surface;)I", (void *)LegacyCameraDevice_nativeDetectSurfaceType }, + { "nativeDetectSurfaceDataspace", + "(Landroid/view/Surface;)I", + (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace }, { "nativeDetectSurfaceDimens", "(Landroid/view/Surface;[I)I", (void *)LegacyCameraDevice_nativeDetectSurfaceDimens }, diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 2ee9283c0fd4..0f5ba83fa19a 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -230,9 +230,11 @@ static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativeP static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - const status_t err = parcel->writeInt32(val); - if (err != NO_ERROR) { - signalExceptionForError(env, clazz, err); + if (parcel != NULL) { + const status_t err = parcel->writeInt32(val); + if (err != NO_ERROR) { + signalExceptionForError(env, clazz, err); + } } } diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index 91a3c7e6891f..0e2ec6b85209 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -77,7 +77,7 @@ NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue) : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue), mWaitingForVsync(false) { - ALOGV("receiver %p ~ Initializing input event receiver.", this); + ALOGV("receiver %p ~ Initializing display event receiver.", this); } NativeDisplayEventReceiver::~NativeDisplayEventReceiver() { diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index eb28c4de12cf..98c17c03b1a7 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -462,6 +462,12 @@ static int android_view_MotionEvent_nativeGetActionButton(JNIEnv* env, jclass cl return event->getActionButton(); } +static void android_view_MotionEvent_nativeSetActionButton(JNIEnv* env, jclass clazz, + jlong nativePtr, jint button) { + MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); + event->setActionButton(button); +} + static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz, jlong nativePtr) { MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr); @@ -779,6 +785,9 @@ static JNINativeMethod gMotionEventMethods[] = { { "nativeGetActionButton", "(J)I", (void*)android_view_MotionEvent_nativeGetActionButton}, + { "nativeSetActionButton", + "(JI)V", + (void*)android_view_MotionEvent_nativeSetActionButton}, { "nativeIsTouchEvent", "(J)Z", (void*)android_view_MotionEvent_nativeIsTouchEvent }, diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b1b772ae7e7e..9637cf5bf903 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -349,20 +349,6 @@ android:description="@string/permdesc_writeContacts" android:protectionLevel="dangerous" /> - <!-- @deprecated No longer enforced. This was last enforced in API version 22. --> - <permission android:name="android.permission.READ_PROFILE" - android:permissionGroup="android.permission-group.CONTACTS" - android:label="@string/permlab_readProfile" - android:description="@string/permdesc_readProfile" - android:protectionLevel="dangerous" /> - - <!-- @deprecated No longer enforced. This was last enforced in API version 22. --> - <permission android:name="android.permission.WRITE_PROFILE" - android:permissionGroup="android.permission-group.CONTACTS" - android:label="@string/permlab_writeProfile" - android:description="@string/permdesc_writeProfile" - android:protectionLevel="dangerous" /> - <!-- ====================================================================== --> <!-- Permissions for accessing user's calendar --> <!-- ====================================================================== --> @@ -511,42 +497,6 @@ android:description="@string/permdesc_sdcardWrite" android:protectionLevel="dangerous" /> - <!-- =============================================================== --> - <!-- Permissions for accessing social info --> - <!-- =============================================================== --> - <eat-comment /> - - <!-- Used for permissions that provide access to the user's social connections, - such as contacts, call logs, social stream, etc. This includes - both reading and writing of this data (which should generally be - expressed as two distinct permissions). --> - - <permission-group android:name="android.permission-group.SOCIAL_INFO" - android:label="@string/permgrouplab_socialInfo" - android:icon="@drawable/perm_group_social_info" - android:description="@string/permgroupdesc_socialInfo" - android:permissionGroupFlags="personalInfo" - android:priority="1200" /> - - <!-- Allows an application to read from the user's social stream. - @deprecated This functionality will be unsupported in the future; cursors returned - will be empty. Please do not use. --> - <permission android:name="android.permission.READ_SOCIAL_STREAM" - android:permissionGroup="android.permission-group.SOCIAL_INFO" - android:protectionLevel="dangerous" - android:label="@string/permlab_readSocialStream" - android:description="@string/permdesc_readSocialStream" /> - - <!-- Allows an application to write (but not read) the user's - social stream data. - @deprecated This functionality will be unsupported in the future; cursors returned - will be empty. Please do not use. --> - <permission android:name="android.permission.WRITE_SOCIAL_STREAM" - android:permissionGroup="android.permission-group.SOCIAL_INFO" - android:protectionLevel="dangerous" - android:label="@string/permlab_writeSocialStream" - android:description="@string/permdesc_writeSocialStream" /> - <!-- ====================================================================== --> <!-- Permissions for accessing the device location --> <!-- ====================================================================== --> @@ -741,7 +691,41 @@ android:protectionLevel="normal" /> <!-- ====================================================================== --> - <!-- INSTALLTIME PERMISSIONS --> + <!-- REMOVED PERMISSIONS --> + <!-- ====================================================================== --> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.READ_PROFILE" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.WRITE_PROFILE" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.READ_SOCIAL_STREAM" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.WRITE_SOCIAL_STREAM" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.READ_USER_DICTIONARY" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- @hide We need to keep this around for backwards compatibility --> + <permission android:name="android.permission.WRITE_USER_DICTIONARY" + android:protectionLevel="normal" + android:permissionFlags="hide"/> + + <!-- ====================================================================== --> + <!-- INSTALL PERMISSIONS --> <!-- ====================================================================== --> <!-- ================================== --> @@ -780,36 +764,6 @@ android:protectionLevel="signature|system" /> <!-- =============================================================== --> - <!-- Permissions for accessing the user dictionary--> - <!-- =============================================================== --> - <eat-comment /> - - <!-- Used for permissions that provide access to the user - calendar to create / view events.--> - <permission-group android:name="android.permission-group.USER_DICTIONARY" - android:label="@string/permgrouplab_dictionary" - android:icon="@drawable/perm_group_user_dictionary" - android:description="@string/permgroupdesc_dictionary" - android:permissionGroupFlags="personalInfo" - android:priority="1100" /> - - <!-- Allows an application to read the user dictionary. This should - really only be required by an IME, or a dictionary editor like - the Settings app. --> - <permission android:name="android.permission.READ_USER_DICTIONARY" - android:permissionGroup="android.permission-group.USER_DICTIONARY" - android:label="@string/permlab_readDictionary" - android:description="@string/permdesc_readDictionary" - android:protectionLevel="dangerous"/> - - <!-- Allows an application to write to the user dictionary. --> - <permission android:name="android.permission.WRITE_USER_DICTIONARY" - android:permissionGroup="android.permission-group.USER_DICTIONARY" - android:label="@string/permlab_writeDictionary" - android:description="@string/permdesc_writeDictionary" - android:protectionLevel="normal"/> - - <!-- =============================================================== --> <!-- Permissions for setting the device alarm --> <!-- =============================================================== --> <eat-comment /> @@ -2090,7 +2044,7 @@ <p>Declaring the permission implies intention to use the API and the user of the device can grant permission through the Settings application. --> <permission android:name="android.permission.PACKAGE_USAGE_STATS" - android:protectionLevel="signature|development|appop" /> + android:protectionLevel="signature|system|development|appop" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @hide Allows an application to change the app idle state of an app. @@ -2457,6 +2411,7 @@ <intent-filter> <action android:name="android.intent.action.CHOOSER" /> <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.VOICE" /> </intent-filter> </activity> <activity android:name="com.android.internal.app.IntentForwarderActivity" diff --git a/core/res/res/drawable-hdpi/perm_group_storage.png b/core/res/res/drawable-hdpi/perm_group_storage.png Binary files differdeleted file mode 100644 index 598e1ccc7c83..000000000000 --- a/core/res/res/drawable-hdpi/perm_group_storage.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index 62fbcdccc3fe..000000000000 --- a/core/res/res/drawable-hdpi/perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index c62dd4c1bda9..000000000000 --- a/core/res/res/drawable-hdpi/perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/perm_group_storage.png b/core/res/res/drawable-mdpi/perm_group_storage.png Binary files differdeleted file mode 100644 index b7a06fbb3934..000000000000 --- a/core/res/res/drawable-mdpi/perm_group_storage.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index a303dc1afd57..000000000000 --- a/core/res/res/drawable-mdpi/perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index 2fc4056457b7..000000000000 --- a/core/res/res/drawable-mdpi/perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/perm_group_storage.png b/core/res/res/drawable-xhdpi/perm_group_storage.png Binary files differdeleted file mode 100644 index a2d4d5e9b3d7..000000000000 --- a/core/res/res/drawable-xhdpi/perm_group_storage.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index 35d7d5fd9872..000000000000 --- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index 74e25ac09c10..000000000000 --- a/core/res/res/drawable-xhdpi/perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index 8c2cd1799f1a..000000000000 --- a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index 121d6cffb2e6..000000000000 --- a/core/res/res/drawable-xxhdpi/ic_perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/perm_group_storage.png b/core/res/res/drawable-xxhdpi/perm_group_storage.png Binary files differdeleted file mode 100644 index 837211e74722..000000000000 --- a/core/res/res/drawable-xxhdpi/perm_group_storage.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index 5b6ea3b0089a..000000000000 --- a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index d92e71912afc..000000000000 --- a/core/res/res/drawable-xxhdpi/perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/perm_group_storage.png b/core/res/res/drawable-xxxhdpi/perm_group_storage.png Binary files differdeleted file mode 100644 index 918b3ed0e295..000000000000 --- a/core/res/res/drawable-xxxhdpi/perm_group_storage.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png b/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png Binary files differdeleted file mode 100644 index 32942ca8aa53..000000000000 --- a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png b/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png Binary files differdeleted file mode 100644 index 343551fde7a9..000000000000 --- a/core/res/res/drawable-xxxhdpi/perm_group_user_dictionary_write.png +++ /dev/null diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml index 11078d337b1e..65da1f1241b4 100644 --- a/core/res/res/drawable/perm_group_storage.xml +++ b/core/res/res/drawable/perm_group_storage.xml @@ -14,8 +14,8 @@ Copyright (C) 2015 The Android Open Source Project limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="48dp" - android:height="48dp" + android:width="24dp" + android:height="24dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> <path diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml index 4b544d2244c1..2fa2054d5cad 100644 --- a/core/res/res/layout-land/time_picker_material.xml +++ b/core/res/res/layout-land/time_picker_material.xml @@ -17,21 +17,24 @@ <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:layoutDirection="ltr"> + <!-- Provides a background for the time layout that extends into the button bar area. --> <View android:id="@+id/time_header" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_column="0" + android:layout_column="@dimen/time_picker_column_start_material" android:layout_row="0" android:layout_rowSpan="3" - android:layout_gravity="center|fill" /> + android:layout_gravity="center|fill" + android:layoutDirection="locale" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_column="0" + android:layout_column="@dimen/time_picker_column_start_material" android:layout_row="1" android:layout_gravity="center|fill" android:paddingStart="?attr/dialogPreferredPadding" @@ -83,7 +86,8 @@ android:layout_height="wrap_content" android:layout_below="@+id/time_layout" android:layout_centerHorizontal="true" - android:orientation="vertical"> + android:orientation="vertical" + android:layoutDirection="locale"> <CheckedTextView android:id="@+id/am_label" @@ -116,28 +120,31 @@ android:layout="@layout/alert_dialog_title_material" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_column="1" + android:layout_column="@dimen/time_picker_column_end_material" android:layout_row="0" - android:layout_gravity="top|fill_horizontal" /> + android:layout_gravity="top|fill_horizontal" + android:layoutDirection="locale" /> <android.widget.RadialTimePickerView android:id="@+id/radial_picker" android:layout_width="@dimen/timepicker_radial_picker_dimen" android:layout_height="@dimen/timepicker_radial_picker_dimen" - android:layout_column="1" + android:layout_column="@dimen/time_picker_column_end_material" android:layout_row="1" android:layout_rowWeight="1" android:layout_gravity="center|fill" android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin" android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin" - android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" /> + android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" + android:layoutDirection="locale" /> <ViewStub android:id="@id/buttonPanel" android:layout="@layout/alert_dialog_button_bar_material" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_column="1" + android:layout_column="@dimen/time_picker_column_end_material" android:layout_row="2" - android:layout_gravity="bottom|fill_horizontal" /> + android:layout_gravity="bottom|fill_horizontal" + android:layoutDirection="locale" /> </GridLayout> diff --git a/core/res/res/values-ldrtl/dimens.xml b/core/res/res/values-ldrtl/dimens.xml new file mode 100644 index 000000000000..807c0424235d --- /dev/null +++ b/core/res/res/values-ldrtl/dimens.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> + +<resources> + <item type="dimen" format="integer" name="time_picker_column_start_material">1</item> + <item type="dimen" format="integer" name="time_picker_column_end_material">0</item> +</resources> diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index f31c1d61d7c5..3cb4d7cd2cc8 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -231,6 +231,9 @@ may cost the user money. Such permissions may be highlighted when shown to the user with this additional information. --> <flag name="costsMoney" value="0x0001" /> + <!-- Additional flag from base permission type: this permission is hidden + and should not show in the UI. --> + <flag name="hide" value="0x2" /> </attr> <!-- Specified the name of a group that this permission is associated diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index edbe1304d910..f6cefba7b77c 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -368,6 +368,9 @@ <!-- Boolean indicating whether the wifi chipset has dual frequency band support --> <bool translatable="false" name="config_wifi_dual_band_support">false</bool> + <!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled --> + <bool translatable="false" name="config_wifi_hotspot2_enabled">true</bool> + <!-- Device type information conforming to Annex B format in WiFi Direct specification. The default represents a dual-mode smartphone --> <string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string> @@ -1840,6 +1843,19 @@ <item>com.android.inputmethod.latin</item> </string-array> + <!-- The list of carrier applications which should be disabled until used. + This function suppresses update notifications for these pre-installed apps. + In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the + following conditions are met. + 1. Not currently carrier-privileged according to the inserted SIM + 2. Pre-installed + 3. In the default state (enabled but not explicitly) + And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted + that marks the app as carrier privileged. It also grants the app default permissions + for Phone and Location. As such, apps MUST only ever be added to this list if they + obtain user consent to access their location through other means. --> + <string-array name="config_disabledUntilUsedPreinstalledCarrierApps" translatable="false" /> + <!-- The list of classes that should be added to the notification ranking pipline. See {@link com.android.server.notification.NotificationSignalExtractor} --> <string-array name="config_notificationSignalExtractors"> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 7e74680255d2..09c1e6fa49b9 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -385,21 +385,24 @@ <item type="dimen" format="float" name="ambient_shadow_alpha">0.039</item> <item type="dimen" format="float" name="spot_shadow_alpha">0.19</item> - <!-- Floating toolbar dimensions --> - <dimen name="floating_toolbar_height">48dp</dimen> - <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen> - <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen> - <dimen name="floating_toolbar_menu_button_side_padding">16dp</dimen> - <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen> - <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen> - <dimen name="floating_toolbar_text_size">14sp</dimen> - <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen> - <dimen name="floating_toolbar_preferred_width">328dp</dimen> - <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen> - <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen> - <dimen name="floating_toolbar_horizontal_margin">16dp</dimen> - <dimen name="floating_toolbar_vertical_margin">8dp</dimen> - <dimen name="content_rect_bottom_clip_allowance">20dp</dimen> - - <dimen name="chooser_grid_padding">0dp</dimen> + <!-- Floating toolbar dimensions --> + <dimen name="floating_toolbar_height">48dp</dimen> + <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen> + <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen> + <dimen name="floating_toolbar_menu_button_side_padding">16dp</dimen> + <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen> + <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen> + <dimen name="floating_toolbar_text_size">14sp</dimen> + <dimen name="floating_toolbar_menu_button_minimum_width">48dp</dimen> + <dimen name="floating_toolbar_preferred_width">328dp</dimen> + <dimen name="floating_toolbar_minimum_overflow_height">96dp</dimen> + <dimen name="floating_toolbar_maximum_overflow_height">192dp</dimen> + <dimen name="floating_toolbar_horizontal_margin">16dp</dimen> + <dimen name="floating_toolbar_vertical_margin">8dp</dimen> + <dimen name="content_rect_bottom_clip_allowance">20dp</dimen> + + <dimen name="chooser_grid_padding">0dp</dimen> + + <item type="dimen" format="integer" name="time_picker_column_start_material">0</item> + <item type="dimen" format="integer" name="time_picker_column_end_material">1</item> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index ea0d349ccd76..246e43a33ff4 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -554,11 +554,6 @@ <string name="permgroupdesc_location">access this device\'s location</string> <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgrouplab_socialInfo">Your social information</string> - <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgroupdesc_socialInfo">Direct access to information about your contacts and social connections.</string> - - <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_calendar">Calendar</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_calendar">access your calendar</string> @@ -573,16 +568,6 @@ <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgroupdesc_storage">access photos, media, and files on your device</string> - <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgrouplab_dictionary">User Dictionary</string> - <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgroupdesc_dictionary">Read or write words in user dictionary.</string> - - <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgrouplab_bookmarks">Bookmarks and History</string> - <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permgroupdesc_bookmarks">Direct access to bookmarks and browser history.</string> - <!-- Title of a category of application permissioncds, listed so the user can choose whether they want to allow the application to do this. --> <string name="permgrouplab_microphone">Microphone</string> <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. --> @@ -901,23 +886,6 @@ <string name="permdesc_writeCallLog" product="default">Allows the app to modify your phone\'s call log, including data about incoming and outgoing calls. Malicious apps may use this to erase or modify your call log.</string> - - <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] --> - <string name="permlab_readProfile">read your own contact card</string> - <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] --> - <string name="permdesc_readProfile" product="default">Allows the app to read - personal profile information stored on your device, such as your name and - contact information. This means the app can identify you and may send your - profile information to others.</string> - - <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] --> - <string name="permlab_writeProfile">modify your own contact card</string> - <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] --> - <string name="permdesc_writeProfile" product="default">Allows the app to - change or add to personal profile information stored on your device, such - as your name and contact information. This means the app can identify you - and may send your profile information to others.</string> - <!-- Title of the body sensors permission, listed so the user can decide whether to allow the application to access body sensor data. [CHAR LIMIT=30] --> <string name="permlab_bodySensors">body sensors (like heart rate monitors) </string> @@ -925,23 +893,6 @@ <string name="permdesc_bodySensors" product="default">Allows the app to access data from sensors that monitor your physical condition, such as your heart rate.</string> - <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] --> - <string name="permlab_readSocialStream" product="default">read your social stream</string> - <string name="permdesc_readSocialStream" product="default">Allows the app - to access and sync social updates from you and your friends. Be careful - when sharing information -- this allows the app to read communications - between you and your friends on social networks, regardless of - confidentiality. Note: this permission may not be enforced on all social - networks.</string> - - <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] --> - <string name="permlab_writeSocialStream" product="default">write to your social stream</string> - <string name="permdesc_writeSocialStream" product="default">Allows the app to - display social updates from your friends. Be careful when sharing - information -- this allows the app to produce messages that may appear to - come from a friend. Note: this permission may not be enforced on all social - networks.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_readCalendar">read calendar events plus confidential information</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> @@ -1285,18 +1236,6 @@ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_readSyncStats">Allows an app to read the sync stats for an account, including the history of sync events and how much data is synced. </string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_readDictionary">read terms you added to the dictionary</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_readDictionary">Allows the app to read all words, - names and phrases that the user may have stored in the user dictionary.</string> - - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permlab_writeDictionary">add words to user-defined dictionary</string> - <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> - <string name="permdesc_writeDictionary">Allows the app to write new words into the - user dictionary.</string> - <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] --> <string name="permlab_sdcardRead" product="nosdcard">read the contents of your USB storage</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 483f83018f66..3a1a1568074d 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1128,6 +1128,7 @@ <java-symbol type="array" name="special_locale_names" /> <java-symbol type="array" name="config_cdma_dun_supported_types" /> <java-symbol type="array" name="config_disabledUntilUsedPreinstalledImes" /> + <java-symbol type="array" name="config_disabledUntilUsedPreinstalledCarrierApps" /> <java-symbol type="array" name="config_operatorConsideredNonRoaming" /> <java-symbol type="array" name="config_sameNamedOperatorConsideredRoaming" /> <java-symbol type="array" name="config_callBarringMMI" /> @@ -1648,6 +1649,7 @@ <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" /> <java-symbol type="bool" name="config_wifi_background_scan_support" /> <java-symbol type="bool" name="config_wifi_dual_band_support" /> + <java-symbol type="bool" name="config_wifi_hotspot2_enabled" /> <java-symbol type="bool" name="config_wimaxEnabled" /> <java-symbol type="bool" name="show_ongoing_ime_switcher" /> <java-symbol type="color" name="config_defaultNotificationColor" /> diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 18c83b4e499e..9548e51b0c74 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -93,11 +93,11 @@ <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU: http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements --> - <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}" /> + <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101" /> <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU: http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf --> - <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}" /> + <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|887" /> <!-- Georgia: 4 digits, known premium codes listed --> <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" /> @@ -184,6 +184,6 @@ <shortcode country="ua" pattern="\\d{4}" premium="444[3-9]|70[579]4|7540" /> <!-- USA: 5-6 digits (premium codes from https://www.premiumsmsrefunds.com/ShortCodes.htm) --> - <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="87902" /> + <shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" /> </shortcodes> diff --git a/docs/html/about/versions/android-4.0.3.jd b/docs/html/about/versions/android-4.0.3.jd index 5fa8547eed5b..4c2ccb96bfd3 100644 --- a/docs/html/about/versions/android-4.0.3.jd +++ b/docs/html/about/versions/android-4.0.3.jd @@ -78,19 +78,19 @@ can now sync that data with each of the user’s contacts, providing items in a stream along with photos for each.</p> <p>The database table that contains an individual contact’s social stream is -defined by {@link android.provider.ContactsContract.StreamItems}, the Uri for +defined by android.provider.ContactsContract.StreamItems, the Uri for which is nested within the {@link android.provider.ContactsContract.RawContacts} directory to which the stream items belong. Each social stream table includes several columns for metadata about each stream item, such as an icon representing the source (an avatar), a label for the item, the primary text content, comments about the item (such as responses from other people), and more. Photos associated with a stream are stored in another table, defined by -{@link android.provider.ContactsContract.StreamItemPhotos}, which is available -as a sub-directory of the {@link android.provider.ContactsContract.StreamItems} +android.provider.ContactsContract.StreamItemPhotos, which is available +as a sub-directory of the android.provider.ContactsContract.StreamItems Uri.</p> -<p>See {@link android.provider.ContactsContract.StreamItems} and -{@link android.provider.ContactsContract.StreamItemPhotos} for more information.</p> +<p>See android.provider.ContactsContract.StreamItems and +android.provider.ContactsContract.StreamItemPhotos for more information.</p> <p>To read or write social stream items for a contact, an application must request permission from the user by declaring <code><uses-permission @@ -272,8 +272,8 @@ let you check and manage video stabilization for a {@link android.hardware.Camer <p>The following are new permissions:</p> <ul> -<li>{@link android.Manifest.permission#READ_SOCIAL_STREAM} and -{@link android.Manifest.permission#WRITE_SOCIAL_STREAM}: Allow a sync +<li>android.Manifest.permission#READ_SOCIAL_STREAM and +android.Manifest.permission#WRITE_SOCIAL_STREAM: Allow a sync adapter to read and write social stream data to a contact in the shared Contacts Provider.</li> </ul> diff --git a/docs/html/about/versions/android-4.0.jd b/docs/html/about/versions/android-4.0.jd index 6c4ccb4c4958..cc1d1c70d9df 100644 --- a/docs/html/about/versions/android-4.0.jd +++ b/docs/html/about/versions/android-4.0.jd @@ -108,9 +108,9 @@ android.provider.ContactsContract.RawContacts} Uri; instead, you must add a prof the table at {@link android.provider.ContactsContract.Profile#CONTENT_RAW_CONTACTS_URI}. Raw contacts in this table are then aggregated into the single user-visible profile labeled "Me".</p> -<p>Adding a new raw contact for the profile requires the {@link -android.Manifest.permission#WRITE_PROFILE} permission. Likewise, in order to read from the profile -table, you must request the {@link android.Manifest.permission#READ_PROFILE} permission. However, +<p>Adding a new raw contact for the profile requires the +android.Manifest.permission#WRITE_PROFILE permission. Likewise, in order to read from the profile +table, you must request the android.Manifest.permission#READ_PROFILE permission. However, most apps should not need to read the user profile, even when contributing data to the profile. Reading the user profile is a sensitive permission and you should expect users to be skeptical of apps that request it.</p> @@ -1638,9 +1638,9 @@ messages to the device.</li> android.service.textservice.SpellCheckerService} must require this permission for itself.</li> <li>{@link android.Manifest.permission#BIND_VPN_SERVICE}: A service that implements {@link android.net.VpnService} must require this permission for itself.</li> -<li>{@link android.Manifest.permission#READ_PROFILE}: Provides read access to the {@link +<li>android.Manifest.permission#READ_PROFILE: Provides read access to the {@link android.provider.ContactsContract.Profile} provider.</li> -<li>{@link android.Manifest.permission#WRITE_PROFILE}: Provides write access to the {@link +<li>android.Manifest.permission#WRITE_PROFILE: Provides write access to the {@link android.provider.ContactsContract.Profile} provider.</li> </ul> diff --git a/docs/html/about/versions/android-4.1.jd b/docs/html/about/versions/android-4.1.jd index 76b90acdeb60..f8770fadc371 100644 --- a/docs/html/about/versions/android-4.1.jd +++ b/docs/html/about/versions/android-4.1.jd @@ -871,7 +871,7 @@ read access using this permission. If your application already requests write a automatically get read access as well. There is a new developer option to turn on read access restriction, for developers to test their applications against how Android will behave in the future.</dd> - <dt>{@link android.Manifest.permission#READ_USER_DICTIONARY}</dt> + <dt>android.Manifest.permission.READ_USER_DICTIONARY</dt> <dd>Allows an application to read the user dictionary. This should only be required by an IME, or a dictionary editor like the Settings app.</dd> <dt>{@link android.Manifest.permission#READ_CALL_LOG}</dt> @@ -879,7 +879,7 @@ IME, or a dictionary editor like the Settings app.</dd> incoming and outgoing calls.</dd> <dt>{@link android.Manifest.permission#WRITE_CALL_LOG}</dt> <dd>Allows an application to modify the system's call log stored on your phone</dd> - <dt>{@link android.Manifest.permission#WRITE_USER_DICTIONARY}</dt> + <dt>android.Manifest.permission.WRITE_USER_DICTIONARY</dt> <dd>Allows an application to write to the user's word dictionary.</dd> </dl> diff --git a/docs/html/distribute/googleplay/about.jd b/docs/html/distribute/googleplay/about.jd index 26520462824e..543d7d3f79af 100644 --- a/docs/html/distribute/googleplay/about.jd +++ b/docs/html/distribute/googleplay/about.jd @@ -1,7 +1,7 @@ page.title=The Google Play Opportunity meta.tags="visibility, growth, distributing" page.tags="play, apps, distributing, publishing" -page.metaDescription=Billons of downloads a month and growing. Get your apps in front of users at Google's scale. +page.metaDescription=Billions of downloads a month and growing. Get your apps in front of users at Google's scale. page.image=images/cards/google-play_2x.png @jd:body diff --git a/docs/html/distribute/googleplay/families/about.jd b/docs/html/distribute/googleplay/families/about.jd index bec9b6a9ff6e..9b85c9a48b12 100644 --- a/docs/html/distribute/googleplay/families/about.jd +++ b/docs/html/distribute/googleplay/families/about.jd @@ -50,7 +50,7 @@ frameborder="0" allowfullscreen></iframe> Designed for Families expands the visibility of your family content on Google Play, helping parents easily find your family-friendly apps and games throughout the store. And new features create a trusted environment that - empowers parents to make informed desicions and engage with your content. + empowers parents to make informed decisions and engage with your content. </p> <h3> Search diff --git a/docs/html/guide/topics/manifest/uses-permission-element.jd b/docs/html/guide/topics/manifest/uses-permission-element.jd index 939411406e36..bb93a702b34f 100644 --- a/docs/html/guide/topics/manifest/uses-permission-element.jd +++ b/docs/html/guide/topics/manifest/uses-permission-element.jd @@ -81,6 +81,7 @@ permission is needed only up to API level 18 with a declaration such as this: </pre> <p>This way, beginning with API level 19, the system will no longer grant your app the {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} permission.</p> +<p>This attribute was added in API level 19.</p> </dd> </dl></dd> diff --git a/docs/html/guide/topics/providers/contacts-provider.jd b/docs/html/guide/topics/providers/contacts-provider.jd index e3b998a7677f..2b145585ab83 100644 --- a/docs/html/guide/topics/providers/contacts-provider.jd +++ b/docs/html/guide/topics/providers/contacts-provider.jd @@ -57,7 +57,7 @@ page.title=Contacts Provider <li>{@link android.provider.ContactsContract.Contacts}</li> <li>{@link android.provider.ContactsContract.RawContacts}</li> <li>{@link android.provider.ContactsContract.Data}</li> - <li>{@link android.provider.ContactsContract.StreamItems}</li> + <li>android.provider.ContactsContract.StreamItems</li> </ol> <h2>Related Samples</h2> <ol> @@ -606,13 +606,13 @@ page.title=Contacts Provider Access to the user profile requires special permissions. In addition to the {@link android.Manifest.permission#READ_CONTACTS} and {@link android.Manifest.permission#WRITE_CONTACTS} permissions needed to read and write, access - to the user profile requires the {@link android.Manifest.permission#READ_PROFILE} and - {@link android.Manifest.permission#WRITE_PROFILE} permissions for read and write access, + to the user profile requires the android.Manifest.permission#READ_PROFILE and + android.Manifest.permission#WRITE_PROFILE permissions for read and write access, respectively. </p> <p> Remember that you should consider a user's profile to be sensitive. The permission - {@link android.Manifest.permission#READ_PROFILE} allows you to access the device user's + android.Manifest.permission#READ_PROFILE allows you to access the device user's personally-identifying data. Make sure to tell the user why you need user profile access permissions in the description of your application. </p> @@ -1826,8 +1826,8 @@ child elements that provide specific data to the </dl> <h2 id="SocialStream">Social Stream Data</h2> <p> - The {@link android.provider.ContactsContract.StreamItems} and - {@link android.provider.ContactsContract.StreamItemPhotos} tables + The android.provider.ContactsContract.StreamItems and + android.provider.ContactsContract.StreamItemPhotos tables manage incoming data from social networks. You can write a sync adapter that adds stream data from your own network to these tables, or you can read stream data from these tables and display it in your own application, or both. With these features, your social networking @@ -1836,7 +1836,7 @@ child elements that provide specific data to the <h3 id="StreamText">Social stream text</h3> <p> Stream items are always associated with a raw contact. The - {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} links to the + android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID links to the <code>_ID</code> value for the raw contact. The account type and account name of the raw contact are also stored in the stream item row. </p> @@ -1845,14 +1845,14 @@ child elements that provide specific data to the </p> <dl> <dt> - {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE} + android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE </dt> <dd> <strong>Required.</strong> The user's account type for the raw contact associated with this stream item. Remember to set this value when you insert a stream item. </dd> <dt> - {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME} + android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME </dt> <dd> <strong>Required.</strong> The user's account name for the raw contact associated with this @@ -1866,30 +1866,30 @@ child elements that provide specific data to the insert a stream item: <ul> <li> - {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: The - {@link android.provider.BaseColumns#_ID} value of the contact that this stream + android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID: The + android.provider.BaseColumns#_ID value of the contact that this stream item is associated with. </li> <li> - {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: The - {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} value of the + android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY: The + android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY value of the contact this stream item is associated with. </li> <li> - {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: The - {@link android.provider.BaseColumns#_ID} value of the raw contact that this stream + android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID: The + android.provider.BaseColumns#_ID value of the raw contact that this stream item is associated with. </li> </ul> </dd> <dt> - {@link android.provider.ContactsContract.StreamItemsColumns#COMMENTS} + android.provider.ContactsContract.StreamItemsColumns#COMMENTS </dt> <dd> Optional. Stores summary information that you can display at the beginning of a stream item. </dd> <dt> - {@link android.provider.ContactsContract.StreamItemsColumns#TEXT} + android.provider.ContactsContract.StreamItemsColumns#TEXT </dt> <dd> The text of the stream item, either the content that was posted by the source of the item, @@ -1899,7 +1899,7 @@ child elements that provide specific data to the ellipsize long content, but it will try to avoid breaking tags. </dd> <dt> - {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} + android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP </dt> <dd> A text string containing the time the stream item was inserted or updated, in the form @@ -1910,42 +1910,42 @@ child elements that provide specific data to the </dl> <p> To display identifying information for your stream items, use the - {@link android.provider.ContactsContract.StreamItemsColumns#RES_ICON}, - {@link android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, and - {@link android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} to link to resources + android.provider.ContactsContract.StreamItemsColumns#RES_ICON, + android.provider.ContactsContract.StreamItemsColumns#RES_LABEL, and + android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE to link to resources in your application. </p> <p> - The {@link android.provider.ContactsContract.StreamItems} table also contains the columns - {@link android.provider.ContactsContract.StreamItemsColumns#SYNC1} through - {@link android.provider.ContactsContract.StreamItemsColumns#SYNC4} for the exclusive use of + The android.provider.ContactsContract.StreamItems table also contains the columns + android.provider.ContactsContract.StreamItemsColumns#SYNC1 through + android.provider.ContactsContract.StreamItemsColumns#SYNC4 for the exclusive use of sync adapters. </p> <h3 id="StreamPhotos">Social stream photos</h3> <p> - The {@link android.provider.ContactsContract.StreamItemPhotos} table stores photos associated + The android.provider.ContactsContract.StreamItemPhotos table stores photos associated with a stream item. The table's - {@link android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} column + android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID column links to values in the {@link android.provider.BaseColumns#_ID} column of - {@link android.provider.ContactsContract.StreamItems} table. Photo references are stored in the + android.provider.ContactsContract.StreamItems table. Photo references are stored in the table in these columns: </p> <dl> <dt> - {@link android.provider.ContactsContract.StreamItemPhotos#PHOTO} column (a BLOB). + android.provider.ContactsContract.StreamItemPhotos#PHOTO column (a BLOB). </dt> <dd> A binary representation of the photo, resized by the provider for storage and display. This column is available for backwards compatibility with previous versions of the Contacts Provider that used it for storing photos. However, in the current version you should not use this column to store photos. Instead, use - either {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} or - {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} (both of + either android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID or + android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI (both of which are described in the following points) to store photos in a file. This column now contains a thumbnail of the photo, which is available for reading. </dd> <dt> - {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} + android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID </dt> <dd> A numeric identifier of a photo for a raw contact. Append this value to the constant @@ -1955,7 +1955,7 @@ child elements that provide specific data to the openAssetFileDescriptor()} to get a handle to the photo file. </dd> <dt> - {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} + android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI </dt> <dd> A content URI pointing directly to the photo file for the photo represented by this row. @@ -1970,27 +1970,27 @@ child elements that provide specific data to the <ul> <li> These tables require additional access permissions. To read from them, your application - must have the permission {@link android.Manifest.permission#READ_SOCIAL_STREAM}. To + must have the permission android.Manifest.permission#READ_SOCIAL_STREAM. To modify them, your application must have the permission - {@link android.Manifest.permission#WRITE_SOCIAL_STREAM}. + android.Manifest.permission#WRITE_SOCIAL_STREAM. </li> <li> - For the {@link android.provider.ContactsContract.StreamItems} table, the number of rows + For the android.provider.ContactsContract.StreamItems table, the number of rows stored for each raw contact is limited. Once this limit is reached, the Contacts Provider makes space for new stream item rows by automatically deleting the rows having the oldest - {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}. To get the + android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP. To get the limit, issue a query to the content URI - {@link android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}. You can leave + android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI. You can leave all the arguments other than the content URI set to <code>null</code>. The query returns a Cursor containing a single row, with the single column - {@link android.provider.ContactsContract.StreamItems#MAX_ITEMS}. + android.provider.ContactsContract.StreamItems#MAX_ITEMS. </li> </ul> <p> - The class {@link android.provider.ContactsContract.StreamItems.StreamItemPhotos} defines a - sub-table of {@link android.provider.ContactsContract.StreamItemPhotos} containing the photo + The class android.provider.ContactsContract.StreamItems.StreamItemPhotos defines a + sub-table of android.provider.ContactsContract.StreamItemPhotos containing the photo rows for a single stream item. </p> <h3 id="SocialStreamInteraction">Social stream interactions</h3> @@ -2003,8 +2003,8 @@ child elements that provide specific data to the <li> By syncing your social networking service to the Contacts Provider with a sync adapter, you can retrieve recent activity for a user's contacts and store it in - the {@link android.provider.ContactsContract.StreamItems} and - {@link android.provider.ContactsContract.StreamItemPhotos} tables for later use. + the android.provider.ContactsContract.StreamItems and + android.provider.ContactsContract.StreamItemPhotos tables for later use. </li> <li> Besides regular synchronization, you can trigger your sync adapter to retrieve @@ -2356,6 +2356,6 @@ child elements that provide specific data to the </p> <p> Social stream data for a person may also include photos. These are stored in the - {@link android.provider.ContactsContract.StreamItemPhotos} table, which is described in more + android.provider.ContactsContract.StreamItemPhotos table, which is described in more detail in the section <a href="#StreamPhotos">Social stream photos</a>. </p> diff --git a/docs/html/images/distribute/hero-IO15-google-play.jpg b/docs/html/images/distribute/hero-IO15-google-play.jpg Binary files differnew file mode 100644 index 000000000000..3bfff961824c --- /dev/null +++ b/docs/html/images/distribute/hero-IO15-google-play.jpg diff --git a/docs/html/images/distribute/hero-IO15-growing-games.jpg b/docs/html/images/distribute/hero-IO15-growing-games.jpg Binary files differnew file mode 100644 index 000000000000..c08bd71ce31d --- /dev/null +++ b/docs/html/images/distribute/hero-IO15-growing-games.jpg diff --git a/docs/html/images/distribute/hero-family-discovery.jpg b/docs/html/images/distribute/hero-family-discovery.jpg Binary files differnew file mode 100644 index 000000000000..7ee26b59acf8 --- /dev/null +++ b/docs/html/images/distribute/hero-family-discovery.jpg diff --git a/docs/html/images/distribute/hero-family.jpg b/docs/html/images/distribute/hero-family.jpg Binary files differdeleted file mode 100644 index 6e467a5521ae..000000000000 --- a/docs/html/images/distribute/hero-family.jpg +++ /dev/null diff --git a/docs/html/images/distribute/hero-shifty-jelly.jpg b/docs/html/images/distribute/hero-shifty-jelly.jpg Binary files differnew file mode 100644 index 000000000000..4a2e98675bbf --- /dev/null +++ b/docs/html/images/distribute/hero-shifty-jelly.jpg diff --git a/docs/html/images/distribute/hero-store-listing-experience.jpg b/docs/html/images/distribute/hero-store-listing-experience.jpg Binary files differnew file mode 100644 index 000000000000..5b00b510b3ec --- /dev/null +++ b/docs/html/images/distribute/hero-store-listing-experience.jpg diff --git a/docs/html/images/distribute/hero-the-hunt.jpg b/docs/html/images/distribute/hero-the-hunt.jpg Binary files differnew file mode 100644 index 000000000000..ad6fd0657b8d --- /dev/null +++ b/docs/html/images/distribute/hero-the-hunt.jpg diff --git a/docs/html/images/distribute/hero-trello.jpg b/docs/html/images/distribute/hero-trello.jpg Binary files differnew file mode 100644 index 000000000000..c89b32a5c7d5 --- /dev/null +++ b/docs/html/images/distribute/hero-trello.jpg diff --git a/docs/html/images/distribute/hero-wooga.jpg b/docs/html/images/distribute/hero-wooga.jpg Binary files differnew file mode 100644 index 000000000000..ca796a8d5327 --- /dev/null +++ b/docs/html/images/distribute/hero-wooga.jpg diff --git a/docs/html/index.jd b/docs/html/index.jd index cd129d4979af..794494e279c2 100644 --- a/docs/html/index.jd +++ b/docs/html/index.jd @@ -71,7 +71,7 @@ page.customHeadTag=<meta name="google-site-verification" content="sa-bIAI6GKvct3 data-maxResults="3"></div> </div></section> -<div class="dac-hero-carousel" data-carousel-query="collection:distribute/landing/carousel"> +<div class="dac-hero-carousel" data-carousel-query="collection:index/secondary/carousel"> </div> <section class="dac-section dac-gray"><div class="wrap"> diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index 86089e65ac44..e677f642882e 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -13,6 +13,15 @@ var RESOURCE_COLLECTIONS = { "sdk/index.html" ] }, + "index/secondary/carousel": { + "title": "", + "resources": [ + "http://www.youtube.com/watch?v=0r36OJaeMo4", + "http://www.youtube.com/watch?v=1Iw7Tg_afKk", + "http://www.youtube.com/watch?v=TieksFvD-7o", + "http://www.youtube.com/watch?v=MCoh4Pxs_ok" + ] + }, "index/multiscreen": { "title": "", "resources": [ @@ -175,10 +184,10 @@ var RESOURCE_COLLECTIONS = { "distribute/landing/carousel": { "title": "", "resources": [ - "http://www.youtube.com/watch?v=Pd49vTkvu0U", - "http://www.youtube.com/watch?v=ekxABqJeRBc", - "http://www.youtube.com/watch?v=MPnH7h12h0U", - "http://www.youtube.com/watch?v=700gYRkhkLM" + "https://www.youtube.com/watch?v=QDM52bblwlg", + "https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", ] }, "distribute/landing/googleplay": { diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js index 5b2468d749fa..5dbca75037b3 100644 --- a/docs/html/jd_extras.js +++ b/docs/html/jd_extras.js @@ -2914,7 +2914,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "image":"http://i1.ytimg.com/vi/jQWB_-o1kz4/maxresdefault.jpg", "lang":"en", - "type":"about" + "type":"youtube" }, { "title":"App Configurations, Testing and Launchers", @@ -2926,7 +2926,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "image":"http://i1.ytimg.com/vi/39NkpWkaH8M/maxresdefault.jpg", "lang":"en", - "type":"about" + "type":"youtube" }, { "title":"Building an enterprise ready app", @@ -2938,7 +2938,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "image":"http://i1.ytimg.com/vi/dH41OutAMNM/maxresdefault.jpg", "lang":"en", - "type":"develop" + "type":"youtube" }, { "title":"Android for Work: Single Use Devices", @@ -2950,7 +2950,7 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "image":"http://i1.ytimg.com/vi/j3QC6hcpy90/maxresdefault.jpg", "lang":"en", - "type":"about" + "type":"youtube" }, { "title":"Discover YouTube cards", @@ -3301,6 +3301,41 @@ DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([ "tags": [], "image": "distribute/images/advertising.jpg", "type": "distribute" + }, + { + "url":"https://www.youtube.com/watch?v=QDM52bblwlg", + "image": "images/distribute/hero-family-discovery.jpg", + "title": "Introducing the new family discovery experience on Google Play", + "summary": "Help families create little moments on Google Play. Opt-in your apps now.", + "tags":["families","googleplay"], + "type":"youtube" + }, + { + "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "http://i1.ytimg.com/vi/wcjqBSei3a0/maxresdefault.jpg", + "title": "Developers connecting the world through Google Play", + "summary": "The mobile ecosystem is empowering developers to make good on the dream of connecting the world through technology to improve people's lives.", + "tags":["io15","googleplay"], + "keywords":["Google I/O 2015","io"], + "type":"youtube" + }, + { + "url":"https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "http://i1.ytimg.com/vi/B6ydLpkhq04/maxresdefault.jpg", + "title": "Store Listing Experiments for Google Play", + "summary": "Learn how to use Google Play’s new store listing optimization feature to get more installs of your app, and how to test different graphics and text to find out which options perform the best. ", + "tags":["io15","googleplay","store listing"], + "tags":["google i/o","google play","store listing"], + "type":"youtube" + }, + { + "url":"https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "http://i1.ytimg.com/vi/jyO3-rF4Mu0/maxresdefault.jpg", + "title": "Growing games with Google", + "summary": "The games industry has never been more promising and full of opportunities. This talk covers how Google is helping developers across a broad range of existing and emerging platforms.", + "tags":["io15","android", "googleplay","games"], + "keywords":["Google I/O","google play","games"], + "type":"youtube" } ]); @@ -3310,41 +3345,85 @@ var CAROUSEL_OVERRIDE = { "heroColor": "#263238", "heroInvert": true, "title": "Android 5.0 Lollipop", - "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new Material design interface, and much more." - }, - "distribute/googleplay/families/about.html": { - "image": "images/distribute/hero-family.jpg", - "title": "Designed for Families", - "summary": "Introducing a new Google Play section to promote family friendly apps. Your apps in the program can benefit from enhanced discoverability in addition to maintaining their existing categories, rankings, and reviews elsewhere on the Google Play store." + "summary": "The Android 5.0 update adds a variety of new features for your apps, such as notifications on the lock screen, an all-new camera API, OpenGL ES 3.1, the new naterial design interface, and much more.", }, "http://www.youtube.com/watch?v=Pd49vTkvu0U": { "url":"http://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-jelly-button.jpg", "title": "How Jelly Button Games are growing globally through data", - "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery." + "summary": "To really understand their users, Jelly Button Games analyzes over 3 billion events each month using Google Analytics and Google BigQuery.", }, "http://www.youtube.com/watch?v=700gYRkhkLM": { "url":"http://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-outfit7.jpg", "title": "Outfit7 — Building an entertainment company with Google", - "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories...." + "summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories....", }, "http://www.youtube.com/watch?v=MPnH7h12h0U": { "url":"http://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-haystack.jpg", - "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen." + "summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen.", }, "http://www.youtube.com/watch?v=ekxABqJeRBc": { "url":"http://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", "image": "images/distribute/hero-ginlemon.jpg", "title": "How GinLemon is breaking through with Google Play", - "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy." + "summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy.", }, "distribute/googleplay/guide.html": { "heroColor": "#fcb94e", "image": "images/distribute/hero-g-play-guidebooks_2x.png", - "title": "Finding Success on Google Play", + "title": "Finding success on Google Play", "summary": "We’ve created a downloadable guide to help you find success with your app or game business on Google Play. In it, you’ll find features, tips, and best practices to help you build an effective strategy.", - "tags": [] + }, + "http://www.youtube.com/watch?v=0r36OJaeMo4": { + "url":"http://www.youtube.com/watch?v=0r36OJaeMo4&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-shifty-jelly.jpg", + "title": "Shifty Jelly — building a number 1 podcast app", + "summary": "Shifty Jelly is an Adelaide based mobile development company that has seen great success building Pocket Casts, a premium podcast manager app.", + }, + "http://www.youtube.com/watch?v=1Iw7Tg_afKk": { + "image": "images/distribute/hero-wooga.jpg", + "url":"http://www.youtube.com/watch?v=1Iw7Tg_afKk&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "title": "Wooga’s fast iterations on Google Play", + "summary": "The speed at which Wooga is able to iterate its live and under development games with the Android and Google Play tools has been key to delivering hits such as Diamond Dash, Jelly Splash, and Agent Alice.", + }, + "http://www.youtube.com/watch?v=TieksFvD-7o": { + "url":"http://www.youtube.com/watch?v=TieksFvD-7o&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-trello.jpg", + "title": "Trello lifts engagement by double digits with material design", + "summary": "Trello recently redesigned their collaborative planning app using the material design guidelines, and their efforts paid off.", + }, + "http://www.youtube.com/watch?v=MCoh4Pxs_ok": { + "url":"http://www.youtube.com/watch?v=MCoh4Pxs_ok&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c", + "image": "images/distribute/hero-the-hunt.jpg", + "title": "The Hunt — growing engagement with material design and Google Play", + "summary": "Material design has helped The Hunt to enhance engagement in their style advice and product discovery app. ", + }, + "https://www.youtube.com/watch?v=QDM52bblwlg": { + "url":"distribute/googleplay/families/about.html", + "image": "images/distribute/hero-family-discovery.jpg", + "title": "Designed for families", + "summary": "Introducing the new family discovery experience in Google Play. Your apps can benefit from enhanced discoverability and maintain their existing categories, rankings, and reviews elsewhere in the store. Opt-in your apps today.", + "type":"distribute", + }, + "https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "url":"https://www.youtube.com/watch?v=wcjqBSei3a0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS", + "image": "images/distribute/hero-IO15-google-play.jpg", + "title": "Connecting the world through Google Play", + "tags":["io15"], + "summary": "In this this Google I/O talk, hear how the mobile ecosystem is empowering developers to connect the world through technology and improve people's lives.", + }, + "https://www.youtube.com/watch?v=B6ydLpkhq04&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "image": "images/distribute/hero-store-listing-experience.jpg", + "title": "Using Google Play store listing experiments", + "tags":["io15"], + "summary": "Learn how to use Google Play store listing experiments to get more installs in this Google I/O talk. Test different graphics and text to find out which options perform the best. ", + }, + "https://www.youtube.com/watch?v=jyO3-rF4Mu0&list=PLOU2XLYxmsIKLNUPiFCWVtcO7mZRZ9MmS": { + "image": "images/distribute/hero-IO15-growing-games.jpg", + "title": "Growing games with Google", + "tags":["io15"], + "summary": "The games industry has never been more promising and full of opportunities. This talk from Google I/O 2015 covers how Google is helping developers across a broad range of existing and emerging platforms.", } -}; +};
\ No newline at end of file diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java index dcccf35b88de..2bbbff309414 100644 --- a/graphics/java/android/graphics/PorterDuff.java +++ b/graphics/java/android/graphics/PorterDuff.java @@ -67,4 +67,38 @@ public class PorterDuff { */ public final int nativeInt; } + + /** + * @hide + */ + public static final int modeToInt(Mode mode) { + return mode.nativeInt; + } + + /** + * @hide + */ + public static final Mode intToMode(int val) { + switch (val) { + default: + case 0: return Mode.CLEAR; + case 1: return Mode.SRC; + case 2: return Mode.DST; + case 3: return Mode.SRC_OVER; + case 4: return Mode.DST_OVER; + case 5: return Mode.SRC_IN; + case 6: return Mode.DST_IN; + case 7: return Mode.SRC_OUT; + case 8: return Mode.DST_OUT; + case 9: return Mode.SRC_ATOP; + case 10: return Mode.DST_ATOP; + case 11: return Mode.XOR; + case 16: return Mode.DARKEN; + case 17: return Mode.LIGHTEN; + case 13: return Mode.MULTIPLY; + case 14: return Mode.SCREEN; + case 12: return Mode.ADD; + case 15: return Mode.OVERLAY; + } + } } diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index f059727cb806..fcd7f63afaaf 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -362,11 +362,6 @@ public class BitmapDrawable extends Drawable { invalidateSelf(); } - @Override - public boolean isDither() { - return mBitmapState.mPaint.isDither(); - } - /** * Indicates the repeat behavior of this drawable on the X axis. * diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 5e62aeac6054..32af59a278b5 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -269,30 +269,29 @@ public abstract class Drawable { } /** - * Set to true to have the drawable dither its colors when drawn to a device - * with fewer than 8-bits per color component. This can improve the look on - * those devices, but can also slow down the drawing a little. + * Set to true to have the drawable dither its colors when drawn to a + * device with fewer than 8-bits per color component. + * + * @see android.graphics.Paint#setDither(boolean); + * @deprecated This property is ignored. */ + @Deprecated public void setDither(boolean dither) {} /** - * @return whether this drawable dithers its colors - * @see #setDither(boolean) - */ - public boolean isDither() { - return false; - } - - /** - * Set to true to have the drawable filter its bitmap when scaled or rotated - * (for drawables that use bitmaps). If the drawable does not use bitmaps, - * this call is ignored. This can improve the look when scaled or rotated, - * but also slows down the drawing. + * Set to true to have the drawable filter its bitmaps with bilinear + * sampling when they are scaled or rotated. + * + * <p>This can improve appearance when bitmaps are rotated. If the drawable + * does not use bitmaps, this call is ignored.</p> + * + * @see #isFilterBitmap() + * @see android.graphics.Paint#setFilterBitmap(boolean); */ public void setFilterBitmap(boolean filter) {} /** - * @return whether this drawable filters its bitmap + * @return whether this drawable filters its bitmaps * @see #setFilterBitmap(boolean) */ public boolean isFilterBitmap() { diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 1759f53da604..b344b86ce1b1 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -167,11 +167,6 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public boolean isDither() { - return mDrawableContainerState.mDither; - } - - @Override public void setColorFilter(ColorFilter colorFilter) { mDrawableContainerState.mHasColorFilter = true; diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 626991d19b6b..a11b2cd3f008 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -826,11 +826,6 @@ public class GradientDrawable extends Drawable { } @Override - public boolean isDither() { - return mGradientState.mDither; - } - - @Override public ColorFilter getColorFilter() { return mColorFilter; } diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 85db6a1e006e..7c9b30b078ff 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -16,13 +16,16 @@ package android.graphics.drawable; +import android.annotation.ColorInt; import android.annotation.DrawableRes; +import android.content.res.ColorStateList; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.PorterDuff; import android.net.Uri; import android.os.AsyncTask; import android.os.Handler; @@ -67,6 +70,10 @@ public final class Icon implements Parcelable { private final int mType; + private ColorStateList mTintList; + static final PorterDuff.Mode DEFAULT_TINT_MODE = Drawable.DEFAULT_TINT_MODE; // SRC_IN + private PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; + // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed // based on the value of mType. @@ -109,6 +116,10 @@ public final class Icon implements Parcelable { return (Bitmap) mObj1; } + private void setBitmap(Bitmap b) { + mObj1 = b; + } + /** * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon. * @hide @@ -254,6 +265,19 @@ public final class Icon implements Parcelable { * @return A fresh instance of a drawable for this image, yours to keep. */ public Drawable loadDrawable(Context context) { + final Drawable result = loadDrawableInner(context); + if (result != null && (mTintList != null || mTintMode != DEFAULT_TINT_MODE)) { + result.mutate(); + result.setTintList(mTintList); + result.setTintMode(mTintMode); + } + return result; + } + + /** + * Do the heavy lifting of loading the drawable, but stop short of applying any tint. + */ + private Drawable loadDrawableInner(Context context) { switch (mType) { case TYPE_BITMAP: return new BitmapDrawable(context.getResources(), getBitmap()); @@ -347,6 +371,16 @@ public final class Icon implements Parcelable { } /** + * Puts the memory used by this instance into Ashmem memory, if possible. + * @hide + */ + public void convertToAshmem() { + if (mType == TYPE_BITMAP && getBitmap().isMutable()) { + setBitmap(getBitmap().createAshmemBitmap()); + } + } + + /** * Writes a serialized version of an Icon to the specified stream. * * @param stream The stream on which to serialize the Icon. @@ -466,7 +500,7 @@ public final class Icon implements Parcelable { throw new IllegalArgumentException("Bitmap must not be null."); } final Icon rep = new Icon(TYPE_BITMAP); - rep.mObj1 = bits; + rep.setBitmap(bits); return rep; } @@ -518,6 +552,38 @@ public final class Icon implements Parcelable { } /** + * Store a color to use whenever this Icon is drawn. + * + * @param tint a color, as in {@link Drawable#setTint(int)} + * @return this same object, for use in chained construction + */ + public Icon setTint(@ColorInt int tint) { + return setTintList(ColorStateList.valueOf(tint)); + } + + /** + * Store a color to use whenever this Icon is drawn. + * + * @param tintList as in {@link Drawable#setTintList(ColorStateList)}, null to remove tint + * @return this same object, for use in chained construction + */ + public Icon setTintList(ColorStateList tintList) { + mTintList = tintList; + return this; + } + + /** + * Store a blending mode to use whenever this Icon is drawn. + * + * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null + * @return this same object, for use in chained construction + */ + public Icon setTintMode(PorterDuff.Mode mode) { + mTintMode = mode; + return this; + } + + /** * Create an Icon pointing to an image file specified by path. * * @param path A path to a file that contains compressed bitmap data of @@ -558,6 +624,15 @@ public final class Icon implements Parcelable { sb.append(" uri=").append(getUriString()); break; } + if (mTintList != null) { + sb.append(" tint="); + String sep = ""; + for (int c : mTintList.getColors()) { + sb.append(String.format("%s0x%08x", sep, c)); + sep = "|"; + } + } + if (mTintMode != DEFAULT_TINT_MODE) sb.append(" mode=").append(mTintMode); sb.append(")"); return sb.toString(); } @@ -603,31 +678,39 @@ public final class Icon implements Parcelable { throw new RuntimeException("invalid " + this.getClass().getSimpleName() + " type in parcel: " + mType); } + if (in.readInt() == 1) { + mTintList = ColorStateList.CREATOR.createFromParcel(in); + } + mTintMode = PorterDuff.intToMode(in.readInt()); } @Override public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mType); switch (mType) { case TYPE_BITMAP: final Bitmap bits = getBitmap(); - dest.writeInt(TYPE_BITMAP); getBitmap().writeToParcel(dest, flags); break; case TYPE_RESOURCE: - dest.writeInt(TYPE_RESOURCE); dest.writeString(getResPackage()); dest.writeInt(getResId()); break; case TYPE_DATA: - dest.writeInt(TYPE_DATA); dest.writeInt(getDataLength()); dest.writeBlob(getDataBytes(), getDataOffset(), getDataLength()); break; case TYPE_URI: - dest.writeInt(TYPE_URI); dest.writeString(getUriString()); break; } + if (mTintList == null) { + dest.writeInt(0); + } else { + dest.writeInt(1); + mTintList.writeToParcel(dest, flags); + } + dest.writeInt(PorterDuff.modeToInt(mTintMode)); } public static final Parcelable.Creator<Icon> CREATOR diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index 90891f606f24..8373c7f94e09 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -1248,16 +1248,6 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public boolean isDither() { - final Drawable dr = getFirstNonNullDrawable(); - if (dr != null) { - return dr.isDither(); - } else { - return super.isDither(); - } - } - - @Override public void setAlpha(int alpha) { final ChildDrawable[] array = mLayerState.mChildren; final int N = mLayerState.mNum; diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index adf53e3e6a2f..152fe6a97fdd 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -374,11 +374,6 @@ public class NinePatchDrawable extends Drawable { } @Override - public boolean isDither() { - return mPaint == null ? DEFAULT_DITHER : mPaint.isDither(); - } - - @Override public void setAutoMirrored(boolean mirrored) { mNinePatchState.mAutoMirrored = mirrored; } diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index a669d3c8667a..30b588e1b4b7 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -328,11 +328,6 @@ public class ShapeDrawable extends Drawable { } @Override - public boolean isDither() { - return mShapeState.mPaint.isDither(); - } - - @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); updateShape(); diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java index 250bad797406..515be1d33ba2 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyFactorySpi.java @@ -113,7 +113,7 @@ public class AndroidKeyStoreKeyFactorySpi extends KeyFactorySpi { return result; } else { throw new InvalidKeySpecException( - "Obtaining RSAPublicKeySpec not supported for " + key.getAlgorithm() + " " + "Obtaining ECPublicKeySpec not supported for " + key.getAlgorithm() + " " + ((key instanceof AndroidKeyStorePrivateKey) ? "private" : "public") + " key"); } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java index 688936c79dc5..66509e2bb7df 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -31,7 +31,6 @@ import java.security.ProviderException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; -import java.util.Date; import javax.crypto.KeyGeneratorSpi; import javax.crypto.SecretKey; @@ -278,15 +277,11 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { KeymasterUtils.addUserAuthArgs(args, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); - args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, - (spec.getKeyValidityStart() != null) - ? spec.getKeyValidityStart() : new Date(0)); - args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, - (spec.getKeyValidityForOriginationEnd() != null) - ? spec.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE)); - args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, - (spec.getKeyValidityForConsumptionEnd() != null) - ? spec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE)); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, spec.getKeyValidityStart()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, + spec.getKeyValidityForOriginationEnd()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, + spec.getKeyValidityForConsumptionEnd()); if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!spec.isRandomizedEncryptionRequired())) { diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index 2055cdb144e5..ff265cfe96d2 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -415,15 +415,11 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato KeymasterUtils.addUserAuthArgs(args, mSpec.isUserAuthenticationRequired(), mSpec.getUserAuthenticationValidityDurationSeconds()); - args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, - (mSpec.getKeyValidityStart() != null) - ? mSpec.getKeyValidityStart() : new Date(0)); - args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, - (mSpec.getKeyValidityForOriginationEnd() != null) - ? mSpec.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE)); - args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, - (mSpec.getKeyValidityForConsumptionEnd() != null) - ? mSpec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE)); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, + mSpec.getKeyValidityForOriginationEnd()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, + mSpec.getKeyValidityForConsumptionEnd()); addAlgorithmSpecificParameters(args); byte[] additionalEntropy = @@ -515,15 +511,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato return generateSelfSignedCertificateWithFakeSignature(publicKey); } else { // Key can be used to sign a certificate - return generateSelfSignedCertificateWithValidSignature( - privateKey, publicKey, signatureAlgorithm); + try { + return generateSelfSignedCertificateWithValidSignature( + privateKey, publicKey, signatureAlgorithm); + } catch (Exception e) { + // Failed to generate the self-signed certificate with valid signature. Fall back + // to generating a self-signed certificate with a fake signature. This is done for + // all exception types because we prefer key pair generation to succeed and end up + // producing a self-signed certificate with an invalid signature to key pair + // generation failing. + return generateSelfSignedCertificateWithFakeSignature(publicKey); + } } } @SuppressWarnings("deprecation") private X509Certificate generateSelfSignedCertificateWithValidSignature( - PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm) - throws Exception { + PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm) throws Exception { final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setPublicKey(publicKey); certGen.setSerialNumber(mSpec.getCertificateSerialNumber()); @@ -624,9 +628,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato // Constraints: // 1. Key must be authorized for signing without user authentication. // 2. Signature digest must be one of key's authorized digests. - // 3. For RSA keys, the digest output size must not exceed modulus size minus space needed - // for RSA PKCS#1 signature padding (about 29 bytes: minimum 10 bytes of padding + 15--19 - // bytes overhead for encoding digest OID and digest value in DER). + // 3. For RSA keys, the digest output size must not exceed modulus size minus space overhead + // of RSA PKCS#1 signature padding scheme (about 30 bytes). // 4. For EC keys, the there is no point in using a digest whose output size is longer than // key/field size because the digest will be truncated to that size. @@ -727,10 +730,12 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato spec.getDigests(), AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests()); - // The amount of space available for the digest is less than modulus size because - // padding must be at least 10 bytes long, and then there's also the 15--19 - // bytes overhead for encoding digest OID and digest value in DER. - int maxDigestOutputSizeBits = keySizeBits - 29 * 8; + // The amount of space available for the digest is less than modulus size by about + // 30 bytes because padding must be at least 11 bytes long (00 || 01 || PS || 00, + // where PS must be at least 8 bytes long), and then there's also the 15--19 bytes + // overhead (depending the on chosen digest) for encoding digest OID and digest + // value in DER. + int maxDigestOutputSizeBits = keySizeBits - 30 * 8; int bestKeymasterDigest = -1; int bestDigestOutputSizeBits = -1; for (int keymasterDigest : availableKeymasterDigests) { diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java index 8b00821314a0..7887923d3a18 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java @@ -147,21 +147,10 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi { } Date keyValidityStart = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME); - if ((keyValidityStart != null) && (keyValidityStart.getTime() <= 0)) { - keyValidityStart = null; - } Date keyValidityForOriginationEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME); - if ((keyValidityForOriginationEnd != null) - && (keyValidityForOriginationEnd.getTime() == Long.MAX_VALUE)) { - keyValidityForOriginationEnd = null; - } Date keyValidityForConsumptionEnd = keyCharacteristics.getDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME); - if ((keyValidityForConsumptionEnd != null) - && (keyValidityForConsumptionEnd.getTime() == Long.MAX_VALUE)) { - keyValidityForConsumptionEnd = null; - } boolean userAuthenticationRequired = !keyCharacteristics.getBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED); int userAuthenticationValidityDurationSeconds = diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index 5fb589e80a8c..084e30ea8b54 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -435,17 +435,12 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(importArgs, spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); - importArgs.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, - (spec.getKeyValidityStart() != null) - ? spec.getKeyValidityStart() : new Date(0)); - importArgs.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, - (spec.getKeyValidityForOriginationEnd() != null) - ? spec.getKeyValidityForOriginationEnd() - : new Date(Long.MAX_VALUE)); - importArgs.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, - (spec.getKeyValidityForConsumptionEnd() != null) - ? spec.getKeyValidityForConsumptionEnd() - : new Date(Long.MAX_VALUE)); + importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, + spec.getKeyValidityStart()); + importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, + spec.getKeyValidityForOriginationEnd()); + importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, + spec.getKeyValidityForConsumptionEnd()); } catch (IllegalArgumentException e) { throw new KeyStoreException("Invalid parameter", e); } @@ -646,15 +641,11 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); - args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, - (params.getKeyValidityStart() != null) - ? params.getKeyValidityStart() : new Date(0)); - args.addDate(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, - (params.getKeyValidityForOriginationEnd() != null) - ? params.getKeyValidityForOriginationEnd() : new Date(Long.MAX_VALUE)); - args.addDate(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, - (params.getKeyValidityForConsumptionEnd() != null) - ? params.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE)); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, + params.getKeyValidityForOriginationEnd()); + args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, + params.getKeyValidityForConsumptionEnd()); if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!params.isRandomizedEncryptionRequired())) { diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 1732db9ae335..919dd489085f 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -71,6 +71,8 @@ import javax.security.auth.x500.X500Principal; * <li>{@link KeyProperties#PURPOSE_SIGN},</li> * <li>operation without requiring the user to be authenticated (see * {@link Builder#setUserAuthenticationRequired(boolean)}),</li> + * <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)} + * and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li> * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li> * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li> @@ -634,11 +636,12 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec { /** * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which - * the key can be used when signing/verifying. Attempts to use the key with any other digest - * algorithm will be rejected. + * the key can be used. Attempts to use the key with any other digest algorithm will be + * rejected. * - * <p>This must be specified for keys which are used for signing/verification. For HMAC - * keys, the set of digests defaults to the digest associated with the key algorithm (e.g., + * <p>This must be specified for signing/verification keys and RSA encryption/decryption + * keys used with RSA OAEP padding scheme because these operations involve a digest. For + * HMAC keys, the default is the digest associated with the key algorithm (e.g., * {@code SHA-256} for key algorithm {@code HmacSHA256}). * * <p>For private keys used for TLS/SSL client or server authentication it is usually diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index b7a2a0b25032..5b4b3e73cb01 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -417,12 +417,13 @@ public final class KeyProtection implements ProtectionParameter { /** * Sets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the - * key can be used when signing/verifying or generating MACs. Attempts to use the key with - * any other digest algorithm will be rejected. + * key can be used. Attempts to use the key with any other digest algorithm will be + * rejected. * - * <p>For HMAC keys, the default is the digest algorithm specified in - * {@link Key#getAlgorithm()}. For asymmetric signing keys the set of digest algorithms - * must be specified. + * <p>This must be specified for signing/verification keys and RSA encryption/decryption + * keys used with RSA OAEP padding scheme because these operations involve a digest. For + * HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()} (e.g., + * {@code SHA-256} for key algorithm {@code HmacSHA256}). * * <p>For private keys used for TLS/SSL client or server authentication it is usually * necessary to authorize the use of no digest ({@link KeyProperties#DIGEST_NONE}). This is diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index 1988f5e06a27..b08187be1f82 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -143,6 +143,8 @@ int DisplayListCanvas::saveLayer(float left, float top, float right, float botto } void DisplayListCanvas::translate(float dx, float dy) { + if (dx == 0.0f && dy == 0.0f) return; + mHasDeferredTranslate = true; mTranslateX += dx; mTranslateY += dy; @@ -151,11 +153,15 @@ void DisplayListCanvas::translate(float dx, float dy) { } void DisplayListCanvas::rotate(float degrees) { + if (degrees == 0.0f) return; + addStateOp(new (alloc()) RotateOp(degrees)); mState.rotate(degrees); } void DisplayListCanvas::scale(float sx, float sy) { + if (sx == 1.0f && sy == 1.0f) return; + addStateOp(new (alloc()) ScaleOp(sx, sy)); mState.scale(sx, sy); } diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index d9b40aebe775..00add2903371 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -14,15 +14,13 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" -#define ATRACE_TAG ATRACE_TAG_VIEW - #include "LayerCache.h" #include "LayerRenderer.h" #include "Matrix.h" #include "Properties.h" #include "Rect.h" #include "renderstate/RenderState.h" +#include "utils/GLUtils.h" #include "utils/TraceUtils.h" #include <ui/Rect.h> @@ -238,8 +236,9 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width layer->allocateTexture(); // This should only happen if we run out of memory - if (glGetError() != GL_NO_ERROR) { - ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height); + if (CC_UNLIKELY(GLUtils::dumpGLErrors())) { + LOG_ALWAYS_FATAL("Could not allocate texture for layer (fbo=%d %dx%d)", + fbo, width, height); renderState.bindFramebuffer(previousFbo); layer->decStrong(nullptr); return nullptr; diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index a32306554699..6cf66cd1484d 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -419,12 +419,12 @@ bool SkiaCanvas::quickRejectPath(const SkPath& path) const { bool SkiaCanvas::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) { SkRect rect = SkRect::MakeLTRB(left, top, right, bottom); mCanvas->clipRect(rect, op); - return mCanvas->isClipEmpty(); + return !mCanvas->isClipEmpty(); } bool SkiaCanvas::clipPath(const SkPath* path, SkRegion::Op op) { mCanvas->clipPath(*path, op); - return mCanvas->isClipEmpty(); + return !mCanvas->isClipEmpty(); } bool SkiaCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { @@ -438,7 +438,7 @@ bool SkiaCanvas::clipRegion(const SkRegion* region, SkRegion::Op op) { } else { mCanvas->clipRect(SkRect::MakeEmpty(), op); } - return mCanvas->isClipEmpty(); + return !mCanvas->isClipEmpty(); } // ---------------------------------------------------------------------------- diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp index 9b298ca2011d..55104de5a9d8 100644 --- a/libs/hwui/utils/GLUtils.cpp +++ b/libs/hwui/utils/GLUtils.cpp @@ -14,8 +14,6 @@ * limitations under the License. */ -#define LOG_TAG "OpenGLRenderer" - #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> @@ -26,9 +24,11 @@ namespace android { namespace uirenderer { -void GLUtils::dumpGLErrors() { +bool GLUtils::dumpGLErrors() { + bool errorObserved = false; GLenum status = GL_NO_ERROR; while ((status = glGetError()) != GL_NO_ERROR) { + errorObserved = true; switch (status) { case GL_INVALID_ENUM: ALOGE("GL error: GL_INVALID_ENUM"); @@ -46,6 +46,7 @@ void GLUtils::dumpGLErrors() { ALOGE("GL error: 0x%x", status); } } + return errorObserved; } }; // namespace uirenderer diff --git a/libs/hwui/utils/GLUtils.h b/libs/hwui/utils/GLUtils.h index 890e3740ef9f..702046148ad8 100644 --- a/libs/hwui/utils/GLUtils.h +++ b/libs/hwui/utils/GLUtils.h @@ -20,12 +20,11 @@ namespace android { namespace uirenderer { class GLUtils { -private: public: /** - * Print out any GL errors with ALOGE + * Print out any GL errors with ALOGE, returns true if any errors were found. */ - static void dumpGLErrors(); + static bool dumpGLErrors(); }; // class GLUtils diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index b09f2169e8ad..2c1932439584 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -892,7 +892,6 @@ public class LocationManager { * @param listener listener object that no longer needs location updates * @throws IllegalArgumentException if listener is null */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void removeUpdates(LocationListener listener) { checkListener(listener); String packageName = mContext.getPackageName(); @@ -1055,7 +1054,6 @@ public class LocationManager { * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} * permission is not present */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void removeProximityAlert(PendingIntent intent) { checkPendingIntent(intent); String packageName = mContext.getPackageName(); @@ -1083,7 +1081,6 @@ public class LocationManager { * * @hide */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void removeGeofence(Geofence fence, PendingIntent intent) { checkPendingIntent(intent); checkGeofence(fence); @@ -1107,7 +1104,6 @@ public class LocationManager { * * @hide */ - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) public void removeAllGeofences(PendingIntent intent) { checkPendingIntent(intent); String packageName = mContext.getPackageName(); diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 9609c3551106..d303a2e39882 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -150,6 +150,25 @@ public class CamcorderProfile /** * High speed ( >= 100fps) quality level corresponding to the lowest available resolution. + * <p> + * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to + * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just + * higher output frame rate and bit rate. Therefore, setting these profiles with + * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will + * produce high speed videos rather than slow motion videos that have different capture and + * output (playback) frame rates. To record slow motion videos, the application must set video + * output (playback) frame rate and bit rate appropriately via + * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate} + * based on the slow motion factor. If the application intends to do the video recording with + * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat} + * similarly according to this CamcorderProfile. + * </p> + * + * @see #videoBitRate + * @see #videoFrameRate + * @see MediaRecorder + * @see MediaCodec + * @see MediaFormat */ public static final int QUALITY_HIGH_SPEED_LOW = 2000; @@ -212,11 +231,56 @@ public class CamcorderProfile /** * The target video output bit rate in bits per second + * <p> + * This is the target recorded video output bit rate if the application configures the video + * recording via {@link MediaRecorder#setProfile} without specifying any other + * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from + * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate + * where the video is recorded with. If the application intends to record slow motion videos + * with the high speed quality profiles, it must set a different video bit rate that is + * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate + * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if + * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps + * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to + * record 1/8 factor slow motion recording videos, the application must set 30fps via + * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion + * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in + * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output + * bit rate exceeds the encoder limit. If the application intends to do the video recording with + * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat} + * similarly according to this CamcorderProfile. + * </p> + * + * @see #videoFrameRate + * @see MediaRecorder + * @see MediaCodec + * @see MediaFormat */ public int videoBitRate; /** - * The target video frame rate in frames per second + * The target video frame rate in frames per second. + * <p> + * This is the target recorded video output frame rate per second if the application configures + * the video recording via {@link MediaRecorder#setProfile} without specifying any other + * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from + * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate + * where the video is recorded and played back with. If the application intends to create slow + * motion use case with the high speed quality profiles, it must set a different video frame + * rate that is corresponding to the desired output (playback) frame rate via + * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P} + * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application + * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via + * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos + * with normal speed playback frame rate (240fps for above example). If the application intends + * to do the video recording with {@link MediaCodec} encoder, it must set each individual field + * of {@link MediaFormat} similarly according to this CamcorderProfile. + * </p> + * + * @see #videoBitRate + * @see MediaRecorder + * @see MediaCodec + * @see MediaFormat */ public int videoFrameRate; diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java index da5f33e4352c..7cd086ecf14d 100644 --- a/media/java/android/media/tv/TvContract.java +++ b/media/java/android/media/tv/TvContract.java @@ -710,7 +710,7 @@ public final class TvContract { public static final String COLUMN_LOCKED = "locked"; /** - * The app badge icon of the app link template for this channel. + * The URI for the app badge icon of the app link template for this channel. * * <p>This small icon is overlaid at the bottom of the poster art specified by * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of @@ -736,9 +736,10 @@ public final class TvContract { public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri"; /** - * The poster art used as the background of the app link template for this channel. + * The URI for the poster art used as the background of the app link template for this + * channel. * - * <p>The data in the column must be a URL or a URI in one of the following formats: + * <p>The data in the column must be a URL, or a URI in one of the following formats: * * <ul> * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> @@ -1100,6 +1101,15 @@ public final class TvContract { /** * The URI for the poster art of this TV program. * + * <p>The data in the column must be a URL, or a URI in one of the following formats: + * + * <ul> + * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> + * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) + * </li> + * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> + * </ul> + * * <p>Can be empty. * * <p>Type: TEXT @@ -1109,6 +1119,19 @@ public final class TvContract { /** * The URI for the thumbnail of this TV program. * + * <p>The system can generate a thumbnail from the poster art if this column is not + * specified. Thus it is not necessary for TV input services to include a thumbnail if it is + * just a scaled image of the poster art. + * + * <p>The data in the column must be a URL, or a URI in one of the following formats: + * + * <ul> + * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li> + * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE}) + * </li> + * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li> + * </ul> + * * <p>Can be empty. * * <p>Type: TEXT diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 64333ad6e8f9..003a2741e557 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -272,7 +272,7 @@ public class TvView extends ViewGroup { /** * Tunes to a given channel. * - * @param inputId The ID of TV input which will play the given channel. + * @param inputId The ID of the TV input for the given channel. * @param channelUri The URI of a channel. */ public void tune(@NonNull String inputId, Uri channelUri) { @@ -282,9 +282,9 @@ public class TvView extends ViewGroup { /** * Tunes to a given channel. * - * @param inputId The ID of TV input which will play the given channel. + * @param inputId The ID of TV input for the given channel. * @param channelUri The URI of a channel. - * @param params Extra parameters which might be handled with the tune event. + * @param params Extra parameters. * @hide */ @SystemApi @@ -298,22 +298,26 @@ public class TvView extends ViewGroup { sMainTvView = new WeakReference<>(this); } } - if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) { + if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) { if (mSession != null) { mSession.tune(channelUri, params); } else { - // Session is not created yet. Replace the channel which will be set once the - // session is made. + // createSession() was called but the actual session for the given inputId has not + // yet been created. Just replace the existing tuning params in the callback with + // the new ones and tune later in onSessionCreated(). It is not necessary to create + // a new callback because this tuning request was made on the same inputId. mSessionCallback.mChannelUri = channelUri; mSessionCallback.mTuneParams = params; } } else { resetInternal(); - // When createSession() is called multiple times before the callback is called, - // only the callback of the last createSession() call will be actually called back. - // The previous callbacks will be ignored. For the logic, mSessionCallback - // is newly assigned for every createSession request and compared with - // MySessionCreateCallback.this. + // In case createSession() is called multiple times across different inputId's before + // any session is created (e.g. when quickly tuning to a channel from input A and then + // to another channel from input B), only the callback for the last createSession() + // should be invoked. (The previous callbacks are simply ignored.) To do that, we create + // a new callback each time and keep mSessionCallback pointing to the last one. If + // MySessionCallback.this is different from mSessionCallback, we know that this callback + // is obsolete and should ignore it. mSessionCallback = new MySessionCallback(inputId, channelUri, params); if (mTvInputManager != null) { mTvInputManager.createSession(inputId, mSessionCallback, mHandler); @@ -337,6 +341,7 @@ public class TvView extends ViewGroup { } private void resetInternal() { + mSessionCallback = null; mPendingAppPrivateCommands.clear(); if (mSession != null) { setSessionSurface(null); @@ -344,7 +349,6 @@ public class TvView extends ViewGroup { mUseRequestedSurfaceLayout = false; mSession.release(); mSession = null; - mSessionCallback = null; resetSurfaceView(); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index fe148daf8f74..c541bca9c398 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -186,6 +186,9 @@ public class DocumentsActivity extends BaseActivity { } if (!mState.restored) { + // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent + // talkback from reading aloud the default title, we clear it here. + setTitle(""); if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) { final Uri rootUri = getIntent().getData(); new RestoreRootTask(rootUri).executeOnExecutor(getCurrentExecutor()); diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index f4e4ea16c7ff..ef08e1900ee7 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -346,7 +346,7 @@ public class WifiTracker { accessPoint.update(mLastInfo, mLastNetworkInfo); } - if (result.passpointNetwork) { + if (result.isPasspointNetwork()) { WifiConfiguration config = mWifiManager.getMatchingWifiConfig(result); if (config != null) { accessPoint.update(config); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index aff6ad89e600..44b9d8b7b55e 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -904,16 +904,16 @@ public class SettingsProvider extends ContentProvider { private boolean mutateSystemSetting(String name, String value, int runAsUserId, int operation) { - // Make sure the caller can change the settings. - enforceWritePermission(Manifest.permission.WRITE_SETTINGS); + // Check for permissions first. + hasPermissionsToMutateSystemSettings(); // Verify whether this operation is allowed for the calling package. if (!isAppOpWriteSettingsAllowedForCallingPackage()) { return false; } - // Enforce what the calling package can mutate in the system settings. - enforceRestrictedSystemSettingsMutationForCallingPackageLocked(operation, name); + // Enforce what the calling package can mutate the system settings. + enforceRestrictedSystemSettingsMutationForCallingPackage(operation, name); // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(runAsUserId); @@ -954,6 +954,28 @@ public class SettingsProvider extends ContentProvider { } } + private boolean hasPermissionsToMutateSystemSettings() { + // Write secure settings is a more protected permission. If caller has it we are good. + if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + + // The write settings permission gates mutation of system settings. + if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SETTINGS) + == PackageManager.PERMISSION_GRANTED) { + return true; + } + + // Excpet we let system apps change system settings without the permission. + PackageInfo packageInfo = getCallingPackageInfoOrThrow(); + if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { + return true; + } + + return false; + } + private void validateSystemSettingValue(String name, String value) { Settings.System.Validator validator = Settings.System.VALIDATORS.get(name); if (validator != null && !validator.validate(value)) { @@ -1000,7 +1022,7 @@ public class SettingsProvider extends ContentProvider { return userId; } - private void enforceRestrictedSystemSettingsMutationForCallingPackageLocked(int operation, + private void enforceRestrictedSystemSettingsMutationForCallingPackage(int operation, String name) { // System/root/shell can mutate whatever secure settings they want. final int callingUid = Binder.getCallingUid(); diff --git a/packages/Shell/src/com/android/shell/BugreportReceiver.java b/packages/Shell/src/com/android/shell/BugreportReceiver.java index 0c84fa148e7f..6278650775f5 100644 --- a/packages/Shell/src/com/android/shell/BugreportReceiver.java +++ b/packages/Shell/src/com/android/shell/BugreportReceiver.java @@ -214,7 +214,7 @@ public class BugreportReceiver extends BroadcastReceiver { try (InputStream is = new FileInputStream(bugreportFile); ZipOutputStream zos = new ZipOutputStream( new BufferedOutputStream(new FileOutputStream(bugreportZippedFile)))) { - ZipEntry entry = new ZipEntry("bugreport.txt"); + ZipEntry entry = new ZipEntry(bugreportFile.getName()); zos.putNextEntry(entry); int totalBytes = Streams.copy(is, zos); Log.v(TAG, "size of original bugreport: " + totalBytes + " bytes"); diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 444f438fea4f..0eb463fc3413 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Foon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Stembystand"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Ontsluit"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Ontsluit-knoppie, wag tans vir vingerafdruk"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontsluit sonder om jou vingerafdruk te gebruik"</string> <string name="unlock_label" msgid="8779712358041029439">"ontsluit"</string> <string name="phone_label" msgid="2320074140205331708">"maak foon oop"</string> <string name="voice_assist_label" msgid="3956854378310019854">"maak stembystand oop"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Jy sal nie deur klanke en vibrasies gesteur word nie, afgesien van wekkers, onthounotas, gebeurtenisse en bellers wat jy spesifiseer."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Pasmaak"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af. Jy sal steeds foonoproepe kan maak."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Dit blokkeer ALLE klanke en vibrasies, insluitend van wekkers, musiek, video\'s en speletjies af."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Raak weer om oop te maak"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 9a68f1ef0ff9..d909c44be8e2 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ስልክ"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"የድምጽ እርዳታ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ክፈት"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"የማስከፈቻ አዝራር፣ የጣት አሻራን በመጠበቅ ላይ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"የጣት አሻራዎን ሳይጠቀሙ ይክፈቱ"</string> <string name="unlock_label" msgid="8779712358041029439">"ክፈት"</string> <string name="phone_label" msgid="2320074140205331708">"ስልክ ክፈት"</string> <string name="voice_assist_label" msgid="3956854378310019854">"የድምጽ ረዳትን ክፈት"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"እርስዎ ከገለጿቸው ማንቂያዎች፣ አስታዋሾች፣ ክስተቶች እና ደዋዮች በስተቀር በድምጾች እና ንዝረቶች አይረበሹም።"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"አብጅ"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል። አሁንም የድምጽ ጥሪዎችን ማድረግ ይችላሉ።"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ይሄ ማንቂያዎችን፣ ሙዚቃን፣ ቪዲዮዎችን እና ጨዋታዎችንም ጨምሮ ሁሉንም ድምጾች እና ንዝረቶች ያጠፋል።"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ለመክፈት ዳግም ይንኩ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index e0fb2f00697a..6de6f4f2cb45 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -91,10 +91,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"الهاتف"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"المساعد الصوتي"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"إلغاء القفل"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"زر إلغاء القفل، في انتظار بصمة إصبع"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"إلغاء القفل دون استخدام بصمة إصبعك"</string> <string name="unlock_label" msgid="8779712358041029439">"إلغاء القفل"</string> <string name="phone_label" msgid="2320074140205331708">"فتح الهاتف"</string> <string name="voice_assist_label" msgid="3956854378310019854">"فتح المساعد الصوتي"</string> @@ -320,10 +318,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"لن يتم إزعاجك بأصوات أو اهتزاز، عدا من التنبيهات والتذكيرات والأحداث والمتصلين الذين تحددهم."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"تخصيص"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب. إلا أنه سيظل بإمكانك إجراء مكالمات هاتفية."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"سيؤدي هذا إلى حظر جميع الأصوات والاهتزازات، بما في ذلك ما يرد من التنبيهات والموسيقى والفيديو والألعاب."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"الإشعارات الأقل إلحاحًا أدناه"</string> <string name="notification_tap_again" msgid="8524949573675922138">"المس مرة أخرى للفتح"</string> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 6f0eb1f933ee..81ac0ea904ae 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Səs Yardımçısı"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Kiliddən çıxarın"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kilid açma düyməsi, barmaq izi üçün gözləyir"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Barmaq izi istifadə etmədən kilidi açın"</string> <string name="unlock_label" msgid="8779712358041029439">"kiliddən çıxarın"</string> <string name="phone_label" msgid="2320074140205331708">"telefonu açın"</string> <string name="voice_assist_label" msgid="3956854378310019854">"səs yardımçısını açın"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> üçün sola sürüşdür."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Zəng, xatırlatma, hadisə və seçdiyiniz zəng edənlər istisna olmaqla səs və vibrasiya Sizi narahat etməyəcək."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Fərdiləşdirin"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır. Yenə də telefon zəngi edə bilərsiniz."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu, zəng, musiqi, video və oyunlar daxil olmaqla BÜTÜN səs və vibrasiyanı bloklayır."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az təcili bildirişlər aşağıdadır"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index e542b20f5330..49982f5ed6da 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласова помощ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Отключване"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Бутон за отключване – изчаква се отпечатък"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Отключете, без да използвате отпечатъка си"</string> <string name="unlock_label" msgid="8779712358041029439">"отключване"</string> <string name="phone_label" msgid="2320074140205331708">"отваряне на телефона"</string> <string name="voice_assist_label" msgid="3956854378310019854">"отваряне на гласовата помощ"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Няма да бъдете обезпокоявани от звуци и вибрирания, различни от будилници, напомняния, събития и обаждания от посочени от вас контакти."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Персонализиране"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри. Пак ще можете да извършвате телефонни обаждания."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Този режим блокира ВСИЧКИ звуци и вибрирания, включително от будилници, музика, видеоклипове и игри."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Докоснете отново за отваряне"</string> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index bb3375bee3c5..af5bd9b7a886 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ফোন"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ভয়েস সহায়তা"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"আনলক করুন"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"আনলক বোতাম, আঙ্গুলের ছাপের জন্য প্রতীক্ষারত"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"আপনার আঙ্গুলের ছাপ ব্যবহার না করেই আনলক করুন"</string> <string name="unlock_label" msgid="8779712358041029439">"আনলক করুন"</string> <string name="phone_label" msgid="2320074140205331708">"ফোন খুলুন"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ভয়েস সহায়তা খুলুন"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> এর জন্য বাম দিকে স্লাইড করুন৷"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"আপনার নির্দিষ্ট অ্যালার্ম, অনুস্মারক, ইভেন্ট, এবং কলারগুলি ব্যতীত আপনাকে শব্দ এবং কম্পনগুলির দ্বারা বিরক্ত করা হবে না৷"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"কাস্টমাইজ করুন"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷ আপনি এখনও ফোন কলগুলি করতে পারবেন৷"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"এটি অ্যালার্ম, সংগীত, ভিডিও এবং গেমগুলি থেকে আসা সমস্ত রকমের ধ্বনি এবং কম্পনগুলিকে বন্ধ করে৷"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string> <string name="notification_tap_again" msgid="8524949573675922138">"খোলার জন্য আবার স্পর্শ করুন"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 33efaebce381..4d6ee7946b4c 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telèfon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistència per veu"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloqueja"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botó de desbloqueig, esperant l\'empremta digital"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloqueja sense utilitzar l\'empremta digital"</string> <string name="unlock_label" msgid="8779712358041029439">"desbloqueja"</string> <string name="phone_label" msgid="2320074140205331708">"obre el telèfon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"obre l\'assistència per veu"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Llisca cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"No t\'interromprà cap so ni cap vibració, tret dels que produeixin les alarmes, els recordatoris, els esdeveniments i les trucades de les persones que especifiquis."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalitza"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els vídeos, els jocs, les alarmes i la música. Tot i això, encara podràs fer trucades."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Es bloquejaran TOTS els sons i totes les vibracions, inclosos els vídeos, els jocs, les alarmes i la música."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Torna a tocar per obrir"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index c7f19a3133ea..ccb7ea17e597 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasová asistence"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Odemknout"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tlačítko odemčení, čekání na otisk prstu"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odemknout bez otisku prstu"</string> <string name="unlock_label" msgid="8779712358041029439">"odemknout"</string> <string name="phone_label" msgid="2320074140205331708">"otevřít telefon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"otevřít hlasovou asistenci"</string> @@ -320,10 +318,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudou vás rušit zvuky ani vibrace s výjimkou budíků, upozornění, událostí a volajících, které zadáte."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Přizpůsobit"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her. Telefonovat budete moci i nadále."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"V tomto režimu budou blokovány VŠECHNY zvuky a vibrace, včetně těch z budíků, hudby, videí a her."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Otevřete opětovným klepnutím"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 88b85267c292..895da77d5a45 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Lås op"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knap til oplåsning. Venter på fingeraftryk"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås op uden at bruge dit fingeraftryk"</string> <string name="unlock_label" msgid="8779712358041029439">"lås op"</string> <string name="phone_label" msgid="2320074140205331708">"åbn telefon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"åbn voice assist"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Du bliver ikke forstyrret af lyde og vibrationer undtagen fra de alarmer, påmindelser, begivenheder og opkaldere, som du angiver."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpas"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil. Du vil stadig kunne foretage telefonopkald."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokerer ALLE lyde og vibrationer, bl.a. fra alarmer, musik, videoer og spil."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende underretninger nedenfor"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Tryk igen for at åbne"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index a87eec058963..1d0ea0ad04f8 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sprachassistent"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Entsperren"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Schaltfläche \"Entsperren\", auf Fingerabdruck warten"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ohne Verwendung des Fingerabdrucks entsperren"</string> <string name="unlock_label" msgid="8779712358041029439">"Entsperren"</string> <string name="phone_label" msgid="2320074140205331708">"Telefon öffnen"</string> <string name="voice_assist_label" msgid="3956854378310019854">"Sprachassistent öffnen"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Klingeltöne und die Vibration werden deaktiviert, außer für Weckrufe, Erinnerungen, Termine sowie Anrufe von zuvor von Ihnen festgelegten Personen."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassen"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele. Anrufe können Sie jedoch weiterhin tätigen."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Hierdurch werden alle Klingeltöne und Vibrationsalarme stummgeschaltet, auch für Weckrufe, Musik, Videos und Spiele."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Zum Öffnen erneut berühren"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index cacf3b83fd2b..eab45d9f72ac 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Τηλέφωνο"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Φωνητική υποβοήθηση"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Ξεκλείδωμα"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Κουμπί ξεκλειδώματος, αναμονή για μοναδικό χαρακτηριστικό"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ξεκλείδωμα χωρίς τη χρήση του μοναδικού χαρακτηριστικού σας"</string> <string name="unlock_label" msgid="8779712358041029439">"ξεκλείδωμα"</string> <string name="phone_label" msgid="2320074140205331708">"άνοιγμα τηλεφώνου"</string> <string name="voice_assist_label" msgid="3956854378310019854">"άνοιγμα φωνητικής υποβοήθησης"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Δεν θα διακόπτεστε από ήχους και δονήσεις, με εξαίρεση τα ξυπνητήρια, τις υπενθυμίσεις, τα συμβάντα και τους καλούντες που έχετε ορίσει."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Προσαρμογή"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Αυτή η επιλογή αποκλείει ΟΛΟΥΣ τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών. Θα εξακολουθείτε να είστε σε θέση να πραγματοποιήσετε τηλεφωνικές κλήσεις."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Αυτή η επιλογή αποκλείει ΟΛΟΥΣ τους ήχους και τις δονήσεις, μεταξύ των οποίων των ξυπνητηριών, της μουσικής, των βίντεο και των παιχνιδιών."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Αγγίξτε ξανά για άνοιγμα"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 07ac57af0d0a..88b5be02914d 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string> <string name="unlock_label" msgid="8779712358041029439">"unlock"</string> <string name="phone_label" msgid="2320074140205331708">"open phone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 07ac57af0d0a..88b5be02914d 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string> <string name="unlock_label" msgid="8779712358041029439">"unlock"</string> <string name="phone_label" msgid="2320074140205331708">"open phone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 07ac57af0d0a..88b5be02914d 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Phone"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Unlock"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Unlock button, waiting for fingerprint"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Unlock without using your fingerprint"</string> <string name="unlock_label" msgid="8779712358041029439">"unlock"</string> <string name="phone_label" msgid="2320074140205331708">"open phone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"open voice assist"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"You won’t be disturbed by sounds and vibrations, except from alarms, reminders, events and callers that you specify."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Customise"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games. You’ll still be able to make phone calls."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"This blocks ALL sounds and vibrations, including from alarms, music, videos and games."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Less urgent notifications below"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Touch again to open"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 7ccb0ae049d2..42801914f387 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón Desbloquear, esperando la huella digital"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sin utilizar la huella digital"</string> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"No te molestarán los sonidos ni las vibraciones, excepto que se trate de alarmas, recordatorios, eventos y emisores que especifiques."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluidas las que provienen de alarmas, videos y juegos. Podrás realizar llamadas telefónicas."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS los sonidos y las vibraciones, incluso los que provienen de alarmas, música, videos y juegos."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir."</string> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index 6da66934a5b3..0c35122ae0a5 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Häälabi"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Luku avamine"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Avamisnupp, sõrmejälje ootel"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ava sõrmejälge kasutamata"</string> <string name="unlock_label" msgid="8779712358041029439">"ava lukk"</string> <string name="phone_label" msgid="2320074140205331708">"ava telefon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ava häälabi"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Teid segatakse helide ja värinaga vaid teie määratud alarmide, meeldetuletuste, sündmuste ning helistajate puhul."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Kohanda"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja värinad. Saate siiski helistada."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"See blokeerib KÕIK – sealhulgas alarmide, muusika, videote ja mängude – helid ja vibratsioonid."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Avamiseks puudutage uuesti"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index ef8f6e2febc3..a9edeac865d9 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonoa"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ahots-laguntza"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desblokeatu"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Desblokeatze-botoia; hatz-markaren zain"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desblokeatu hatz-markaren bidez"</string> <string name="unlock_label" msgid="8779712358041029439">"desblokeatu"</string> <string name="phone_label" msgid="2320074140205331708">"ireki telefonoan"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ireki ahots-laguntza"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Lerratu ezkerrera hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Soinuek eta dardarek ez zaituzte eragotziko, zehazten dituzun alarmek, abisuek, gertaerek eta deitzaileek izan ezik."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Pertsonalizatu"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak. Telefono-deiak egiteko aukera izaten jarraituko duzu."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Irekitzeko, ukitu berriro"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index ce005e310f6a..65d3866f9edf 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"تلفن"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"دستیار صوتی"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"باز کردن قفل"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"دکمه باز کردن قفل، در انتظار اثر انگشت"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"باز کردن قفل بدون استفاده از اثر انگشت"</string> <string name="unlock_label" msgid="8779712358041029439">"بازکردن قفل"</string> <string name="phone_label" msgid="2320074140205331708">"باز کردن تلفن"</string> <string name="voice_assist_label" msgid="3956854378310019854">"«دستیار صوتی» را باز کنید"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"صداها و لرزشهایی به جز هشدارها، یادآوریها، رویدادها و تماسگیرندههایی که مشخص میکنید، مزاحم شما نمیشوند."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"سفارشی کردن"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند. همچنان میتوانید تماس تلفنی برقرار کنید."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string> <string name="notification_tap_again" msgid="8524949573675922138">"برای باز کردن دوباره لمس کنید"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 633484c8f711..2f4f5a16f17b 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Puhelin"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ääniapuri"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Avaa lukitus"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Avauspainike, odotetaan sormenjälkeä."</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Avaa lukitus jollakin muulla tavalla kuin sormenjäljellä"</string> <string name="unlock_label" msgid="8779712358041029439">"avaa lukitus"</string> <string name="phone_label" msgid="2320074140205331708">"avaa puhelin"</string> <string name="voice_assist_label" msgid="3956854378310019854">"Avaa ääniapuri"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Äänet ja värinät eivät häiritse sinua, paitsi jos ne ovat hälytyksiä, muistutuksia, tapahtumia tai määrittämiäsi soittajia."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Muokkaa"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät. Voit kuitenkin soittaa puheluita."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Tämä estää KAIKKI äänet ja värinät, mukaan lukien hälytysten, musiikin, videoiden ja pelien äänet ja värinät."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Avaa koskettamalla uudelleen"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index aa2f7d9caab8..a225864b1f83 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphone"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Bouton de déverrouillage. En attente d\'une empreinte digitale…"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string> <string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string> <string name="phone_label" msgid="2320074140205331708">"Ouvrir le téléphone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous spécifiez."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez quand même faire des appels téléphoniques."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Touchez à nouveau pour ouvrir"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 0e0f1bbb7d49..286aa32e6e02 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphoner"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Bouton de déverrouillage. En attente d\'une empreinte digitale…"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Déverrouiller le système sans utiliser votre empreinte digitale"</string> <string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string> <string name="phone_label" msgid="2320074140205331708">"ouvrir le téléphone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Vous ne serez pas dérangé par les sonneries ni les vibrations, sauf pour les alarmes, les rappels, les événements et les appels des personnes que vous spécifiez."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personnaliser"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux. Vous pourrez toujours passer des appels téléphoniques."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Cette option permet de bloquer TOUS les sons et les vibrations, y compris pour les alarmes, la musique, les vidéos et les jeux."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Appuyer à nouveau pour ouvrir"</string> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 5c039cbbc999..0e3d08d69800 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente de voz"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botón de desbloqueo, agardando pola impresión dixital"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquea sen usar a túa impresión dixital"</string> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir asistente de voz"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Pasa o dedo cara a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Non te molestará ningún son nin vibración, agás os procedentes de alarmas, recordatorios, eventos de emisores de chamada especificados."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos. Aínda podes facer chamadas de teléfono."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta acción bloquea TODOS os sons e vibracións, incluídos os das alarmas, música, vídeos e xogos."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacións menos urxentes abaixo"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Toca outra vez para abrir o elemento"</string> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index c6193d82d0e1..f64a4546f333 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ફોન"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"વૉઇસ સહાય"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"અનલૉક કરો"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"અનલૉક બટન, ફિંગરપ્રિન્ટ માટે રાહ જોઈ રહ્યાં છીએ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કર્યા વગર અનલૉક કરો"</string> <string name="unlock_label" msgid="8779712358041029439">"અનલૉક કરો"</string> <string name="phone_label" msgid="2320074140205331708">"ફોન ખોલો"</string> <string name="voice_assist_label" msgid="3956854378310019854">"વૉઇસ સહાય ખોલો"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ડાબે સ્લાઇડ કરો."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"તમને તમે ઉલ્લેખિત એલાર્મ્સ, સ્મૃતિપત્રો, ઇવેન્ટ્સ અને કૉલર્સ સિવાયના ધ્વનિઓ અને વાઇબ્રેશન્સથી ખલેલ પહોંચાડવામાં આવશે નહીં."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"કસ્ટમાઇઝ કરો"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે. તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત તમામ ધ્વનિઓ અને વાઇબ્રેશન્સને આ અવરોધિત કરે છે."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ખોલવા માટે ફરી ટચ કરો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index cd2e8865c5a6..ff441ab7c312 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"फ़ोन"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"वॉइस सहायक"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करें"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलॉक बटन, फ़िंगरप्रिंट की प्रतीक्षा कर रहा है"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"अपने फ़िंगरप्रिंट का उपयोग किए बिना अनलॉक करें"</string> <string name="unlock_label" msgid="8779712358041029439">"अनलॉक करें"</string> <string name="phone_label" msgid="2320074140205331708">"फ़ोन खोलें"</string> <string name="voice_assist_label" msgid="3956854378310019854">"वॉइस सहायक खोलें"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्लाइड करें."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"आपको आपके द्वारा निर्दिष्ट किए गए अलार्म, रिमाइंडर्स, ईवेंट और कॉलर को छोड़कर अन्य ध्वनियों और कंपनों के द्वारा परेशान नहीं किया जाएगा."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"कस्टमाइज़ करें"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं. आप अभी भी फ़ोन काॅल कर सकेंगे."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"इससे अलार्म, संगीत, वीडियो और गेम सहित सभी ध्वनियां और कंपन अवरुद्ध हो जाते हैं."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string> <string name="notification_tap_again" msgid="8524949573675922138">"खोलने के लिए पुन: स्पर्श करें"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 52c01fa1ec55..59969799f147 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -88,10 +88,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Otključavanje"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Gumb za otključavanje, čekanje na otisak prsta"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Otključavanje bez otiska prsta"</string> <string name="unlock_label" msgid="8779712358041029439">"otključavanje"</string> <string name="phone_label" msgid="2320074140205331708">"otvaranje telefona"</string> <string name="voice_assist_label" msgid="3956854378310019854">"otvaranje glasovne pomoći"</string> @@ -317,10 +315,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Neće vas prekidati zvukovi i vibracije, osim alarma, podsjetnika, događaja i pozivatelja koje navedete."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre. I dalje ćete moći telefonirati."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"To blokira SVE zvukove i vibracije, uključujući alarme, glazbu, videozapise i igre."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Dodirnite ponovo da biste otvorili"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index b8db72ae7a9b..6cc4c5150b42 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hangsegéd"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Feloldás"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Feloldás gomb, várakozás az ujjlenyomatra"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Feloldás ujjlenyomat nélkül"</string> <string name="unlock_label" msgid="8779712358041029439">"feloldás"</string> <string name="phone_label" msgid="2320074140205331708">"telefon megnyitása"</string> <string name="voice_assist_label" msgid="3956854378310019854">"hangsegéd megnyitása"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Nem zavarják majd hanghatások, sem rezgés, kivéve az ébresztéseket, emlékeztetőket, eseményeket és az Ön által megjelölt hívókat."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Személyre szabás"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is. Telefonhívást továbbra is indíthat majd."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Ez letiltja az ÖSSZES hanghatást és rezgést, beleértve az ébresztések, zeneszámok, videók és játékok hangjait is."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Érintse meg ismét a megnyitáshoz"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 1a771a33a22c..ebd7a438436f 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telepon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Bantuan Suara"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Buka kunci"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tombol buka kunci, menunggu sidik jari"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Buka kunci tanpa menggunakan sidik jari"</string> <string name="unlock_label" msgid="8779712358041029439">"buka kunci"</string> <string name="phone_label" msgid="2320074140205331708">"buka ponsel"</string> <string name="voice_assist_label" msgid="3956854378310019854">"buka bantuan suara"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Anda tidak akan diganggu oleh suara dan getaran, kecuali dari alarm, pengingat, acara, dan penelepon tertentu."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Sesuaikan"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir. Anda tetap dapat melakukan panggilan telepon."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"SEMUA suara dan getaran, termasuk dari alarm, musik, video, dan game akan diblokir."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifikasi kurang darurat di bawah"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Sentuh lagi untuk membuka"</string> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 03ed3e87f348..ef401037c3bc 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Sími"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Raddaðstoð"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Taka úr lás"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Hnappur til að taka úr lás, beðið eftir fingrafari"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Taka úr lás án þess að nota fingrafar"</string> <string name="unlock_label" msgid="8779712358041029439">"taka úr lás"</string> <string name="phone_label" msgid="2320074140205331708">"opna síma"</string> <string name="voice_assist_label" msgid="3956854378310019854">"opna raddaðstoð"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Strjúktu til vinstri til að <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Þú verður ekki fyrir truflunum af hljóðmerkjum og titringi, fyrir utan vekjara, áminningar, viðburði og símtöl sem þú leyfir fyrir fram."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Sérsníða"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum. Þú getur áfram hringt símtöl."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Þetta lokar á ÖLL hljóðmerki og titring, þ.m.t. frá vekjurum, tónlist, myndskeiðum og leikjum."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Minna áríðandi tilkynningar fyrir neðan"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Snertu aftur til að opna"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index d9fdd465f90a..88b2cdb0bb99 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefono"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Sblocca"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Pulsante Sblocca, in attesa dell\'impronta digitale"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Sblocca senza utilizzare l\'impronta digitale"</string> <string name="unlock_label" msgid="8779712358041029439">"sblocca"</string> <string name="phone_label" msgid="2320074140205331708">"apri telefono"</string> <string name="voice_assist_label" msgid="3956854378310019854">"apri Voice Assist"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Non verrai disturbato da suoni e vibrazioni, ad eccezione di sveglie, promemoria, eventi e chiamate da contatti da te specificati."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizza"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi. Potrai ancora telefonare."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Verranno bloccati TUTTI i suoni e le vibrazioni, anche di sveglie, musica, video e giochi."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Tocca di nuovo per aprire"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 92188d3b8cf3..52da80030681 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"טלפון"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"מסייע קולי"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ביטול נעילה"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"לחצן ביטול נעילה, ממתין לטביעת אצבע"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"בטל את הנעילה בלי להשתמש בטביעת האצבע"</string> <string name="unlock_label" msgid="8779712358041029439">"בטל את הנעילה"</string> <string name="phone_label" msgid="2320074140205331708">"פתח את הטלפון"</string> <string name="voice_assist_label" msgid="3956854378310019854">"פתח את המסייע הקולי"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"צלילים ורטט לא יופעלו, פרט להתראות, תזכורות, אירועים ומתקשרים שתציין."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"התאם אישית"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"פעולה זו מבטלת את כל הצלילים והרטט, כולל צלילים ורטט שמקורם בהתראות, מוזיקה, סרטונים ומשחקים. תוכל עדיין להתקשר."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"פעולה זו מבטלת את כל הצלילים והרטט, כולל בהתראות, מוזיקה, סרטונים ומשחקים."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"הודעות בדחיפות נמוכה יותר בהמשך"</string> <string name="notification_tap_again" msgid="8524949573675922138">"גע שוב כדי לפתוח"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 5ea8ef91088a..01031d437b82 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"音声アシスト"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ロック解除"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ロック解除ボタン、指紋を待っています"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"指紋を使用せずにロック解除"</string> <string name="unlock_label" msgid="8779712358041029439">"ロック解除"</string> <string name="phone_label" msgid="2320074140205331708">"電話を起動"</string> <string name="voice_assist_label" msgid="3956854378310019854">"音声アシストを開く"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"アラーム、リマインダー、予定、指定した人からの着信以外で音やバイブレーションに煩わされることはありません。"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"カスタマイズ"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。電話をかけることはできます。"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"アラーム、音楽、動画、ゲームを含むすべての音とバイブレーションがブロックされます。"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string> <string name="notification_tap_again" msgid="8524949573675922138">"開くにはもう一度タップしてください"</string> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index 6d22c3ddd099..0255fb984ccd 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дауыс көмекшісі"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Бекітпесін ашу"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Құлыпты ашу түймесі, саусақ ізі күтілуде"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Саусақ ізін пайдаланбай құлыпты ашу"</string> <string name="unlock_label" msgid="8779712358041029439">"бекітпесін ашу"</string> <string name="phone_label" msgid="2320074140205331708">"телефонды ашу"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ашық дауыс көмекшісі"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> үшін солға сырғыту."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Дабылдар, еске салғыштар, оқиғалар мен өзіңіз көрсеткен контактілердің қоңырауларынан басқа дыбыстар мен дірілдер мазаламайтын болады."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Реттеу"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Бұл БАРЛЫҚ дыбыстарды және дірілдерді бұғаттайды, соның ішінде, дабылдардыкін, музыканыкін, бейнелердікін және ойындардыкін. Сіз әлі де телефон қоңырауларын шала аласыз."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Бұл БАРЛЫҚ дыбыстарды және дірілдерді бұғаттайды, соның ішінде, дабылдардыкін, музыканыкін, бейнелердікін және ойындардыкін."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Ашу үшін қайтадан түртіңіз"</string> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index 0a6b62c44b8a..9a5bf067cc24 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ទូរស័ព្ទ"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ជំនួយសំឡេង"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ដោះសោ"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ប៊ូតុងដោះសោ កំពុងរង់ចាំស្នាមម្រាមដៃ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ដោះសោដោយមិនបាច់ប្រើស្នាមម្រាមដៃរបស់អ្នក"</string> <string name="unlock_label" msgid="8779712358041029439">"ដោះសោ"</string> <string name="phone_label" msgid="2320074140205331708">"បើកទូរស័ព្ទ"</string> <string name="voice_assist_label" msgid="3956854378310019854">"បើកជំនួយសំឡេង"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"អ្នកនឹងមិនរំខានដោយសម្លេង និងរំញ័រឡើយ លើកលែងតែសម្លេងរោទិ៍ ការរំលឹក ព្រឹត្តិការណ៍ និងអ្នកហៅដែលអ្នកបានបញ្ជាក់ប៉ុណ្ណោះ។"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"ប្ដូរតាមបំណង"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ ដោយរួមបញ្ចូលទាំងសំឡេងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។ អ្នកនឹងនៅតែអាចធ្វើការហៅទូរស័ព្ទបានដដែល។"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"វារារាំងសំឡេង និងរំញ័រទាំងអស់ដែលចេញពីម៉ោងរោទិ៍ តន្ត្រី វីដេអូ និងហ្គេម។"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ប៉ះម្ដងទៀតដើម្បីបើក"</string> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index 5a904391f46f..d706272ee379 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ಫೋನ್"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ಧ್ವನಿ ಸಹಾಯಕ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ಅನ್ಲಾಕ್"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ಅನ್ಲಾಕ್ ಬಟನ್, ಫಿಂಗರ್ಪ್ರಿಂಟ್ಗೆ ಕಾಯಲಾಗುತ್ತಿದೆ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ನಿಮ್ಮ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಬಳಸದೆಯೇ ಅನ್ಲಾಕ್ ಮಾಡಿ"</string> <string name="unlock_label" msgid="8779712358041029439">"ಅನ್ಲಾಕ್ ಮಾಡು"</string> <string name="phone_label" msgid="2320074140205331708">"ಫೋನ್ ತೆರೆಯಿರಿ"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ಗಾಗಿ ಎಡಕ್ಕೆ ಸ್ಲೈಡ್ ಮಾಡಿ."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"ಅಲಾರಮ್ಗಳು, ಜ್ಞಾಪನೆಗಳು, ಈವೆಂಟ್ಗಳು ಮತ್ತು ನೀವು ಸೂಚಿಸುವ ಕರೆದಾರರನ್ನು ಹೊರತುಪಡಿಸಿ, ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳಿಂದ ನಿಮಗೆ ತೊಂದರೆ ಆಗುವುದಿಲ್ಲ."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"ಕಸ್ಟಮೈಸ್ ಮಾಡು"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ಇದು ಅಲಾರಮ್ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಆಟಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. ನಿಮಗೆ ಈಗಲೂ ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ಇದು ಅಲಾರಮ್ಗಳು, ಸಂಗೀತ, ವೀಡಿಯೊಗಳು, ಮತ್ತು ಆಟಗಳು ಸೇರಿದಂತೆ ಎಲ್ಲಾ ಧ್ವನಿಗಳು ಮತ್ತು ವೈಬ್ರೇಶನ್ಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ತೆರೆಯಲು ಮತ್ತೊಮ್ಮೆ ಸ್ಪರ್ಶಿಸಿ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 2895fdff2851..18018d9f816e 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"전화"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"음성 지원"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"잠금 해제"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"잠금 해제 버튼, 지문 파일 대기 중"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"지문 파일을 사용하지 않고 잠금 해제"</string> <string name="unlock_label" msgid="8779712358041029439">"잠금 해제"</string> <string name="phone_label" msgid="2320074140205331708">"휴대전화 열기"</string> <string name="voice_assist_label" msgid="3956854378310019854">"음성 지원 열기"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"지정한 알람, 알림, 이벤트, 발신자를 제외하고 소리와 진동을 끕니다."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"맞춤설정"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다. 전화는 걸 수 있습니다."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"알람, 음악, 동영상, 게임을 포함하여 모든 소리와 진동을 끕니다."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string> <string name="notification_tap_again" msgid="8524949573675922138">"다시 터치하여 열기"</string> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 1316a4a049eb..ddf88d53a422 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ໂທລະສັບ"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ຊ່ວຍເຫຼືອທາງສຽງ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ປົດລັອກ"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ປົດລັອກປຸ່ມ, ກຳລັງລໍຖ້າລາຍນີ້ວມື"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ປົດລັອກໂດຍບໍ່ມີການໃຊ້ລາຍນີ້ວມືຂອງທ່ານ"</string> <string name="unlock_label" msgid="8779712358041029439">"ປົດລັອກ"</string> <string name="phone_label" msgid="2320074140205331708">"ເປີດແປ້ນໂທລະສັບ"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ຊ່ວເຫຼືອເປີດສຽງ"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"ທ່ານຈະບໍ່ຖືກລົບກວນຈາກສຽງ ແລະການສັ່ນ, ຍົກເວັ້ນຈາກໂມງປຸກ, ການເຕືອນ, ເຫດການ, ແລະຜູ້ໂທທີ່ທ່ານລະບຸ."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"ປັບແຕ່ງ"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ອັນນີ້ບລັອກທຸກສຽງ ແລະການສັ່ນ, ລວມທັງຈາກໂມງປຸກ, ເພງ, ວິດີໂອ, ແລະເກມ. ທ່ານຍັງຈະສາມາດໂທລະສັບໄດ້."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ອັນນີ້ບລັອກທຸກສຽງ ແລະການສັ່ນ, ລວມທັງຈາກໂມງປຸກ, ເພງ, ວິດີໂອ, ແລະເກມ."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ແຕະອີກເທື່ອນຶ່ງເພື່ອເປີດ"</string> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index 30da026cbe60..b2d4a9f3d210 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помош"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Отклучување"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Копче за отклучување, се чека отпечаток"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Отклучете без да го користите вашиот отпечаток"</string> <string name="unlock_label" msgid="8779712358041029439">"отклучи"</string> <string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string> <string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовна помош"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Лизгај налево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Нема да ви пречат звуци и вибрации, освен од аларми, потсетници, настани и повикувачи што ќе ги наведете."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Приспособи"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите. Сѐ уште ќе може да воспоставувате телефонски повици."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Ова ги блокира СИТЕ звуци и вибрации, вклучувајќи ги и оние од алармите, музиката, видеата и игрите."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Допрете повторно за да отворите"</string> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index 7c8fdc19254e..68b8603a9056 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ഫോണ്"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"വോയ്സ് സഹായം"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"അണ്ലോക്ക് ചെയ്യുക"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"അൺലോക്ക് ബട്ടൺ, ഫിംഗർപ്രിന്റിനായി കാക്കുന്നു"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"നിങ്ങളുടെ ഫിംഗർപ്രിന്റ് ഉപയോഗിക്കാതെ അൺലോക്കുചെയ്യുക"</string> <string name="unlock_label" msgid="8779712358041029439">"അൺലോക്കുചെയ്യുക"</string> <string name="phone_label" msgid="2320074140205331708">"ഫോൺ തുറക്കുക"</string> <string name="voice_assist_label" msgid="3956854378310019854">"വോയ്സ് അസിസ്റ്റ് തുറക്കുക"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> എന്നതിനായി ഇടത്തേയ്ക്ക് സ്ലൈഡുചെയ്യുക."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"നിങ്ങൾ വ്യക്തമാക്കിയിട്ടുള്ള അലാറങ്ങൾ, ഓർമ്മപ്പെടുത്തലുകൾ, ഇവന്റുകൾ, കോളർമാർ എന്നിവ ഒഴികെയുള്ള ശബ്ദങ്ങളോ വൈബ്രേഷനുകളോ കാരണം നിങ്ങൾക്ക് ശല്യമുണ്ടാകില്ല."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"ഇഷ്ടാനുസൃതമാക്കുക"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു. നിങ്ങൾക്ക് തുടർന്നും ഫോൺ വിളിക്കാനാകും."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ഇത് അലാറങ്ങൾ, സംഗീതം, വീഡിയോകൾ, ഗെയിമുകൾ എന്നിവയിൽ നിന്നുൾപ്പെടെ എല്ലാ ശബ്ദങ്ങളും വൈബ്രേഷനുകളും തടയുന്നു."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string> <string name="notification_tap_again" msgid="8524949573675922138">"തുറക്കുന്നതിന് വീണ്ടും സ്പർശിക്കുക"</string> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index bcfe68752b56..17e27a8f0878 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -85,10 +85,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Утас"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дуут туслах"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Тайлах"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Toвчлуурыг онгойлгоно уу. Хурууны хээг хүлээж байна"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Хурууны хээ ашиглалгүйгээр түгжээг тайлаарай"</string> <string name="unlock_label" msgid="8779712358041029439">"тайлах"</string> <string name="phone_label" msgid="2320074140205331708">"утас нээх"</string> <string name="voice_assist_label" msgid="3956854378310019854">"дуут туслахыг нээнэ"</string> @@ -314,10 +312,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Танд сэрүүлгэ, сануулга, үйл явдлын сануулга, таны сануулсан дуудлага зэргээс бусад дуу чимээ, чичиргээ танд садаа болохгүй."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Тохируулах"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог. Та дуудлага хийх боломжтой хэвээр байна."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Энэ нь сэрүүлэг, хөгжим, видео, тоглоом зэргийг оруулаад зэрэг БҮХ дуу, чичиргээг блоклодог."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Нээхийн тулд дахин хүрнэ үү"</string> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index ee509f4536c8..c331590899f6 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"व्हॉइस सहाय्य"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करा"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलॉक बटण, फिंगरप्रिंटची प्रतीक्षा करीत आहे"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"आपले फिंगरप्रिंट न वापरता अनलॉक करा"</string> <string name="unlock_label" msgid="8779712358041029439">"अनलॉक करा"</string> <string name="phone_label" msgid="2320074140205331708">"फोन उघडा"</string> <string name="voice_assist_label" msgid="3956854378310019854">"व्हॉइस सहाय्य उघडा"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> साठी डावीकडे स्लाइड करा."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"आपण निर्दिष्ट करता ते अलार्म, स्मरणपत्रे, इव्हेंट आणि कॉलर व्यतिरिक्त, आपल्याला आवाज आणि कंपनांमुळे व्यत्यय येणार नाही."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"सानुकूलित करा"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते. आपण तरीही फोन कॉल करण्यात सक्षम व्हाल."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"हे अलार्म, संगीत, व्हिडिओ आणि गेम यासह, सर्व आवाज आणि कंपने अवरोधित करते."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string> <string name="notification_tap_again" msgid="8524949573675922138">"उघडण्यासाठी पुन्हा स्पर्श करा"</string> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index 332592bfb08a..7c60abef2f8c 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ဖုန်း"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"အသံ အကူအညီ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"သော့ဖွင့်ရန်"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ခလုတ် ဖွင့်ရန်၊ လက်ဗွေရာအား စောင့်ပါ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"လက်ဗွေရာ မသုံးဘဲ ဖွင့်ပါ"</string> <string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string> <string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string> <string name="voice_assist_label" msgid="3956854378310019854">"အသံ အကူအညီအား ဖွင့်ရန်"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် ဖယ်ဘက်ကို ပွတ်ဆွဲပါ"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"နှိုးစက်များ၊ အသိပေးချက်များ၊ ဖြစ်ရပ်များ နှင့် သင်သတ်မှတ်ထားသည့် ခေါ်ဆိုသူများမှ လွဲ၍ အသံများနှင့် တုန်ခါမှုများသည် သင့်အား နှောင့်ယှက်မည် မဟုတ်ပါ။"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"စိတ်ကြိုက် ပြုလုပ်ရန်"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ဤအရာမှ နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား တားဆီးပေးသည်။ ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်နိုင်ဆဲဖြစ်မည်။"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"နှိုးစက်၊ ဂီတ၊ ဗွီဒီယိုများနှင့် ဂိမ်းများ အပါအဝင်၊ အသံအားလုံးနှင့် တုန်ခါမှုများအား ဤအရာမှ တားဆီးပေး၏။"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ဖွင့်ရန် ထပ်ပြီး ထိပါ"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index a7d34741c751..d8906c117e61 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Talehjelp"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Lås opp"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Lås opp-knappen – venter på fingeravtrykk"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås opp uten å bruke fingeravtrykk"</string> <string name="unlock_label" msgid="8779712358041029439">"lås opp"</string> <string name="phone_label" msgid="2320074140205331708">"åpne telefonen"</string> <string name="voice_assist_label" msgid="3956854378310019854">"åpne talehjelp"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir ikke forstyrret av lyder og vibrasjoner, bortsett fra alarmer, påminnelser, aktiviteter og oppringere du angir."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tilpass"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill. Du kan fremdeles ringe."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Dette blokkerer ALLE lyder og vibrasjoner, inkludert fra alarmer, musikk, videoer og spill."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Trykk på nytt for å åpne"</string> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 7cf0ed0cf48c..af707bafd825 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"आवाज सहायता"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"खोल्नुहोस्"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"अनलक बटन फिंगरप्रिन्ट पर्खँदै"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"तपाईँको फिंगरप्रिन्ट बिना नै अनलक गर्नुहोस्"</string> <string name="unlock_label" msgid="8779712358041029439">"खोल्नुहोस्"</string> <string name="phone_label" msgid="2320074140205331708">"फोन खोल्नुहोस्"</string> <string name="voice_assist_label" msgid="3956854378310019854">"आवाज सहायता खोल्नुहोस्"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"स्लाइड <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>को लागि बायाँ।"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"अलार्म, रिमाइन्डर, घटना, र तपाईँले निर्दिष्ट गर्नुहुने कलरहरू देखि बाहेक, आवाज र कम्पनले तपाईँ लाई वाधा गर्ने छैन।"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"अनुकूलन गर्नुहोस्"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"यसले अलार्म, संगीत, भिडियो, र खेलहरू लगायतका सबै ध्वनि र कम्पन निषेध गर्छ। तपाईँ अझै पनि फोन कल गर्न सक्षम हुनुहुन्छ।"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"यसले अलार्म, संगीत, भिडियोहरू र खेलहरूसहित सबै ध्वनिहरू र कम्पनहरूलाई रोक्छ।"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string> <string name="notification_tap_again" msgid="8524949573675922138">"खोल्न फेरि छुनुहोस्"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index ded227ae59d2..0ca197f1a5c8 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Spraakassistent"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Ontgrendelen"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Knop Ontgrendelen, wacht op vingerafdruk"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Ontgrendelen zonder uw vingerafdruk te gebruiken"</string> <string name="unlock_label" msgid="8779712358041029439">"ontgrendelen"</string> <string name="phone_label" msgid="2320074140205331708">"telefoon openen"</string> <string name="voice_assist_label" msgid="3956854378310019854">"spraakassistent openen"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"U wordt niet gestoord door geluiden en trillingen, behalve voor alarmen, herinneringen, afspraken en bellers die u specificeert."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Aanpassen"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games. U kunt wel nog steeds bellen."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Hiermee worden ALLE geluiden en trillingen geblokkeerd, waaronder die voor alarmen, muziek, video\'s en games."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Raak opnieuw aan om te openen"</string> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 45f852c0c0ef..6144a80ef51c 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ਫੋਨ"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ਵੌਇਸ ਅਸਿਸਟ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ਅਨਲੌਕ ਕਰੋ"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ਅਨਲੌਕ ਬਟਨ, ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ਆਪਣਾ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੇ ਬਿਨਾਂ ਅਨਲੌਕ ਕਰੋ"</string> <string name="unlock_label" msgid="8779712358041029439">"ਅਨਲੌਕ ਕਰੋ"</string> <string name="phone_label" msgid="2320074140205331708">"ਫੋਨ ਖੋਲ੍ਹੋ"</string> <string name="voice_assist_label" msgid="3956854378310019854">"ਵੌਇਸ ਅਸਿਸਟ ਖੋਲ੍ਹੋ"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਨਿਰਦਿਸ਼ਟ ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਇਵੈਂਟਸ, ਅਤੇ ਕਾਲਰਸ ਤੋਂ ਇਲਾਵਾ, ਧੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਤੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"ਅਨੁਕੂਲਿਤ ਕਰੋ"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ।"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀਆਂ ਧੁਨੀਆਂ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ।"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string> <string name="notification_tap_again" msgid="8524949573675922138">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਛੋਹਵੋ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 75ea440e9eb9..1f35c859623d 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asystent głosowy"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Odblokuj"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Przycisk odblokowania, oczekiwanie na odcisk palca"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odblokuj bez używania odcisku palca"</string> <string name="unlock_label" msgid="8779712358041029439">"odblokuj"</string> <string name="phone_label" msgid="2320074140205331708">"otwórz telefon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"otwórz pomoc głosową"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Urządzenie nie będzie odtwarzać dźwięków ani włączać wibracji, z wyjątkiem wybranych przez Ciebie alarmów, przypomnień, wydarzeń i kontaktów."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Dostosuj"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"To zablokuje WSZYSTKIE dźwięki i wibracje, w tym alarmy, muzykę, filmy i gry. Nadal będzie można wykonywać połączenia."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"To zablokuje WSZYSTKIE dźwięki i wibracje – w tym alarmy, muzykę, filmy i gry."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Kliknij ponownie, by otworzyć"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 1741c1c4ee07..e2ec2ffb78b9 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telemóvel"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistente de voz"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botão de desbloqueio, a aguardar a impressão digital"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sem utilizar a sua impressão digital"</string> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir telemóvel"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir assistente de voz"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Não é incomodado por sons e vibrações, exceto de alarmes, lembretes, eventos e autores de chamadas que especificar."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos. Continua a ser possível telefonar."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Esta ação bloqueia TODOS os sons e as vibrações, incluindo de alarmes, de músicas, de vídeos e de jogos."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Tocar novamente para abrir"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 4ba9ec196f70..c3fcd27362d3 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefone"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistência de voz"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Botão de desbloqueio. Aguardando impressão digital"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Desbloquear sem usar impressão digital"</string> <string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string> <string name="phone_label" msgid="2320074140205331708">"abrir telefone"</string> <string name="voice_assist_label" msgid="3956854378310019854">"abrir assistência de voz"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Você não será perturbado por sons e vibrações, com exceção de alarmes, lembretes, eventos e autores de chamadas que você especificar."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizar"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos. Você ainda poderá fazer chamadas telefônicas."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Isso bloqueia TODOS os sons e vibrações, incluindo alarmes, músicas, vídeos e jogos."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Toque novamente para abrir"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index f16d59e76fce..f1428eaa9050 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон."</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Аудиоподсказки"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Разблокировать."</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка разблокировки, отсканируйте отпечаток пальца"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Разблокировать без отпечатка пальца"</string> <string name="unlock_label" msgid="8779712358041029439">"Разблокировать."</string> <string name="phone_label" msgid="2320074140205331708">"Открыть телефон."</string> <string name="voice_assist_label" msgid="3956854378310019854">"включить аудиоподсказки"</string> @@ -320,10 +318,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Вибрация и звуки будут отключены. Вы услышите только сигналы будильника, напоминания, уведомления о мероприятиях и звонки от выбранных абонентов."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Настроить"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео). При этом вы сможете разговаривать по телефону."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"В этом режиме будут отключены вибросигнал и все звуки (в том числе для будильника, музыкального проигрывателя, игр и видео)."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные оповещения"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Нажмите ещё раз, чтобы открыть"</string> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 3d7dc479cfbe..a2ba41413fa2 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"දුරකථනය"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"හඬ සහාය"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"අඟුල අරින්න"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"අගුළු ඇරීමේ බොත්තම, ඇඟිලි සලකුණු සඳහා රැඳී සිටිමින්"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ඔබේ ඇඟිලි සලකුණ භාවිත නොකර අගුළු අරින්න"</string> <string name="unlock_label" msgid="8779712358041029439">"අඟුල අරින්න"</string> <string name="phone_label" msgid="2320074140205331708">"දුරකථනය විවෘත කරන්න"</string> <string name="voice_assist_label" msgid="3956854378310019854">"විවෘත හඬ සහාය"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> සඳහා වමට සර්පණය කරන්න."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"එලාම, සිහි කැඳවීම්, සිදුවීම් සහ ඔබ සඳහන් කරන අමතන්නන් වෙතින් හැර, වෙනත් ශබ්ද සහ කම්පනවලින් ඔබට බාධා නොවනු ඇත."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"අභිරුචිකරණය"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"මෙය සීනු, සංගීතය, වීඩියෝ, සහ ක්රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි. ඔබට තවමත් දුරකථන ඇමතුම් සිදු කිරීමේ හැකියාව ඇත."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"මෙය සීනු, සංගීතය, වීඩියෝ, සහ ක්රීඩා ඇතුළු, සියලු ශබ්ද සහ කම්පන අවහිර කරයි."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"හදිසිය අඩු දැනුම් දීම් පහත"</string> <string name="notification_tap_again" msgid="8524949573675922138">"විවෘත කිරීමට නැවත ස්පර්ශ කරන්න"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index ce92e4ab48b9..65e0cd56531e 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefón"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasový asistent"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Odomknúť"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Tlačidlo Odomknúť, čaká sa na odtlačok"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odomknúť bez použitia odtlačku"</string> <string name="unlock_label" msgid="8779712358041029439">"odomknúť"</string> <string name="phone_label" msgid="2320074140205331708">"otvoriť telefón"</string> <string name="voice_assist_label" msgid="3956854378310019854">"otvoriť hlasového asistenta"</string> @@ -320,10 +318,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Nebudú vás rušiť zvuky ani vibrácie s výnimkou budíkov, pripomenutí, udalostí a volajúcich, ktoré špecifikujete."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prispôsobiť"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier. Stále však budete môcť telefonovať."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Zablokujú sa tým VŠETKY zvuky a vibrácie vrátane zvukov budíkov, hudby, videí a hier."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Otvorte opätovným klepnutím"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 3ca6edb330a8..8e80c3822cdc 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovni pomočnik"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Odkleni"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Gumb za odklepanje, čakanje na prstni odtis"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Odklepanje brez prstnega odtisa"</string> <string name="unlock_label" msgid="8779712358041029439">"odkleni"</string> <string name="phone_label" msgid="2320074140205331708">"odpri telefon"</string> <string name="voice_assist_label" msgid="3956854378310019854">"odpri glasovnega pomočnika"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Ne bodo vas motili zvoki in vibriranje, razen od alarmov, opomnikov, dogodkov in klicateljev, ki jih določite."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Prilagodi"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger. Še vedno boste lahko opravljali telefonske klice."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"S tem so blokirani VSI zvoki in vibriranje – tudi od alarmov, glasbe, videoposnetkov in iger."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Dotaknite se znova, če želite odpreti"</string> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index 388280271c38..24987069bc2d 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoni"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ndihma zanore"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Shkyç"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Butoni i shkyçjes, në pritje për gjurmën e gishtit"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Shkyçe pa përdorur gjurmën e gishtit"</string> <string name="unlock_label" msgid="8779712358041029439">"shkyç"</string> <string name="phone_label" msgid="2320074140205331708">"hap telefonin"</string> <string name="voice_assist_label" msgid="3956854378310019854">"hap ndihmën zanore"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Rrëshqit majtas për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç atyre nga alarmet, rikujtesat, ngjarjet dhe telefonuesit që specifikon."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizo"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat. Përsëri do të mund të bësh telefonata."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Njoftimet më pak urgjente, më poshtë!"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Prek sërish për ta hapur"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index dd7921888a4b..d82922c7f4c9 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -88,10 +88,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помоћ"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Откључајте"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Дугме за откључавање, чека се на отисак прста"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Откључај без коришћења отиска прста"</string> <string name="unlock_label" msgid="8779712358041029439">"откључај"</string> <string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string> <string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовну помоћ"</string> @@ -317,10 +315,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Неће вас узнемиравати звукови и вибрације, осим за аларме, подсетнике, догађаје и позиваоце које изаберете."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Прилагоди"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре. И даље ћете моћи да упућујете позиве."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Ово блокира СВЕ звукове и вибрације укључујући аларме, музику, видео снимке и игре."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Додирните поново да бисте отворили"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 23a61cabf787..627196606203 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Mobil"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Röstassistent"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Lås upp"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Upplåsningsknapp – väntar på fingeravtryck"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Lås upp utan att använda fingeravtryck"</string> <string name="unlock_label" msgid="8779712358041029439">"lås upp"</string> <string name="phone_label" msgid="2320074140205331708">"öppna mobilen"</string> <string name="voice_assist_label" msgid="3956854378310019854">"öppna röstassistenten"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Du blir inte störd av ljud och vibrationer, förutom från alarm, påminnelser, event och specifika samtal."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Anpassa"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel. Du kan fortfarande ringa."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Detta blockerar ALLA ljud och vibrationer, inklusive alarm, musik, videor och spel."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Tryck igen för att öppna"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 975f269fd3d3..f78f433fa81b 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Simu"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Mapendekezo ya Sauti"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Fungua"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kitufe cha kufungua, kinasubiri kitambulisho"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Fungua bila kutumia kitambulisho chako"</string> <string name="unlock_label" msgid="8779712358041029439">"fungua"</string> <string name="phone_label" msgid="2320074140205331708">"fungua simu"</string> <string name="voice_assist_label" msgid="3956854378310019854">"fungua mapendekezo ya sauti"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Hutasumbuliwa na sauti na mitetemo, isipokuwa kengele, vikumbusho, matukio na wapigaji simu utakaobainisha."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Badilisha kukufaa"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa na pamoja na ile inayotokana na kengele, muziki, video na michezo. Bado utaweza kupiga simu."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Hatua hii huzuia sauti na mitetemo YOTE, ikiwa ni pamoja na ile inayotokana na kengele, muziki, video na michezo."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>+"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Gusa tena ili ufungue"</string> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index e79eb4a2cfb5..aab90ff825a2 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ஃபோன்"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"குரல் உதவி"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"திற"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"திறப்பதற்கான பொத்தான், கைரேகைக்காகக் காத்திருக்கிறது"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"உங்கள் கைரேகையைப் பயன்படுத்தாமல் திறக்கும்"</string> <string name="unlock_label" msgid="8779712358041029439">"திற"</string> <string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string> <string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> க்கு இடதுபக்கமாக இழுக்கவும்."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"அலாரங்கள், நினைவூட்டல்கள், நிகழ்வுகள், குறிப்பிட்ட அழைப்புகள் தவிர, ஒலிகளினாலும் அதிர்வினாலும் தொந்தரவு இருக்காது."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"தனிப்பயனாக்கு"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும். இருப்பினும் நீங்கள் அழைப்புகளைச் செய்யலாம்."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"இது அலாரங்கள், இசை, வீடியோக்கள் மற்றும் கேம்கள் உட்பட எல்லா ஒலிகளையும் அதிர்வுகளையும் தடுக்கும்."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string> <string name="notification_tap_again" msgid="8524949573675922138">"திறக்க, மீண்டும் தட்டவும்"</string> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index 7aaa6e228e98..308e243dcac4 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"ఫోన్"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"వాయిస్ సహాయకం"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"అన్లాక్ చేయి"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"అన్లాక్ బటన్, వేలిముద్ర కోసం వేచి ఉంది"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"మీ వేలిముద్రను ఉపయోగించకుండా అన్లాక్ చేయండి"</string> <string name="unlock_label" msgid="8779712358041029439">"అన్లాక్ చేయి"</string> <string name="phone_label" msgid="2320074140205331708">"ఫోన్ను తెరువు"</string> <string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ సహాయకం తెరువు"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> కోసం ఎడమవైపుకు స్లైడ్ చేయండి."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"మీరు అలారాలు, రిమైండర్లు, ఈవెంట్లు మరియు పేర్కొనే కాలర్ల నుండి మినహా మరే ఇతర ధ్వనులు మరియు వైబ్రేషన్లతో మీకు అంతరాయం కలగదు."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"అనుకూలీకరించు"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్లను బ్లాక్ చేస్తుంది. మీరు ఇప్పటికీ ఫోన్ కాల్లు చేయగలుగుతారు."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"ఇది అలారాలు, సంగీతం, వీడియోలు మరియు గేమ్లతో సహా అన్ని ధ్వనులు మరియు వైబ్రేషన్లను బ్లాక్ చేస్తుంది."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్లు దిగువన"</string> <string name="notification_tap_again" msgid="8524949573675922138">"తెరవడానికి మళ్లీ తాకండి"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 52afa6a422c7..8a5e2166cab3 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"โทรศัพท์"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ตัวช่วยเสียง"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"ปลดล็อก"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"ปุ่มปลดล็อก กำลังรอลายนิ้วมือ"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"ปลดล็อกโดยไม่ต้องใช้ลายนิ้วมือ"</string> <string name="unlock_label" msgid="8779712358041029439">"ปลดล็อก"</string> <string name="phone_label" msgid="2320074140205331708">"เปิดโทรศัพท์"</string> <string name="voice_assist_label" msgid="3956854378310019854">"เปิดตัวช่วยเสียง"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"คุณจะไม่ถูกรบกวนจากเสียงและการสั่น ยกเว้นการปลุก การเตือนความจำ กิจกรรม และผู้โทรที่คุณระบุ"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"กำหนดค่า"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม คุณจะยังโทรออกได้อยู่"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"การใช้โหมดนี้จะบล็อกเสียงและการสั่นทั้งหมด ซึ่งรวมถึงเสียงปลุก เพลง วิดีโอ และเกม"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string> <string name="notification_tap_again" msgid="8524949573675922138">"แตะอีกครั้งเพื่อเปิด"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index db8957184a0c..0d0ee09b9f7c 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telepono"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"I-unlock"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"I-unlock ang button, naghihintay para sa fingerprint"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"I-unlock nang hindi ginagamit ang iyong fingerprint"</string> <string name="unlock_label" msgid="8779712358041029439">"i-unlock"</string> <string name="phone_label" msgid="2320074140205331708">"buksan ang telepono"</string> <string name="voice_assist_label" msgid="3956854378310019854">"buksan ang voice assist"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Hindi ka magagambala ng mga tunog at pag-vibrate, maliban mula sa mga alarm, paalala, kaganapan at mga tinukoy mong tumatawag."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"I-customize"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro. Magagawa mo pa ring tumawag."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Bina-block nito ang LAHAT ng tunog at pag-vibrate, kabilang ang mula sa mga alarm, musika, video at laro."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Pinduting muli upang buksan"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 177c1bcdf4e0..8f7b5f7e9fdc 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sesli Yardım"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Kilidi aç"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Kilit açma düğmesi, parmak izi bekleniyor"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Kilidi, parmak iziniz olmadan açın"</string> <string name="unlock_label" msgid="8779712358041029439">"kilidi aç"</string> <string name="phone_label" msgid="2320074140205331708">"telefonu aç"</string> <string name="voice_assist_label" msgid="3956854378310019854">"sesli yardımı aç"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Belirttiğiniz alarmlar, hatırlatıcılar, etkinlikler ve arayanlar hariç olmak üzere, sesler ve titreşimlerle rahatsız edilmeyeceksiniz."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Özelleştir"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir. Telefon aramaları yapmaya devam edebileceksiniz."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Bu seçenek TÜM sesleri ve titreşimleri engeller. Buna alarmlar, müzik, videolar ve oyunlar dahildir."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Açmak için tekrar dokunun"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 220937453602..9ed43974052f 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -89,10 +89,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Номер телефону"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Голосові підказки"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Розблокувати"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Кнопка розблокування. Очікується цифровий відбиток"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Розблокувати без цифрового відбитка"</string> <string name="unlock_label" msgid="8779712358041029439">"розблокувати"</string> <string name="phone_label" msgid="2320074140205331708">"відкрити телефон"</string> <string name="voice_assist_label" msgid="3956854378310019854">"запустити голосові підказки"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Ви отримуватимете звукові й вібросигнали лише для вибраних сповіщень, нагадувань, повідомлень про події та викликів абонентів."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Налаштувати"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри. Ви зможете телефонувати."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Блокуватимуться ВСІ звукові та вібросигнали, зокрема будильники, музика, відео й ігри."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Торкніться знову, щоб відкрити"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 2e1b9789c16d..ea4da8044911 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Điện thoại"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Trợ lý thoại"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Mở khóa"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Nút Mở khóa, đang chờ vân tay"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Mở khóa không dùng vân tay của bạn"</string> <string name="unlock_label" msgid="8779712358041029439">"mở khóa"</string> <string name="phone_label" msgid="2320074140205331708">"mở điện thoại"</string> <string name="voice_assist_label" msgid="3956854378310019854">"mở trợ lý thoại"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Bạn sẽ không bị làm phiền bởi âm thanh và tiếng rung, ngoại trừ báo thức, nhắc nhở, sự kiện và người gọi mà bạn chỉ định."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Tùy chỉnh"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Chế độ này sẽ chặn TẤT CẢ âm thanh và tiếng rung, bao gồm báo thức, âm nhạc, video và trò chơi. Bạn vẫn có thể gọi điện thoại."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Chế độ này sẽ chặn TẤT CẢ âm thanh và tiếng rung, bao gồm báo thức, âm nhạc, video và trò chơi."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Chạm lại để mở"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 9ce90e33817e..a9a4f2645066 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"語音助手"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"解鎖"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"解鎖按鈕,正在等待指紋解鎖"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"不使用指紋解鎖"</string> <string name="unlock_label" msgid="8779712358041029439">"解鎖"</string> <string name="phone_label" msgid="2320074140205331708">"開啟電話"</string> <string name="voice_assist_label" msgid="3956854378310019854">"開啟語音助手"</string> @@ -318,10 +316,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"除了指定的鬧鐘、提醒、活動及來電者,您將不會受到其他聲音和震動騷擾。"</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"自訂"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲,但您仍可撥打電話。"</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"這會封鎖所有聲音和震動,包括鬧鐘、音樂、影片和遊戲。"</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"還有 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g> 則通知"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"不太緊急的通知會在下方顯示"</string> <string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 7ad977f82207..0de326701f6f 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -87,10 +87,8 @@ <string name="accessibility_phone_button" msgid="6738112589538563574">"Ifoni"</string> <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Isisekeli sezwi"</string> <string name="accessibility_unlock_button" msgid="128158454631118828">"Vula"</string> - <!-- no translation found for accessibility_unlock_button_fingerprint (8214125623493923751) --> - <skip /> - <!-- no translation found for accessibility_unlock_without_fingerprint (7541705575183694446) --> - <skip /> + <string name="accessibility_unlock_button_fingerprint" msgid="8214125623493923751">"Inkinobho yokuvula, ilinde izigxivizo zeminwe"</string> + <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Vula ngaphandle kokusebenzisa izigxivizo zakho zeminwe"</string> <string name="unlock_label" msgid="8779712358041029439">"vula"</string> <string name="phone_label" msgid="2320074140205331708">"vula ifoni"</string> <string name="voice_assist_label" msgid="3956854378310019854">"vula isilekeleli sezwi"</string> @@ -316,10 +314,8 @@ <string name="description_direction_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string> <string name="zen_priority_introduction" msgid="3070506961866919502">"Ngeke uze uphazanyiswe yimisindo nokudlidliza, ngaphandle kokuvela kuma-alamu, izikhumbuzi, imicimbi, nabashayi obacacisayo."</string> <string name="zen_priority_customize_button" msgid="7948043278226955063">"Enza ngendlela oyifisayo"</string> - <!-- no translation found for zen_silence_introduction_voice (2284540992298200729) --> - <skip /> - <!-- no translation found for zen_silence_introduction (3137882381093271568) --> - <skip /> + <string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Lokhu kuvimbela YONKE imisindo nokudludliza, kufaka phakathi ama-alamu, umculo, amavidiyo, namageyimu. Usazokwazi ukwenza amkholi wefoni."</string> + <string name="zen_silence_introduction" msgid="3137882381093271568">"Lokhu kuvimbela YONKE imisindo nokudlidliza, kufaka phakathi kusuka kuma-alamu, umculo, amavidiyo, namageyimu."</string> <string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string> <string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Thinta futhi ukuze uvule"</string> diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 674356b0f866..7838119cc6de 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -311,4 +311,12 @@ public class AssistManager { public void showDisclosure() { mAssistDisclosure.postShow(); } + + public void onUserSwitched(int newUserId) { + updateAssistInfo(); + } + + public void prepareBeforeInvocation() { + updateAssistInfo(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index d6a16fa2893c..77c27fa043c2 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -30,6 +30,8 @@ import android.os.UserHandle; import android.provider.Settings; import android.widget.ImageView; +import com.android.internal.logging.MetricsLogger; + import java.util.ArrayList; public class BrightnessController implements ToggleSlider.Listener { @@ -195,12 +197,16 @@ public class BrightnessController implements ToggleSlider.Listener { } @Override - public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) { + public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value, + boolean stopTracking) { updateIcon(mAutomatic); if (mExternalChange) return; if (!mAutomatic) { final int val = value + mMinimumBacklight; + if (stopTracking) { + MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS, val); + } setBrightness(val); if (!tracking) { AsyncTask.execute(new Runnable() { @@ -213,6 +219,9 @@ public class BrightnessController implements ToggleSlider.Listener { } } else { final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1; + if (stopTracking) { + MetricsLogger.action(mContext, MetricsLogger.ACTION_BRIGHTNESS_AUTO, value); + } setBrightnessAdj(adj); if (!tracking) { AsyncTask.execute(new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java index 74267a533054..cef4d34a1d29 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java @@ -24,6 +24,7 @@ import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; +import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; /** A dialog that provides controls for adjusting the screen brightness. */ @@ -52,11 +53,13 @@ public class BrightnessDialog extends Activity { protected void onStart() { super.onStart(); mBrightnessController.registerCallbacks(); + MetricsLogger.visible(this, MetricsLogger.BRIGHTNESS_DIALOG); } @Override protected void onStop() { super.onStop(); + MetricsLogger.hidden(this, MetricsLogger.BRIGHTNESS_DIALOG); mBrightnessController.unregisterCallbacks(); } diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java index cdb8e69eca03..d247711df41f 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java @@ -35,7 +35,8 @@ import com.android.systemui.statusbar.policy.BrightnessMirrorController; public class ToggleSlider extends RelativeLayout { public interface Listener { public void onInit(ToggleSlider v); - public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value); + public void onChanged(ToggleSlider v, boolean tracking, boolean checked, int value, + boolean stopTracking); } private Listener mListener; @@ -143,7 +144,7 @@ public class ToggleSlider extends RelativeLayout { if (mListener != null) { mListener.onChanged( - ToggleSlider.this, mTracking, checked, mSlider.getProgress()); + ToggleSlider.this, mTracking, checked, mSlider.getProgress(), false); } if (mMirror != null) { @@ -157,7 +158,7 @@ public class ToggleSlider extends RelativeLayout { public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mListener != null) { mListener.onChanged( - ToggleSlider.this, mTracking, mToggle.isChecked(), progress); + ToggleSlider.this, mTracking, mToggle.isChecked(), progress, false); } } @@ -166,8 +167,8 @@ public class ToggleSlider extends RelativeLayout { mTracking = true; if (mListener != null) { - mListener.onChanged( - ToggleSlider.this, mTracking, mToggle.isChecked(), mSlider.getProgress()); + mListener.onChanged(ToggleSlider.this, mTracking, mToggle.isChecked(), + mSlider.getProgress(), false); } mToggle.setChecked(false); @@ -183,8 +184,8 @@ public class ToggleSlider extends RelativeLayout { mTracking = false; if (mListener != null) { - mListener.onChanged( - ToggleSlider.this, mTracking, mToggle.isChecked(), mSlider.getProgress()); + mListener.onChanged(ToggleSlider.this, mTracking, mToggle.isChecked(), + mSlider.getProgress(), true); } if (mMirrorController != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 295fdc81e775..9d6204c0e3b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1613,17 +1613,11 @@ public abstract class BaseStatusBar extends SystemUI implements /** * The LEDs are turned off when the notification panel is shown, even just a little bit. - * This was added last-minute and is inconsistent with the way the rest of the notifications - * are handled, because the notification isn't really cancelled. The lights are just - * turned off. If any other notifications happen, the lights will turn back on. Steve says - * this is what he wants. (see bug 1131461) */ protected void handleVisibleToUserChanged(boolean visibleToUser) { try { if (visibleToUser) { - // Only stop blinking, vibrating, ringing when the user went into the shade - // manually (SHADE or SHADE_LOCKED). - boolean clearNotificationEffects = + boolean clearNotificationEffects = mShowLockscreenNotifications || (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED); mBarService.onPanelRevealed(clearNotificationEffects); } else { 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 ade40e507173..9e6dd7e86537 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -96,6 +96,7 @@ import android.widget.ImageView; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; +import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.StatusBarIcon; import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.keyguard.ViewMediatorCallback; @@ -457,7 +458,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private int mDisabledUnmodified2; /** Keys of notifications currently visible to the user. */ - private final ArraySet<String> mCurrentlyVisibleNotifications = new ArraySet<String>(); + private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications = + new ArraySet<>(); private long mLastVisibilityReportUptimeMs; private final ShadeUpdates mShadeUpdates = new ShadeUpdates(); @@ -471,9 +473,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private int mLastLoggedStateFingerprint; private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD - | StackViewState.LOCATION_TOP_STACK_PEEKING - | StackViewState.LOCATION_MAIN_AREA - | StackViewState.LOCATION_BOTTOM_STACK_PEEKING; + | StackViewState.LOCATION_MAIN_AREA; private final OnChildLocationsChangedListener mNotificationLocationsChangedListener = new OnChildLocationsChangedListener() { @@ -498,12 +498,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Tracks notifications currently visible in mNotificationStackScroller and // emits visibility events via NoMan on changes. private final Runnable mVisibilityReporter = new Runnable() { - private final ArrayList<String> mTmpNewlyVisibleNotifications = new ArrayList<String>(); - private final ArrayList<String> mTmpCurrentlyVisibleNotifications = new ArrayList<String>(); + private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications = + new ArraySet<>(); + private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications = + new ArraySet<>(); + private final ArraySet<NotificationVisibility> mTmpNoLongerVisibleNotifications = + new ArraySet<>(); @Override public void run() { mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis(); + final String mediaKey = getCurrentMediaNotificationKey(); // 1. Loop over mNotificationData entries: // A. Keep list of visible notifications. @@ -518,31 +523,45 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, for (int i = 0; i < N; i++) { Entry entry = activeNotifications.get(i); String key = entry.notification.getKey(); - boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key); - boolean currentlyVisible = + boolean isVisible = (mStackScroller.getChildLocation(entry.row) & VISIBLE_LOCATIONS) != 0; - if (currentlyVisible) { + NotificationVisibility visObj = NotificationVisibility.obtain(key, i, isVisible); + boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(visObj); + if (isVisible) { // Build new set of visible notifications. - mTmpCurrentlyVisibleNotifications.add(key); - } - if (!previouslyVisible && currentlyVisible) { - mTmpNewlyVisibleNotifications.add(key); + mTmpCurrentlyVisibleNotifications.add(visObj); + if (!previouslyVisible) { + mTmpNewlyVisibleNotifications.add(visObj); + } + } else { + // release object + visObj.recycle(); } } - ArraySet<String> noLongerVisibleNotifications = mCurrentlyVisibleNotifications; - noLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications); + mTmpNoLongerVisibleNotifications.addAll(mCurrentlyVisibleNotifications); + mTmpNoLongerVisibleNotifications.removeAll(mTmpCurrentlyVisibleNotifications); logNotificationVisibilityChanges( - mTmpNewlyVisibleNotifications, noLongerVisibleNotifications); + mTmpNewlyVisibleNotifications, mTmpNoLongerVisibleNotifications); - mCurrentlyVisibleNotifications.clear(); + recycleAllVisibilityObjects(mCurrentlyVisibleNotifications); mCurrentlyVisibleNotifications.addAll(mTmpCurrentlyVisibleNotifications); - mTmpNewlyVisibleNotifications.clear(); + recycleAllVisibilityObjects(mTmpNoLongerVisibleNotifications); mTmpCurrentlyVisibleNotifications.clear(); + mTmpNewlyVisibleNotifications.clear(); + mTmpNoLongerVisibleNotifications.clear(); } }; + private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) { + final int N = array.size(); + for (int i = 0 ; i < N; i++) { + array.valueAt(i).recycle(); + } + array.clear(); + } + private final View.OnClickListener mOverflowClickListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -1028,6 +1047,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private int mShowSearchHoldoff = 0; private Runnable mInvokeAssist = new Runnable() { public void run() { + mAssistManager.prepareBeforeInvocation(); invokeAssistGesture(true /* vibrate */); awakenDreams(); if (mNavigationBarView != null) { @@ -2917,6 +2937,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateNotifications(); resetUserSetupObserver(); setControllerUsers(); + mAssistManager.onUserSwitched(newUserId); } private void setControllerUsers() { @@ -2987,9 +3008,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Report all notifications as invisible and turn down the // reporter. if (!mCurrentlyVisibleNotifications.isEmpty()) { - logNotificationVisibilityChanges( - Collections.<String>emptyList(), mCurrentlyVisibleNotifications); - mCurrentlyVisibleNotifications.clear(); + logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(), + mCurrentlyVisibleNotifications); + recycleAllVisibilityObjects(mCurrentlyVisibleNotifications); } mHandler.removeCallbacks(mVisibilityReporter); mStackScroller.setChildLocationsChangedListener(null); @@ -3007,18 +3028,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void logNotificationVisibilityChanges( - Collection<String> newlyVisible, Collection<String> noLongerVisible) { + Collection<NotificationVisibility> newlyVisible, + Collection<NotificationVisibility> noLongerVisible) { if (newlyVisible.isEmpty() && noLongerVisible.isEmpty()) { return; } - String[] newlyVisibleAr = newlyVisible.toArray(new String[newlyVisible.size()]); - String[] noLongerVisibleAr = noLongerVisible.toArray(new String[noLongerVisible.size()]); + NotificationVisibility[] newlyVisibleAr = + newlyVisible.toArray(new NotificationVisibility[newlyVisible.size()]); + NotificationVisibility[] noLongerVisibleAr = + noLongerVisible.toArray(new NotificationVisibility[noLongerVisible.size()]); try { mBarService.onNotificationVisibilityChanged(newlyVisibleAr, noLongerVisibleAr); } catch (RemoteException e) { // Ignore. } - setNotificationsShown(newlyVisibleAr); + + final int N = newlyVisible.size(); + String[] newlyVisibleKeyAr = new String[N]; + for (int i = 0; i < N; i++) { + newlyVisibleKeyAr[i] = newlyVisibleAr[i].key; + } + setNotificationsShown(newlyVisibleKeyAr); } // State logging @@ -3886,6 +3916,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScreenOnComingFromTouch = true; mScreenOnTouchLocation = new PointF(event.getX(), event.getY()); mNotificationPanel.setTouchDisabled(false); + mStatusBarKeyguardViewManager.notifyScreenWakeUpRequested(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index fcf3a9c2e477..a7e8406f1cf3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -73,6 +73,7 @@ public class StatusBarKeyguardViewManager { private boolean mLastBouncerShowing; private boolean mLastBouncerDismissible; private OnDismissAction mAfterKeyguardGoneAction; + private boolean mScreenWillWakeUp; public StatusBarKeyguardViewManager(Context context, ViewMediatorCallback callback, LockPatternUtils lockPatternUtils) { @@ -163,6 +164,7 @@ public class StatusBarKeyguardViewManager { public void onScreenTurnedOn(final IKeyguardShowCallback callback) { mScreenOn = true; + mScreenWillWakeUp = false; mPhoneStatusBar.onScreenTurnedOn(); if (callback != null) { callbackAfterDraw(callback); @@ -182,6 +184,10 @@ public class StatusBarKeyguardViewManager { }); } + public void notifyScreenWakeUpRequested() { + mScreenWillWakeUp = !mScreenOn; + } + public void verifyUnlock() { dismiss(); } @@ -297,7 +303,7 @@ public class StatusBarKeyguardViewManager { * Dismisses the keyguard by going to the next screen or making it gone. */ public void dismiss() { - if (mScreenOn) { + if (mScreenOn || mScreenWillWakeUp) { showBouncer(); } } diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java index 2b76c31ca90b..a5b244e21c91 100644 --- a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java +++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java @@ -150,13 +150,23 @@ public class QsTuner extends Fragment implements Callback { } public void onStartDrag() { - mDropTarget.setVisibility(View.VISIBLE); - mAddTarget.setVisibility(View.GONE); + mDropTarget.post(new Runnable() { + @Override + public void run() { + mDropTarget.setVisibility(View.VISIBLE); + mAddTarget.setVisibility(View.GONE); + } + }); } public void stopDrag() { - mDropTarget.setVisibility(View.GONE); - mAddTarget.setVisibility(View.VISIBLE); + mDropTarget.post(new Runnable() { + @Override + public void run() { + mDropTarget.setVisibility(View.GONE); + mAddTarget.setVisibility(View.VISIBLE); + } + }); } @Override @@ -230,9 +240,16 @@ public class QsTuner extends Fragment implements Callback { public void showAddDialog() { List<String> tiles = mTileSpecs; + int numBroadcast = 0; + for (int i = 0; i < tiles.size(); i++) { + if (tiles.get(i).startsWith(IntentTile.PREFIX)) { + numBroadcast++; + } + } String[] defaults = getContext().getString(R.string.quick_settings_tiles_default).split(","); - final String[] available = new String[defaults.length + 1 - tiles.size()]; + final String[] available = new String[defaults.length + 1 + - (tiles.size() - numBroadcast)]; final String[] availableTiles = new String[available.length]; int index = 0; for (int i = 0; i < defaults.length; i++) { diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index b33b10bc7abc..25f8872fa53c 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -19,6 +19,7 @@ package com.android.server; import android.Manifest; import android.app.ActivityManager; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetoothCallback; @@ -114,6 +115,13 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final int SERVICE_IBLUETOOTH = 1; private static final int SERVICE_IBLUETOOTHGATT = 2; + private static final String[] DEVICE_TYPE_NAMES = new String[] { + "???", + "BR/EDR", + "LE", + "DUAL" + }; + private final Context mContext; private static int mBleAppCount = 0; @@ -1801,6 +1809,14 @@ class BluetoothManagerService extends IBluetoothManager.Stub { } else { ParcelFileDescriptor pfd = null; try { + writer.println("Bonded devices:"); + for (BluetoothDevice device : mBluetooth.getBondedDevices()) { + writer.println(" " + device.getAddress() + + " [" + DEVICE_TYPE_NAMES[device.getType()] + "] " + + device.getName()); + } + writer.flush(); + pfd = ParcelFileDescriptor.dup(fd); mBluetooth.dump(pfd); } catch (RemoteException re) { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 25d4d5ec01e0..2d5141eda962 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -23,6 +23,7 @@ import static android.net.ConnectivityManager.TYPE_NONE; import static android.net.ConnectivityManager.TYPE_VPN; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; +import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; @@ -1559,7 +1560,7 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkCapabilities.TRANSPORT_WIFI)) { timeout = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DATA_ACTIVITY_TIMEOUT_WIFI, - 5); + 15); type = ConnectivityManager.TYPE_WIFI; } else { // do not track any other networks @@ -1869,7 +1870,14 @@ public class ConnectivityService extends IConnectivityManager.Stub if (nai == null) { loge("EVENT_NETWORK_CAPABILITIES_CHANGED from unknown NetworkAgent"); } else { - updateCapabilities(nai, (NetworkCapabilities)msg.obj); + final NetworkCapabilities networkCapabilities = + (NetworkCapabilities)msg.obj; + if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL) || + networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { + Slog.wtf(TAG, "BUG: " + nai + " has stateful capability."); + } + updateCapabilities(nai, networkCapabilities, + NascentState.NOT_JUST_VALIDATED); } break; } @@ -1956,20 +1964,16 @@ public class ConnectivityService extends IConnectivityManager.Stub if (isLiveNetworkAgent(nai, "EVENT_NETWORK_TESTED")) { final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); - final boolean validationChanged = (valid != nai.lastValidated); - nai.lastValidated = valid; - if (valid) { - if (DBG) log("Validated " + nai.name()); - nai.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); - if (!nai.everValidated) { - nai.everValidated = true; - rematchNetworkAndRequests(nai, NascentState.JUST_VALIDATED, - ReapUnvalidatedNetworks.REAP); - // If score has changed, rebroadcast to NetworkFactories. b/17726566 - sendUpdatedScoreToFactories(nai); - } - } else { - nai.networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED); + if (DBG) log(nai.name() + " validation " + (valid ? " passed" : "failed")); + if (valid != nai.lastValidated) { + final int oldScore = nai.getCurrentScore(); + final NascentState nascent = (valid && !nai.everValidated) ? + NascentState.JUST_VALIDATED : NascentState.NOT_JUST_VALIDATED; + nai.lastValidated = valid; + nai.everValidated |= valid; + updateCapabilities(nai, nai.networkCapabilities, nascent); + // If score has changed, rebroadcast to NetworkFactories. b/17726566 + if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); } updateInetCondition(nai); // Let the NetworkAgent know the state of its network @@ -1977,10 +1981,6 @@ public class ConnectivityService extends IConnectivityManager.Stub android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS, (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), 0, null); - - if (validationChanged) { - notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED); - } } break; } @@ -1993,21 +1993,28 @@ public class ConnectivityService extends IConnectivityManager.Stub } case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: { final int netId = msg.arg2; - if (msg.arg1 == 0) { - setProvNotificationVisibleIntent(false, netId, null, 0, null, null); + final boolean visible = (msg.arg1 != 0); + final NetworkAgentInfo nai; + synchronized (mNetworkForNetId) { + nai = mNetworkForNetId.get(netId); + } + // If captive portal status has changed, update capabilities. + if (nai != null && (visible != nai.lastCaptivePortalDetected)) { + nai.lastCaptivePortalDetected = visible; + nai.everCaptivePortalDetected |= visible; + updateCapabilities(nai, nai.networkCapabilities, + NascentState.NOT_JUST_VALIDATED); + } + if (!visible) { + setProvNotificationVisibleIntent(false, netId, null, 0, null, null, false); } else { - final NetworkAgentInfo nai; - synchronized (mNetworkForNetId) { - nai = mNetworkForNetId.get(netId); - } if (nai == null) { loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); break; } - nai.captivePortalDetected = true; setProvNotificationVisibleIntent(true, netId, NotificationType.SIGN_IN, - nai.networkInfo.getType(),nai.networkInfo.getExtraInfo(), - (PendingIntent)msg.obj); + nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), + (PendingIntent)msg.obj, nai.networkMisc.explicitlySelected); } break; } @@ -2390,7 +2397,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (accept != nai.networkMisc.acceptUnvalidated) { int oldScore = nai.getCurrentScore(); nai.networkMisc.acceptUnvalidated = accept; - rematchAllNetworksAndRequests(nai, oldScore); + rematchAllNetworksAndRequests(nai, oldScore, NascentState.NOT_JUST_VALIDATED); sendUpdatedScoreToFactories(nai); } @@ -2426,7 +2433,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Only prompt if the network is unvalidated and was explicitly selected by the user, and if // we haven't already been told to switch to it regardless of whether it validated or not. // Also don't prompt on captive portals because we're already prompting the user to sign in. - if (nai == null || nai.everValidated || nai.captivePortalDetected || + if (nai == null || nai.everValidated || nai.everCaptivePortalDetected || !nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) { return; } @@ -2440,7 +2447,7 @@ public class ConnectivityService extends IConnectivityManager.Stub PendingIntent pendingIntent = PendingIntent.getActivityAsUser( mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT); setProvNotificationVisibleIntent(true, nai.network.netId, NotificationType.NO_INTERNET, - nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), pendingIntent); + nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), pendingIntent, true); } private class InternalHandler extends Handler { @@ -3233,7 +3240,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Concatenate the range of types onto the range of NetIDs. int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE); setProvNotificationVisibleIntent(visible, id, NotificationType.SIGN_IN, - networkType, null, pendingIntent); + networkType, null, pendingIntent, false); } /** @@ -3252,11 +3259,12 @@ public class ConnectivityService extends IConnectivityManager.Stub * we concatenate the range of types with the range of NetIDs. */ private void setProvNotificationVisibleIntent(boolean visible, int id, - NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent) { + NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent, + boolean highPriority) { if (DBG) { log("setProvNotificationVisibleIntent " + notifyType + " visible=" + visible + " networkType=" + getNetworkTypeName(networkType) - + " extraInfo=" + extraInfo); + + " extraInfo=" + extraInfo + " highPriority=" + highPriority); } Resources r = Resources.getSystem(); @@ -3311,6 +3319,12 @@ public class ConnectivityService extends IConnectivityManager.Stub .setContentTitle(title) .setContentText(details) .setContentIntent(intent) + .setLocalOnly(true) + .setPriority(highPriority ? + Notification.PRIORITY_HIGH : + Notification.PRIORITY_DEFAULT) + .setDefaults(Notification.DEFAULT_ALL) + .setOnlyAlertOnce(true) .build(); try { @@ -3571,12 +3585,24 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + private void ensureImmutableCapabilities(NetworkCapabilities networkCapabilities) { + if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { + throw new IllegalArgumentException( + "Cannot request network with NET_CAPABILITY_VALIDATED"); + } + if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) { + throw new IllegalArgumentException( + "Cannot request network with NET_CAPABILITY_CAPTIVE_PORTAL"); + } + } + @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { networkCapabilities = new NetworkCapabilities(networkCapabilities); enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); + ensureImmutableCapabilities(networkCapabilities); if (timeoutMs < 0 || timeoutMs > ConnectivityManager.MAX_NETWORK_REQUEST_TIMEOUT_MS) { throw new IllegalArgumentException("Bad timeout specified"); @@ -3645,6 +3671,7 @@ public class ConnectivityService extends IConnectivityManager.Stub networkCapabilities = new NetworkCapabilities(networkCapabilities); enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); + ensureImmutableCapabilities(networkCapabilities); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId()); @@ -4046,18 +4073,35 @@ public class ConnectivityService extends IConnectivityManager.Stub mNumDnsEntries = last; } + /** + * Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities} + * augmented with any stateful capabilities implied from {@code networkAgent} + * (e.g., validated status and captive portal status). + * + * @param networkAgent the network having its capabilities updated. + * @param networkCapabilities the new network capabilities. + * @param nascent indicates whether {@code networkAgent} was validated + * (i.e. had everValidated set for the first time) immediately prior to this call. + */ private void updateCapabilities(NetworkAgentInfo networkAgent, - NetworkCapabilities networkCapabilities) { + NetworkCapabilities networkCapabilities, NascentState nascent) { + // Don't modify caller's NetworkCapabilities. + networkCapabilities = new NetworkCapabilities(networkCapabilities); + if (networkAgent.lastValidated) { + networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); + } else { + networkCapabilities.removeCapability(NET_CAPABILITY_VALIDATED); + } + if (networkAgent.lastCaptivePortalDetected) { + networkCapabilities.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + } else { + networkCapabilities.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL); + } if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) { synchronized (networkAgent) { networkAgent.networkCapabilities = networkCapabilities; } - if (networkAgent.lastValidated) { - networkAgent.networkCapabilities.addCapability(NET_CAPABILITY_VALIDATED); - // There's no need to remove the capability if we think the network is unvalidated, - // because NetworkAgents don't set the validated capability. - } - rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore()); + rematchAllNetworksAndRequests(networkAgent, networkAgent.getCurrentScore(), nascent); notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_CAP_CHANGED); } } @@ -4401,15 +4445,21 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - // Attempt to rematch all Networks with NetworkRequests. This may result in Networks - // being disconnected. - // If only one Network's score or capabilities have been modified since the last time - // this function was called, pass this Network in via the "changed" arugment, otherwise - // pass null. - // If only one Network has been changed but its NetworkCapabilities have not changed, - // pass in the Network's score (from getCurrentScore()) prior to the change via - // "oldScore", otherwise pass changed.getCurrentScore() or 0 if "changed" is null. - private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore) { + /** + * Attempt to rematch all Networks with NetworkRequests. This may result in Networks + * being disconnected. + * @param changed If only one Network's score or capabilities have been modified since the last + * time this function was called, pass this Network in this argument, otherwise pass + * null. + * @param oldScore If only one Network has been changed but its NetworkCapabilities have not + * changed, pass in the Network's score (from getCurrentScore()) prior to the change via + * this argument, otherwise pass {@code changed.getCurrentScore()} or 0 if + * {@code changed} is {@code null}. This is because NetworkCapabilities influence a + * network's score. + * @param nascent indicates if {@code changed} has just been validated. + */ + private void rematchAllNetworksAndRequests(NetworkAgentInfo changed, int oldScore, + NascentState nascent) { // TODO: This may get slow. The "changed" parameter is provided for future optimization // to avoid the slowness. It is not simply enough to process just "changed", for // example in the case where "changed"'s score decreases and another network should begin @@ -4418,9 +4468,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // Optimization: Only reprocess "changed" if its score improved. This is safe because it // can only add more NetworkRequests satisfied by "changed", and this is exactly what // rematchNetworkAndRequests() handles. - if (changed != null && oldScore < changed.getCurrentScore()) { - rematchNetworkAndRequests(changed, NascentState.NOT_JUST_VALIDATED, - ReapUnvalidatedNetworks.REAP); + if (changed != null && + (oldScore < changed.getCurrentScore() || nascent == NascentState.JUST_VALIDATED)) { + rematchNetworkAndRequests(changed, nascent, ReapUnvalidatedNetworks.REAP); } else { for (Iterator i = mNetworkAgentInfos.values().iterator(); i.hasNext(); ) { rematchNetworkAndRequests((NetworkAgentInfo)i.next(), @@ -4547,7 +4597,7 @@ public class ConnectivityService extends IConnectivityManager.Stub final int oldScore = nai.getCurrentScore(); nai.setCurrentScore(score); - rematchAllNetworksAndRequests(nai, oldScore); + rematchAllNetworksAndRequests(nai, oldScore, NascentState.NOT_JUST_VALIDATED); sendUpdatedScoreToFactories(nai); } diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 49d4c221397d..43b640b434ce 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -74,7 +74,7 @@ option java_package com.android.server # when a notification has been canceled 27530 notification_canceled (key|3),(reason|1),(lifespan|1),(freshness|1),(exposure|1) # replaces 27510 with a row per notification -27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1) +27531 notification_visibility (key|3),(visibile|1),(lifespan|1),(freshness|1),(exposure|1),(rank|1) # a notification emited noise, vibration, or light 27532 notification_alert (key|3),(buzz|1),(beep|1),(blink|1) diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 61bedf5d6bd7..cae060a8493e 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -270,6 +270,17 @@ public class LocationManagerService extends ILocationManager.Stub { }; mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback); + PackageManager.OnPermissionsChangedListener permissionListener + = new PackageManager.OnPermissionsChangedListener() { + @Override + public void onPermissionsChanged(final int uid) { + synchronized (mLock) { + applyAllProviderRequirementsLocked(); + } + } + }; + mPackageManager.addOnPermissionsChangeListener(permissionListener); + mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); updateUserProfiles(mCurrentUserId); @@ -1133,23 +1144,34 @@ public class LocationManagerService extends ILocationManager.Stub { return -1; } - boolean reportLocationAccessNoThrow(int uid, String packageName, int allowedResolutionLevel) { + boolean reportLocationAccessNoThrow( + int pid, int uid, String packageName, int allowedResolutionLevel) { int op = resolutionLevelToOp(allowedResolutionLevel); if (op >= 0) { if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { return false; } } + + if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) { + return false; + } + return true; } - boolean checkLocationAccess(int uid, String packageName, int allowedResolutionLevel) { + boolean checkLocationAccess(int pid, int uid, String packageName, int allowedResolutionLevel) { int op = resolutionLevelToOp(allowedResolutionLevel); if (op >= 0) { if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { return false; } } + + if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) { + return false; + } + return true; } @@ -1347,7 +1369,10 @@ public class LocationManagerService extends ILocationManager.Stub { if (records != null) { for (UpdateRecord record : records) { if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) { - if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName, + if (checkLocationAccess( + record.mReceiver.mPid, + record.mReceiver.mUid, + record.mReceiver.mPackageName, record.mReceiver.mAllowedResolutionLevel)) { LocationRequest locationRequest = record.mRequest; providerRequest.locationRequests.add(locationRequest); @@ -1583,7 +1608,7 @@ public class LocationManagerService extends ILocationManager.Stub { try { // We don't check for MODE_IGNORED here; we will do that when we go to deliver // a location. - checkLocationAccess(uid, packageName, allowedResolutionLevel); + checkLocationAccess(pid, uid, packageName, allowedResolutionLevel); synchronized (mLock) { Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid, @@ -1711,6 +1736,7 @@ public class LocationManagerService extends ILocationManager.Stub { request.getProvider()); // no need to sanitize this request, as only the provider name is used + final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long identity = Binder.clearCallingIdentity(); try { @@ -1720,7 +1746,7 @@ public class LocationManagerService extends ILocationManager.Stub { return null; } - if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) { + if (!reportLocationAccessNoThrow(pid, uid, packageName, allowedResolutionLevel)) { if (D) Log.d(TAG, "not returning last loc for no op app: " + packageName); return null; @@ -1794,7 +1820,6 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) { - checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel()); checkPendingIntent(intent); checkPackageName(packageName); @@ -1816,10 +1841,11 @@ public class LocationManagerService extends ILocationManager.Stub { checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, LocationManager.GPS_PROVIDER); + final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { - if (!checkLocationAccess(uid, packageName, allowedResolutionLevel)) { + if (!checkLocationAccess(pid, uid, packageName, allowedResolutionLevel)) { return false; } } finally { @@ -1859,11 +1885,12 @@ public class LocationManagerService extends ILocationManager.Stub { allowedResolutionLevel, LocationManager.GPS_PROVIDER); + int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); boolean hasLocationAccess; try { - hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel); + hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel); } finally { Binder.restoreCallingIdentity(identity); } @@ -1890,11 +1917,12 @@ public class LocationManagerService extends ILocationManager.Stub { allowedResolutionLevel, LocationManager.GPS_PROVIDER); + int pid = Binder.getCallingPid(); int uid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); boolean hasLocationAccess; try { - hasLocationAccess = checkLocationAccess(uid, packageName, allowedResolutionLevel); + hasLocationAccess = checkLocationAccess(pid, uid, packageName, allowedResolutionLevel); } finally { Binder.restoreCallingIdentity(identity); } @@ -2209,7 +2237,7 @@ public class LocationManagerService extends ILocationManager.Stub { continue; } - if (!reportLocationAccessNoThrow(receiver.mUid, receiver.mPackageName, + if (!reportLocationAccessNoThrow(receiver.mPid, receiver.mUid, receiver.mPackageName, receiver.mAllowedResolutionLevel)) { if (D) Log.d(TAG, "skipping loc update for no op app: " + receiver.mPackageName); diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index 5436ce020abc..c5ea8bc1dbc6 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -27,11 +27,10 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.content.Context.USER_SERVICE; -import static android.Manifest.permission.READ_PROFILE; +import static android.Manifest.permission.READ_CONTACTS; import android.database.sqlite.SQLiteDatabase; import android.os.Binder; import android.os.IBinder; -import android.os.Process; import android.os.RemoteException; import android.os.storage.IMountService; import android.os.ServiceManager; @@ -264,12 +263,12 @@ public class LockSettingsService extends ILockSettings.Stub { private final void checkReadPermission(String requestedKey, int userId) { final int callingUid = Binder.getCallingUid(); - for (int i = 0; i < READ_PROFILE_PROTECTED_SETTINGS.length; i++) { - String key = READ_PROFILE_PROTECTED_SETTINGS[i]; - if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_PROFILE) + for (int i = 0; i < READ_CONTACTS_PROTECTED_SETTINGS.length; i++) { + String key = READ_CONTACTS_PROTECTED_SETTINGS[i]; + if (key.equals(requestedKey) && mContext.checkCallingOrSelfPermission(READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("uid=" + callingUid - + " needs permission " + READ_PROFILE + " to read " + + " needs permission " + READ_CONTACTS + " to read " + requestedKey + " for user " + userId); } } @@ -722,8 +721,8 @@ public class LockSettingsService extends ILockSettings.Stub { Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED }; - // Reading these settings needs the profile permission - private static final String[] READ_PROFILE_PROTECTED_SETTINGS = new String[] { + // Reading these settings needs the contacts permission + private static final String[] READ_CONTACTS_PROTECTED_SETTINGS = new String[] { Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, Secure.LOCK_SCREEN_OWNER_INFO }; diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 34dceedb0a8f..7204aec5e692 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -259,6 +259,7 @@ class MountService extends IMountService.Stub private static final String TAG_VOLUME = "volume"; private static final String ATTR_TYPE = "type"; private static final String ATTR_FS_UUID = "fsUuid"; + private static final String ATTR_PART_GUID = "partGuid"; private static final String ATTR_NICKNAME = "nickname"; private static final String ATTR_USER_FLAGS = "userFlags"; @@ -689,7 +690,7 @@ class MountService extends IMountService.Stub // Create a stub volume that represents internal storage final VolumeInfo internal = new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL, - VolumeInfo.TYPE_PRIVATE, null, 0); + VolumeInfo.TYPE_PRIVATE, null, null, 0); internal.state = VolumeInfo.STATE_MOUNTED; internal.path = Environment.getDataDirectory().getAbsolutePath(); mVolumes.put(internal.id, internal); @@ -900,10 +901,12 @@ class MountService extends IMountService.Stub case VoldResponseCode.VOLUME_CREATED: { final String id = cooked[1]; final int type = Integer.parseInt(cooked[2]); - final String diskId = (cooked.length == 4) ? cooked[3] : null; + final String diskId = TextUtils.nullIfEmpty(cooked[3]); + final String partGuid = TextUtils.nullIfEmpty(cooked[4]); + final DiskInfo disk = mDisks.get(diskId); final int mtpIndex = allocateMtpIndex(id); - final VolumeInfo vol = new VolumeInfo(id, type, disk, mtpIndex); + final VolumeInfo vol = new VolumeInfo(id, type, disk, partGuid, mtpIndex); mVolumes.put(id, vol); onVolumeCreatedLocked(vol); break; @@ -1091,13 +1094,21 @@ class MountService extends IMountService.Stub // Remember that we saw this volume so we're ready to accept user // metadata, or so we can annoy them when a private volume is ejected if (vol.isMountedReadable() && !TextUtils.isEmpty(vol.fsUuid)) { - if (!mRecords.containsKey(vol.fsUuid)) { - final VolumeRecord rec = new VolumeRecord(vol.type, vol.fsUuid); + VolumeRecord rec = mRecords.get(vol.fsUuid); + if (rec == null) { + rec = new VolumeRecord(vol.type, vol.fsUuid); + rec.partGuid = vol.partGuid; if (vol.type == VolumeInfo.TYPE_PRIVATE) { rec.nickname = vol.disk.getDescription(); } mRecords.put(rec.fsUuid, rec); writeSettingsLocked(); + } else { + // Handle upgrade case where we didn't store partition GUID + if (TextUtils.isEmpty(rec.partGuid)) { + rec.partGuid = vol.partGuid; + writeSettingsLocked(); + } } } @@ -1347,6 +1358,7 @@ class MountService extends IMountService.Stub final int type = readIntAttribute(in, ATTR_TYPE); final String fsUuid = readStringAttribute(in, ATTR_FS_UUID); final VolumeRecord meta = new VolumeRecord(type, fsUuid); + meta.partGuid = readStringAttribute(in, ATTR_PART_GUID); meta.nickname = readStringAttribute(in, ATTR_NICKNAME); meta.userFlags = readIntAttribute(in, ATTR_USER_FLAGS); return meta; @@ -1356,6 +1368,7 @@ class MountService extends IMountService.Stub out.startTag(null, TAG_VOLUME); writeIntAttribute(out, ATTR_TYPE, rec.type); writeStringAttribute(out, ATTR_FS_UUID, rec.fsUuid); + writeStringAttribute(out, ATTR_PART_GUID, rec.partGuid); writeStringAttribute(out, ATTR_NICKNAME, rec.nickname); writeIntAttribute(out, ATTR_USER_FLAGS, rec.userFlags); out.endTag(null, TAG_VOLUME); @@ -1491,6 +1504,8 @@ class MountService extends IMountService.Stub try { final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId); return Long.parseLong(res.getMessage()); + } catch (NativeDaemonTimeoutException e) { + return Long.MAX_VALUE; } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } @@ -1573,9 +1588,11 @@ class MountService extends IMountService.Stub Preconditions.checkNotNull(fsUuid); synchronized (mLock) { - mRecords.remove(fsUuid); - - // TODO: tell vold to forget keys + final VolumeRecord rec = mRecords.remove(fsUuid); + if (rec != null && !TextUtils.isEmpty(rec.partGuid)) { + forgetPartition(rec.partGuid); + } + mCallbacks.notifyVolumeForgotten(fsUuid); // If this had been primary storage, revert back to internal and // reset vold so we bind into new volume into place. @@ -1584,7 +1601,6 @@ class MountService extends IMountService.Stub resetIfReadyAndConnected(); } - mCallbacks.notifyVolumeForgotten(fsUuid); writeSettingsLocked(); } } @@ -1597,6 +1613,10 @@ class MountService extends IMountService.Stub synchronized (mLock) { for (int i = 0; i < mRecords.size(); i++) { final String fsUuid = mRecords.keyAt(i); + final VolumeRecord rec = mRecords.valueAt(i); + if (!TextUtils.isEmpty(rec.partGuid)) { + forgetPartition(rec.partGuid); + } mCallbacks.notifyVolumeForgotten(fsUuid); } mRecords.clear(); @@ -1610,6 +1630,14 @@ class MountService extends IMountService.Stub } } + private void forgetPartition(String partGuid) { + try { + mConnector.execute("volume", "forget_partition", partGuid); + } catch (NativeDaemonConnectorException e) { + Slog.w(TAG, "Failed to forget key for " + partGuid + ": " + e); + } + } + @Override public void setDebugFlags(int flags, int mask) { enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java index 78c7f385a1b6..e7979e4310b0 100644 --- a/services/core/java/com/android/server/NativeDaemonConnector.java +++ b/services/core/java/com/android/server/NativeDaemonConnector.java @@ -421,7 +421,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo event = mResponseQueue.remove(sequenceNumber, timeout, logCmd); if (event == null) { loge("timed-out waiting for response to " + logCmd); - throw new NativeDaemonFailureException(logCmd, event); + throw new NativeDaemonTimeoutException(logCmd, event); } if (VDBG) log("RMV <- {" + event + "}"); events.add(event); diff --git a/services/core/java/com/android/server/NativeDaemonTimeoutException.java b/services/core/java/com/android/server/NativeDaemonTimeoutException.java new file mode 100644 index 000000000000..658f7d6264eb --- /dev/null +++ b/services/core/java/com/android/server/NativeDaemonTimeoutException.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015 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; + +/** + * An exception that indicates there was a timeout with a + * {@link NativeDaemonConnector} operation. + */ +public class NativeDaemonTimeoutException extends NativeDaemonConnectorException { + public NativeDaemonTimeoutException(String command, NativeDaemonEvent event) { + super(command, event); + } +} + diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index baa55e721a28..7afb192794f0 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -214,9 +214,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub */ @GuardedBy("mQuotaLock") private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); - - private boolean mStandbyChainEnabled = false; - private boolean mDozableChainEnabled = false; + /** Set of states for the child firewall chains. True if the chain is active. */ + @GuardedBy("mQuotaLock") + final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); private Object mIdleTimerLock = new Object(); /** Set of interfaces with active idle timers. */ @@ -307,9 +307,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } public void systemReady() { - // init firewall states - mDozableChainEnabled = false; - mStandbyChainEnabled = true; prepareNativeDaemon(); if (DBG) Slog.d(TAG, "Prepared"); } @@ -611,7 +608,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } - if (mStandbyChainEnabled) { + if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)) { setFirewallChainEnabled(FIREWALL_CHAIN_STANDBY, true); } @@ -625,7 +622,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub uidFirewallRules.valueAt(i)); } } - if (mDozableChainEnabled) { + if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)) { setFirewallChainEnabled(FIREWALL_CHAIN_DOZABLE, true); } } @@ -2013,24 +2010,31 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallChainEnabled(int chain, boolean enable) { enforceSystemUid(); - final String operation = enable ? "enable_chain" : "disable_chain"; - try { - String chainName; - switch(chain) { - case FIREWALL_CHAIN_STANDBY: - chainName = FIREWALL_CHAIN_NAME_STANDBY; - mStandbyChainEnabled = enable; - break; - case FIREWALL_CHAIN_DOZABLE: - chainName = FIREWALL_CHAIN_NAME_DOZABLE; - mDozableChainEnabled = enable; - break; - default: - throw new IllegalArgumentException("Bad child chain: " + chain); + synchronized (mQuotaLock) { + if (mFirewallChainStates.indexOfKey(chain) >= 0 && + mFirewallChainStates.get(chain) == enable) { + // All is the same, nothing to do. + return; + } + mFirewallChainStates.put(chain, enable); + + final String operation = enable ? "enable_chain" : "disable_chain"; + try { + String chainName; + switch(chain) { + case FIREWALL_CHAIN_STANDBY: + chainName = FIREWALL_CHAIN_NAME_STANDBY; + break; + case FIREWALL_CHAIN_DOZABLE: + chainName = FIREWALL_CHAIN_NAME_DOZABLE; + break; + default: + throw new IllegalArgumentException("Bad child chain: " + chain); + } + mConnector.execute("firewall", operation, chainName); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); } - mConnector.execute("firewall", operation, chainName); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); } } @@ -2048,27 +2052,29 @@ public class NetworkManagementService extends INetworkManagementService.Stub @Override public void setFirewallUidRules(int chain, int[] uids, int[] rules) { enforceSystemUid(); - SparseIntArray uidFirewallRules = getUidFirewallRules(chain); - SparseIntArray newRules = new SparseIntArray(); - // apply new set of rules - for (int index = uids.length - 1; index >= 0; --index) { - int uid = uids[index]; - int rule = rules[index]; - setFirewallUidRule(chain, uid, rule); - newRules.put(uid, rule); - } - // collect the rules to remove. - SparseIntArray rulesToRemove = new SparseIntArray(); - for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { - int uid = uidFirewallRules.keyAt(index); - if (newRules.indexOfKey(uid) < 0) { - rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); + synchronized (mQuotaLock) { + SparseIntArray uidFirewallRules = getUidFirewallRules(chain); + SparseIntArray newRules = new SparseIntArray(); + // apply new set of rules + for (int index = uids.length - 1; index >= 0; --index) { + int uid = uids[index]; + int rule = rules[index]; + setFirewallUidRule(chain, uid, rule); + newRules.put(uid, rule); + } + // collect the rules to remove. + SparseIntArray rulesToRemove = new SparseIntArray(); + for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { + int uid = uidFirewallRules.keyAt(index); + if (newRules.indexOfKey(uid) < 0) { + rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); + } + } + // remove dead rules + for (int index = rulesToRemove.size() - 1; index >= 0; --index) { + int uid = rulesToRemove.keyAt(index); + setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT); } - } - // remove dead rules - for (int index = rulesToRemove.size() - 1; index >= 0; --index) { - int uid = rulesToRemove.keyAt(index); - setFirewallUidRuleInternal(chain, uid, FIREWALL_RULE_DEFAULT); } } @@ -2094,34 +2100,43 @@ public class NetworkManagementService extends INetworkManagementService.Stub } try { - String ruleName; - if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { - if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { - ruleName = "allow"; - } else { - ruleName = "deny"; - } - } else { // Blacklist mode - if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) { - ruleName = "deny"; - } else { - ruleName = "allow"; - } - } + String ruleName = getFirewallRuleName(chain, rule); + String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { uidFirewallRules.delete(uid); } else { uidFirewallRules.put(uid, rule); } - mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, - ruleName); + + if (!ruleName.equals(oldRuleName)) { + mConnector.execute("firewall", "set_uid_rule", getFirewallChainName(chain), uid, + ruleName); + } } catch (NativeDaemonConnectorException e) { throw e.rethrowAsParcelableException(); } } } + private @NonNull String getFirewallRuleName(int chain, int rule) { + String ruleName; + if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) { + if (rule == NetworkPolicyManager.FIREWALL_RULE_ALLOW) { + ruleName = "allow"; + } else { + ruleName = "deny"; + } + } else { // Blacklist mode + if (rule == NetworkPolicyManager.FIREWALL_RULE_DENY) { + ruleName = "deny"; + } else { + ruleName = "allow"; + } + } + return ruleName; + } + private @NonNull SparseIntArray getUidFirewallRules(int chain) { switch (chain) { case FIREWALL_CHAIN_STANDBY: @@ -2272,7 +2287,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } - pw.println("UID firewall standby chain enabled: " + mStandbyChainEnabled); + pw.println("UID firewall standby chain enabled: " + + mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)); synchronized (mUidFirewallStandbyRules) { pw.print("UID firewall standby rule: ["); final int size = mUidFirewallStandbyRules.size(); @@ -2285,7 +2301,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub pw.println("]"); } - pw.println("UID firewall dozable chain enabled: " + mDozableChainEnabled); + pw.println("UID firewall dozable chain enabled: " + + mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)); synchronized (mUidFirewallDozableRules) { pw.print("UID firewall dozable rule: ["); final int size = mUidFirewallDozableRules.size(); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 3456dbcc6994..50d311ff2748 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -1591,13 +1591,6 @@ public class AccountManagerService try { final ContentValues values = new ContentValues(); values.put(ACCOUNTS_PASSWORD, password); - long time = 0; - // Only set current time, if it is a valid password. For clear password case, it - // should not be set. - if (password != null) { - time = System.currentTimeMillis(); - } - values.put(ACCOUNTS_LAST_AUTHENTICATE_TIME_EPOCH_MILLIS, time); final long accountId = getAccountIdLocked(db, account); if (accountId >= 0) { final String[] argsAccountId = {String.valueOf(accountId)}; @@ -2130,7 +2123,7 @@ public class AccountManagerService try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */, null /* accountName */, - false /* authDetailsRequired */) { + false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, @@ -2207,7 +2200,7 @@ public class AccountManagerService try { new Session(accounts, response, accountType, expectActivityLaunch, true /* stripAuthTokenFromResult */, null /* accountName */, - false /* authDetailsRequired */) { + false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) { @Override public void run() throws RemoteException { mAuthenticator.addAccount(this, mAccountType, authTokenType, requiredFeatures, @@ -2940,14 +2933,14 @@ public class AccountManagerService if (result != null) { boolean isSuccessfulConfirmCreds = result.getBoolean( AccountManager.KEY_BOOLEAN_RESULT, false); - boolean isSuccessfulUpdateCreds = + boolean isSuccessfulUpdateCredsOrAddAccount = result.containsKey(AccountManager.KEY_ACCOUNT_NAME) && result.containsKey(AccountManager.KEY_ACCOUNT_TYPE); // We should only update lastAuthenticated time, if // mUpdateLastAuthenticatedTime is true and the confirmRequest // or updateRequest was successful boolean needUpdate = mUpdateLastAuthenticatedTime - && (isSuccessfulConfirmCreds || isSuccessfulUpdateCreds); + && (isSuccessfulConfirmCreds || isSuccessfulUpdateCredsOrAddAccount); if (needUpdate || mAuthDetailsRequired) { boolean accountPresent = isAccountPresentForCaller(mAccountName, mAccountType); if (needUpdate && accountPresent) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 030163829059..1ef1375b1cac 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10779,15 +10779,21 @@ public final class ActivityManagerService extends ActivityManagerNative return; } } - pae.intent.replaceExtras(pae.extras); - pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_SINGLE_TOP - | Intent.FLAG_ACTIVITY_CLEAR_TOP); - closeSystemDialogs("assist"); + + long ident = Binder.clearCallingIdentity(); try { - mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); - } catch (ActivityNotFoundException e) { - Slog.w(TAG, "No activity to handle assist action.", e); + pae.intent.replaceExtras(pae.extras); + pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_SINGLE_TOP + | Intent.FLAG_ACTIVITY_CLEAR_TOP); + closeSystemDialogs("assist"); + try { + mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); + } catch (ActivityNotFoundException e) { + Slog.w(TAG, "No activity to handle assist action.", e); + } + } finally { + Binder.restoreCallingIdentity(ident); } } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 3854e5160fc6..78557634c636 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -38,6 +38,7 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.WorkSource; +import android.telephony.DataConnectionRealTimeInfo; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.util.Slog; @@ -629,7 +630,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub // Collect data now for the past activity. synchronized (mStats) { if (mStats.isOnBattery()) { - mHandler.scheduleWifiSync("wifi-data"); + final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH || + powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active" + : "inactive"; + mHandler.scheduleWifiSync("wifi-data: " + type); } mStats.noteWifiRadioPowerState(powerState, tsNanos); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 47d3bde7a5e1..0dc4076b067d 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -3099,10 +3099,13 @@ public class AudioService extends IAudioService.Stub { || mContext.getResources().getBoolean( com.android.internal.R.bool.config_safe_media_volume_enabled); + boolean safeMediaVolumeBypass = + SystemProperties.getBoolean("audio.safemedia.bypass", false); + // The persisted state is either "disabled" or "active": this is the state applied // next time we boot and cannot be "inactive" int persistedState; - if (safeMediaVolumeEnabled) { + if (safeMediaVolumeEnabled && !safeMediaVolumeBypass) { persistedState = SAFE_MEDIA_VOLUME_ACTIVE; // The state can already be "inactive" here if the user has forced it before // the 30 seconds timeout for forced configuration. In this case we don't reset diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java index 9347c241bb4e..0be24f4c10ea 100644 --- a/services/core/java/com/android/server/camera/CameraService.java +++ b/services/core/java/com/android/server/camera/CameraService.java @@ -16,7 +16,10 @@ package com.android.server.camera; import android.app.ActivityManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.UserInfo; import android.hardware.ICameraService; import android.hardware.ICameraServiceProxy; @@ -67,6 +70,32 @@ public class CameraService extends SystemService implements Handler.Callback { private final Object mLock = new Object(); private Set<Integer> mEnabledCameraUsers; + private int mLastUser; + + private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action == null) return; + + switch (action) { + case Intent.ACTION_USER_ADDED: + case Intent.ACTION_USER_REMOVED: + case Intent.ACTION_USER_INFO_CHANGED: + case Intent.ACTION_MANAGED_PROFILE_ADDED: + case Intent.ACTION_MANAGED_PROFILE_REMOVED: + synchronized(mLock) { + // Return immediately if we haven't seen any users start yet + if (mEnabledCameraUsers == null) return; + switchUserLocked(mLastUser); + } + break; + default: + break; // do nothing + } + + } + }; private final ICameraServiceProxy.Stub mCameraServiceProxy = new ICameraServiceProxy.Stub() { @Override @@ -103,6 +132,15 @@ public class CameraService extends SystemService implements Handler.Callback { // Should never see this unless someone messes up the SystemServer service boot order. throw new IllegalStateException("UserManagerService must start before CameraService!"); } + + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_USER_ADDED); + filter.addAction(Intent.ACTION_USER_REMOVED); + filter.addAction(Intent.ACTION_USER_INFO_CHANGED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); + mContext.registerReceiver(mIntentReceiver, filter); + publishBinderService(CAMERA_SERVICE_PROXY_BINDER_NAME, mCameraServiceProxy); } @@ -125,6 +163,7 @@ public class CameraService extends SystemService implements Handler.Callback { private void switchUserLocked(int userHandle) { Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle); + mLastUser = userHandle; if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) { // Some user handles have been added or removed, update mediaserver. mEnabledCameraUsers = currentUserHandles; diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 3bf118338274..51c6628d1ff3 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -45,6 +45,7 @@ public class NetworkAgentInfo { // This Network object is always valid. public final Network network; public LinkProperties linkProperties; + // This should only be modified via ConnectivityService.updateCapabilities(). public NetworkCapabilities networkCapabilities; public final NetworkMonitor networkMonitor; public final NetworkMisc networkMisc; @@ -66,7 +67,10 @@ public class NetworkAgentInfo { // Whether a captive portal was ever detected on this network. // This is a sticky bit; once set it is never cleared. - public boolean captivePortalDetected; + public boolean everCaptivePortalDetected; + + // Whether a captive portal was found during the last network validation attempt. + public boolean lastCaptivePortalDetected; // This represents the last score received from the NetworkAgent. private int currentScore; @@ -174,7 +178,8 @@ public class NetworkAgentInfo { "created{" + created + "} " + "explicitlySelected{" + networkMisc.explicitlySelected + "} " + "acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " + - "captivePortalDetected{" + captivePortalDetected + "} " + + "everCaptivePortalDetected{" + everCaptivePortalDetected + "} " + + "lastCaptivePortalDetected{" + lastCaptivePortalDetected + "} " + "}"; } diff --git a/services/core/java/com/android/server/content/AppIdleMonitor.java b/services/core/java/com/android/server/content/AppIdleMonitor.java index 9598de8e5c24..fe5c2da4c6d1 100644 --- a/services/core/java/com/android/server/content/AppIdleMonitor.java +++ b/services/core/java/com/android/server/content/AppIdleMonitor.java @@ -18,11 +18,6 @@ package com.android.server.content; import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.BatteryManager; import android.os.UserHandle; import com.android.server.LocalServices; @@ -31,53 +26,32 @@ import com.android.server.LocalServices; * Helper to listen for app idle and charging status changes and restart backed off * sync operations. */ -class AppIdleMonitor implements AppIdleStateChangeListener { +class AppIdleMonitor extends AppIdleStateChangeListener { private final SyncManager mSyncManager; private final UsageStatsManagerInternal mUsageStats; - final BatteryManager mBatteryManager; - /** Is the device currently plugged into power. */ - private boolean mPluggedIn; + private boolean mAppIdleParoleOn; - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - onPluggedIn(mBatteryManager.isCharging()); - } - }; - - AppIdleMonitor(SyncManager syncManager, Context context) { + AppIdleMonitor(SyncManager syncManager) { mSyncManager = syncManager; mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); - mUsageStats.addAppIdleStateChangeListener(this); - mBatteryManager = context.getSystemService(BatteryManager.class); - mPluggedIn = isPowered(); - registerReceivers(context); - } - - private void registerReceivers(Context context) { - // Monitor battery charging state - IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); - filter.addAction(BatteryManager.ACTION_DISCHARGING); - context.registerReceiver(mReceiver, filter); - } + mAppIdleParoleOn = mUsageStats.isAppIdleParoleOn(); - private boolean isPowered() { - return mBatteryManager.isCharging(); + mUsageStats.addAppIdleStateChangeListener(this); } - void onPluggedIn(boolean pluggedIn) { - if (mPluggedIn == pluggedIn) { + void setAppIdleParoleOn(boolean appIdleParoleOn) { + if (mAppIdleParoleOn == appIdleParoleOn) { return; } - mPluggedIn = pluggedIn; - if (mPluggedIn) { + mAppIdleParoleOn = appIdleParoleOn; + if (mAppIdleParoleOn) { mSyncManager.onAppNotIdle(null, UserHandle.USER_ALL); } } boolean isAppIdle(String packageName, int userId) { - return !mPluggedIn && mUsageStats.isAppIdle(packageName, userId); + return !mAppIdleParoleOn && mUsageStats.isAppIdle(packageName, userId); } @Override @@ -86,4 +60,9 @@ class AppIdleMonitor implements AppIdleStateChangeListener { if (idle) return; mSyncManager.onAppNotIdle(packageName, userId); } + + @Override + public void onParoleStateChanged(boolean isParoleOn) { + setAppIdleParoleOn(isParoleOn); + } } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index cd9c7fe0b9bb..658f6f858acc 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -19,6 +19,7 @@ package com.android.server.content; import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.AppGlobals; @@ -55,6 +56,7 @@ import android.content.pm.UserInfo; import android.database.ContentObserver; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.net.TrafficStats; import android.os.BatteryStats; import android.os.Bundle; import android.os.Handler; @@ -100,7 +102,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Random; @@ -162,6 +163,19 @@ public class SyncManager { private static final long ACTIVE_SYNC_TIMEOUT_MILLIS = 30L * 60 * 1000; // 30 mins /** + * How often to periodically poll network traffic for an adapter performing a sync to determine + * whether progress is being made. + */ + private static final long SYNC_MONITOR_WINDOW_LENGTH_MILLIS = 60 * 1000; // 60 seconds + + /** + * How many bytes must be transferred (Tx + Rx) over the period of time defined by + * {@link #SYNC_MONITOR_WINDOW_LENGTH_MILLIS} for the sync to be considered to be making + * progress. + */ + private static final int SYNC_MONITOR_PROGRESS_THRESHOLD_BYTES = 10; // 10 bytes + + /** * How long to delay each queued {@link SyncHandler} message that may have occurred before boot * or befor the device became provisioned. */ @@ -448,7 +462,7 @@ public class SyncManager { mSyncAlarmIntent = PendingIntent.getBroadcast( mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0); - mAppIdleMonitor = new AppIdleMonitor(this, mContext); + mAppIdleMonitor = new AppIdleMonitor(this); IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); context.registerReceiver(mConnectivityIntentReceiver, intentFilter); @@ -957,20 +971,42 @@ public class SyncManager { } /** - * Remove any time-outs previously posted for the provided active sync. + * Post a delayed message that will monitor the given sync context by periodically checking how + * much network has been used by the uid. */ - private void removeSyncExpiryMessage(ActiveSyncContext activeSyncContext) { + private void postMonitorSyncProgressMessage(ActiveSyncContext activeSyncContext) { if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "removing all MESSAGE_SYNC_EXPIRED for " + activeSyncContext.toString()); - } - mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext); + Log.v(TAG, "posting MESSAGE_SYNC_MONITOR in " + + (SYNC_MONITOR_WINDOW_LENGTH_MILLIS/1000) + "s"); + } + + activeSyncContext.mBytesTransferredAtLastPoll = + getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid); + activeSyncContext.mLastPolledTimeElapsed = SystemClock.elapsedRealtime(); + Message monitorMessage = + mSyncHandler.obtainMessage( + SyncHandler.MESSAGE_MONITOR_SYNC, + activeSyncContext); + mSyncHandler.sendMessageDelayed(monitorMessage, SYNC_MONITOR_WINDOW_LENGTH_MILLIS); } + /** + * Monitor sync progress by calculating how many bytes it is managing to send to and fro. + */ + private long getTotalBytesTransferredByUid(int uid) { + return (TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid)); + } + + /** + * Convenience class for passing parameters for a finished or cancelled sync to the handler + * to be processed. + */ class SyncHandlerMessagePayload { public final ActiveSyncContext activeSyncContext; public final SyncResult syncResult; - SyncHandlerMessagePayload(ActiveSyncContext syncContext, SyncResult syncResult) { + SyncHandlerMessagePayload(ActiveSyncContext syncContext, + SyncResult syncResult) { this.activeSyncContext = syncContext; this.syncResult = syncResult; } @@ -1236,7 +1272,7 @@ public class SyncManager { * @param userId The user for which the package has become active. Can be USER_ALL if * the device just plugged in. */ - void onAppNotIdle(String packageName, int userId) { + void onAppNotIdle(@Nullable String packageName, int userId) { synchronized (mSyncQueue) { // For all sync operations in sync queue, if marked as idle, compare with package name // and unmark. And clear backoff for the operation. @@ -1277,6 +1313,14 @@ public class SyncManager { boolean mIsLinkedToDeath = false; String mEventName; + /** Total bytes transferred, counted at {@link #mLastPolledTimeElapsed} */ + long mBytesTransferredAtLastPoll; + /** + * Last point in {@link SystemClock#elapsedRealtime()} at which we checked the # of bytes + * transferred to/fro by this adapter. + */ + long mLastPolledTimeElapsed; + /** * Create an ActiveSyncContext for an impending sync and grab the wakelock for that * sync adapter. Since this grabs the wakelock you need to be sure to call @@ -2048,8 +2092,16 @@ public class SyncManager { private static final int MESSAGE_SERVICE_CONNECTED = 4; private static final int MESSAGE_SERVICE_DISCONNECTED = 5; private static final int MESSAGE_CANCEL = 6; - /** Posted delayed in order to expire syncs that are long-running. */ + /** + * Posted delayed in order to expire syncs that are long-running. + * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext} + */ private static final int MESSAGE_SYNC_EXPIRED = 7; + /** + * Posted periodically to monitor network process for long-running syncs. + * obj: {@link com.android.server.content.SyncManager.ActiveSyncContext} + */ + private static final int MESSAGE_MONITOR_SYNC = 8; public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo(); private Long mAlarmScheduleTime = null; @@ -2167,28 +2219,16 @@ public class SyncManager { // to also take into account the periodic syncs. earliestFuturePollTime = scheduleReadyPeriodicSyncs(); switch (msg.what) { - case SyncHandler.MESSAGE_SYNC_EXPIRED: - ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj; - if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED: expiring " - + expiredContext); - } - cancelActiveSync(expiredContext.mSyncOperation.target, - expiredContext.mSyncOperation.extras); - nextPendingSyncTime = maybeStartNextSyncH(); - break; - - case SyncHandler.MESSAGE_CANCEL: { - SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj; + case SyncHandler.MESSAGE_CANCEL: + SyncStorageEngine.EndPoint endpoint = (SyncStorageEngine.EndPoint) msg.obj; Bundle extras = msg.peekData(); if (Log.isLoggable(TAG, Log.DEBUG)) { - Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: " - + payload + " bundle: " + extras); + Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_CANCEL: " + + endpoint + " bundle: " + extras); } - cancelActiveSyncLocked(payload, extras); + cancelActiveSyncH(endpoint, extras); nextPendingSyncTime = maybeStartNextSyncH(); break; - } case SyncHandler.MESSAGE_SYNC_FINISHED: if (Log.isLoggable(TAG, Log.VERBOSE)) { @@ -2254,7 +2294,6 @@ public class SyncManager { // since a sync just finished check if it is time to start a new sync nextPendingSyncTime = maybeStartNextSyncH(); } - break; } @@ -2278,6 +2317,36 @@ public class SyncManager { } nextPendingSyncTime = maybeStartNextSyncH(); break; + case SyncHandler.MESSAGE_SYNC_EXPIRED: + ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj; + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED:" + + " cancelling " + expiredContext); + } + runSyncFinishedOrCanceledH( + null /* cancel => no result */, + expiredContext); + nextPendingSyncTime = maybeStartNextSyncH(); + break; + case SyncHandler.MESSAGE_MONITOR_SYNC: + ActiveSyncContext monitoredSyncContext = (ActiveSyncContext) msg.obj; + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_MONITOR_SYNC: " + + monitoredSyncContext.mSyncOperation.target); + } + + if (isSyncNotUsingNetworkH(monitoredSyncContext)) { + Log.w(TAG, String.format( + "Detected sync making no progress for %s. cancelling.", + monitoredSyncContext)); + runSyncFinishedOrCanceledH( + null /* cancel => no result */, monitoredSyncContext); + } else { + // Repost message to check again. + postMonitorSyncProgressMessage(monitoredSyncContext); + } + break; + } } finally { manageSyncNotificationLocked(); @@ -2699,6 +2768,30 @@ public class SyncManager { return nextReadyToRunTime; } + private boolean isSyncNotUsingNetworkH(ActiveSyncContext activeSyncContext) { + final long bytesTransferredCurrent = + getTotalBytesTransferredByUid(activeSyncContext.mSyncAdapterUid); + final long deltaBytesTransferred = + bytesTransferredCurrent - activeSyncContext.mBytesTransferredAtLastPoll; + + if (Log.isLoggable(TAG, Log.DEBUG)) { + // Bytes transferred + long remainder = deltaBytesTransferred; + long mb = remainder / (1024 * 1024); + remainder %= 1024 * 1024; + long kb = remainder / 1024; + remainder %= 1024; + long b = remainder; + Log.d(TAG, String.format( + "Time since last update: %ds. Delta transferred: %dMBs,%dKBs,%dBs", + (SystemClock.elapsedRealtime() + - activeSyncContext.mLastPolledTimeElapsed)/1000, + mb, kb, b) + ); + } + return (deltaBytesTransferred <= SYNC_MONITOR_PROGRESS_THRESHOLD_BYTES); + } + /** * Determine if a sync is no longer valid and should be dropped from the sync queue and its * pending op deleted. @@ -2849,18 +2942,22 @@ public class SyncManager { } ActiveSyncContext activeSyncContext = new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid); + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext); + } + activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext); mActiveSyncContexts.add(activeSyncContext); - if (!activeSyncContext.mSyncOperation.isInitialization() && - !activeSyncContext.mSyncOperation.isExpedited() && + // Post message to cancel this sync if it runs for too long. + if (!activeSyncContext.mSyncOperation.isExpedited() && !activeSyncContext.mSyncOperation.isManual() && !activeSyncContext.mSyncOperation.isIgnoreSettings()) { - // Post message to expire this sync if it runs for too long. postSyncExpiryMessage(activeSyncContext); } - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext); - } + + // Post message to begin monitoring this sync's progress. + postMonitorSyncProgressMessage(activeSyncContext); + if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) { Log.e(TAG, "Bind attempt failed - target: " + targetComponent); closeActiveSyncContext(activeSyncContext); @@ -2902,9 +2999,10 @@ public class SyncManager { /** * Cancel the sync for the provided target that matches the given bundle. - * @param info can have null fields to indicate all the active syncs for that field. + * @param info Can have null fields to indicate all the active syncs for that field. + * @param extras Can be null to indicate <strong>all</strong> syncs for the given endpoint. */ - private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) { + private void cancelActiveSyncH(SyncStorageEngine.EndPoint info, Bundle extras) { ArrayList<ActiveSyncContext> activeSyncs = new ArrayList<ActiveSyncContext>(mActiveSyncContexts); for (ActiveSyncContext activeSyncContext : activeSyncs) { @@ -2920,8 +3018,7 @@ public class SyncManager { false /* no config settings */)) { continue; } - runSyncFinishedOrCanceledH(null /* no result since this is a cancel */, - activeSyncContext); + runSyncFinishedOrCanceledH(null /* cancel => no result */, activeSyncContext); } } } @@ -3034,7 +3131,13 @@ public class SyncManager { mActiveSyncContexts.remove(activeSyncContext); mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo, activeSyncContext.mSyncOperation.target.userId); - removeSyncExpiryMessage(activeSyncContext); + + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "removing all MESSAGE_MONITOR_SYNC & MESSAGE_SYNC_EXPIRED for " + + activeSyncContext.toString()); + } + mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext); + mSyncHandler.removeMessages(SyncHandler.MESSAGE_MONITOR_SYNC, activeSyncContext); } /** diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index 35fbef6d289f..8d2687ba9db9 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -231,6 +231,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // The elapsed real time when the screen on was blocked. private long mScreenOnBlockStartRealTime; + // True if we told the window manager policy that the screen was off. + private boolean mReportedScreenOffToPolicy; + // Remembers whether certain kinds of brightness adjustments // were recently applied so that we can decide how to transition. private boolean mAppliedAutoBrightness; @@ -764,24 +767,30 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } catch (RemoteException ex) { // same process } + } - // Tell the window manager what's happening. - // Temporarily block turning the screen on until the window manager is ready - // by leaving a black surface covering the screen. This surface is essentially - // the final state of the color fade animation. - boolean isOn = (state != Display.STATE_OFF); - if (wasOn && !isOn) { + // Tell the window manager policy when the screen is turned off or on unless it's due + // to the proximity sensor. We temporarily block turning the screen on until the + // window manager is ready by leaving a black surface covering the screen. + // This surface is essentially the final state of the color fade animation and + // it is only removed once the window manager tells us that the activity has + // finished drawing underneath. + final boolean isOff = (state == Display.STATE_OFF); + if (isOff && !mReportedScreenOffToPolicy && !mScreenOffBecauseOfProximity) { + mReportedScreenOffToPolicy = true; + unblockScreenOn(); + mWindowManagerPolicy.screenTurnedOff(); + } else if (!isOff && mReportedScreenOffToPolicy) { + mReportedScreenOffToPolicy = false; + if (mPowerState.getColorFadeLevel() == 0.0f) { + blockScreenOn(); + } else { unblockScreenOn(); - mWindowManagerPolicy.screenTurnedOff(); - } else if (!wasOn && isOn) { - if (mPowerState.getColorFadeLevel() == 0.0f) { - blockScreenOn(); - } else { - unblockScreenOn(); - } - mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); } + mWindowManagerPolicy.screenTurningOn(mPendingScreenOnUnblocker); } + + // Return true if the screen isn't blocked. return mPendingScreenOnUnblocker == null; } @@ -1086,6 +1095,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mAppliedLowPower=" + mAppliedLowPower); pw.println(" mPendingScreenOnUnblocker=" + mPendingScreenOnUnblocker); pw.println(" mPendingScreenOff=" + mPendingScreenOff); + pw.println(" mReportedScreenOffToPolicy=" + mReportedScreenOffToPolicy); pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" + mScreenBrightnessRampAnimator.isAnimating()); diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java index 98fb11b6aef2..02d4f4034244 100644 --- a/services/core/java/com/android/server/job/controllers/AppIdleController.java +++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java @@ -17,12 +17,7 @@ package com.android.server.job.controllers; import android.app.usage.UsageStatsManagerInternal; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.BatteryManager; -import android.os.BatteryManagerInternal; import android.util.Slog; import com.android.server.LocalServices; @@ -38,8 +33,7 @@ import java.util.ArrayList; * for a certain amount of time (maybe hours or days) are considered idle. When the app comes * out of idle state, it will be allowed to run scheduled jobs. */ -public class AppIdleController extends StateController - implements UsageStatsManagerInternal.AppIdleStateChangeListener { +public class AppIdleController extends StateController { private static final String LOG_TAG = "AppIdleController"; private static final boolean DEBUG = false; @@ -49,14 +43,7 @@ public class AppIdleController extends StateController private static volatile AppIdleController sController; final ArrayList<JobStatus> mTrackedTasks = new ArrayList<JobStatus>(); private final UsageStatsManagerInternal mUsageStatsInternal; - private final BatteryManager mBatteryManager; - private boolean mPluggedIn; - - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - onPluggedIn(mBatteryManager.isCharging()); - } - }; + boolean mAppIdleParoleOn; public static AppIdleController get(JobSchedulerService service) { synchronized (sCreationLock) { @@ -70,17 +57,8 @@ public class AppIdleController extends StateController private AppIdleController(StateChangedListener stateChangedListener, Context context) { super(stateChangedListener, context); mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class); - mBatteryManager = context.getSystemService(BatteryManager.class); - mPluggedIn = mBatteryManager.isCharging(); - mUsageStatsInternal.addAppIdleStateChangeListener(this); - registerReceivers(); - } - - private void registerReceivers() { - // Monitor battery charging state - IntentFilter filter = new IntentFilter(BatteryManager.ACTION_CHARGING); - filter.addAction(BatteryManager.ACTION_DISCHARGING); - mContext.registerReceiver(mReceiver, filter); + mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn(); + mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); } @Override @@ -88,7 +66,7 @@ public class AppIdleController extends StateController synchronized (mTrackedTasks) { mTrackedTasks.add(jobStatus); String packageName = jobStatus.job.getService().getPackageName(); - final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, + final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, jobStatus.getUserId()); if (DEBUG) { Slog.d(LOG_TAG, "Start tracking, setting idle state of " @@ -108,7 +86,7 @@ public class AppIdleController extends StateController @Override public void dumpControllerState(PrintWriter pw) { pw.println("AppIdle"); - pw.println("Plugged In: " + mPluggedIn); + pw.println("Parole On: " + mAppIdleParoleOn); synchronized (mTrackedTasks) { for (JobStatus task : mTrackedTasks) { pw.print(task.job.getService().getPackageName()); @@ -119,48 +97,20 @@ public class AppIdleController extends StateController } } - @Override - public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { - boolean changed = false; - synchronized (mTrackedTasks) { - // If currently plugged in, we don't care about app idle state - if (mPluggedIn) { - return; - } - for (JobStatus task : mTrackedTasks) { - if (task.job.getService().getPackageName().equals(packageName) - && task.getUserId() == userId) { - if (task.appNotIdleConstraintSatisfied.get() != !idle) { - if (DEBUG) { - Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " - + packageName + " to " + idle); - } - task.appNotIdleConstraintSatisfied.set(!idle); - changed = true; - } - } - } - } - if (changed) { - mStateChangedListener.onControllerStateChanged(); - } - } - - void onPluggedIn(boolean pluggedIn) { + void setAppIdleParoleOn(boolean isAppIdleParoleOn) { // Flag if any app's idle state has changed boolean changed = false; synchronized (mTrackedTasks) { - if (mPluggedIn == pluggedIn) { + if (mAppIdleParoleOn == isAppIdleParoleOn) { return; } - mPluggedIn = pluggedIn; + mAppIdleParoleOn = isAppIdleParoleOn; for (JobStatus task : mTrackedTasks) { String packageName = task.job.getService().getPackageName(); - final boolean appIdle = !mPluggedIn && mUsageStatsInternal.isAppIdle(packageName, + final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName, task.getUserId()); if (DEBUG) { - Slog.d(LOG_TAG, "Plugged in " + pluggedIn + ", setting idle state of " - + packageName + " to " + appIdle); + Slog.d(LOG_TAG, "Setting idle state of " + packageName + " to " + appIdle); } if (task.appNotIdleConstraintSatisfied.get() == appIdle) { task.appNotIdleConstraintSatisfied.set(!appIdle); @@ -172,4 +122,41 @@ public class AppIdleController extends StateController mStateChangedListener.onControllerStateChanged(); } } + + private class AppIdleStateChangeListener + extends UsageStatsManagerInternal.AppIdleStateChangeListener { + @Override + public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { + boolean changed = false; + synchronized (mTrackedTasks) { + if (mAppIdleParoleOn) { + return; + } + for (JobStatus task : mTrackedTasks) { + if (task.job.getService().getPackageName().equals(packageName) + && task.getUserId() == userId) { + if (task.appNotIdleConstraintSatisfied.get() != !idle) { + if (DEBUG) { + Slog.d(LOG_TAG, "App Idle state changed, setting idle state of " + + packageName + " to " + idle); + } + task.appNotIdleConstraintSatisfied.set(!idle); + changed = true; + } + } + } + } + if (changed) { + mStateChangedListener.onControllerStateChanged(); + } + } + + @Override + public void onParoleStateChanged(boolean isParoleOn) { + if (DEBUG) { + Slog.d(LOG_TAG, "Parole on: " + isParoleOn); + } + setAppIdleParoleOn(isParoleOn); + } + } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index b0550d664b89..847bcb5d08eb 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -86,7 +86,6 @@ import android.app.IUidObserver; import android.app.Notification; import android.app.PendingIntent; import android.app.usage.UsageStatsManagerInternal; -import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -154,7 +153,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; -import com.android.server.DeviceIdleController; import com.android.server.LocalServices; import com.google.android.collect.Lists; @@ -182,8 +180,7 @@ import java.util.List; * and delivers to listeners, such as {@link ConnectivityManager}, for * enforcement. */ -public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub - implements AppIdleStateChangeListener { +public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final String TAG = "NetworkPolicy"; private static final boolean LOGD = false; private static final boolean LOGV = false; @@ -279,6 +276,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub final SparseIntArray mUidPolicy = new SparseIntArray(); /** Currently derived rules for each UID. */ final SparseIntArray mUidRules = new SparseIntArray(); + /** Set of states for the child firewall chains. True if the chain is active. */ final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); /** @@ -508,7 +506,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub WifiManager.NETWORK_STATE_CHANGED_ACTION); mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler); - mUsageStats.addAppIdleStateChangeListener(this); + mUsageStats.addAppIdleStateChangeListener(new AppIdleStateChangeListener()); } @@ -2043,7 +2041,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules); } - enableFirewallChain(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); + enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); + } + + void updateRulesForAppIdleParoleLocked() { + boolean enableChain = !mUsageStats.isAppIdleParoleOn(); + enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain); } /** @@ -2187,9 +2190,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub final boolean firewallReject = (uidRules & RULE_REJECT_ALL) != 0; if (oldFirewallReject != firewallReject) { setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, firewallReject); - if (mDeviceIdleMode && !firewallReject) { - // if we are in device idle mode, and we decide to allow this uid. we need to punch - // a hole in the device idle chain. + if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE) && !firewallReject) { + // if the dozable chain is on, and we decide to allow this uid. we need to punch + // a hole in the dozable chain. setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, false); } } @@ -2207,15 +2210,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub } } - @Override - public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { - try { - int uid = mContext.getPackageManager().getPackageUid(packageName, userId); + private class AppIdleStateChangeListener + extends UsageStatsManagerInternal.AppIdleStateChangeListener { + + @Override + public void onAppIdleStateChanged(String packageName, int userId, boolean idle) { + try { + int uid = mContext.getPackageManager().getPackageUid(packageName, userId); + synchronized (mRulesLock) { + updateRulesForUidLocked(uid); + } + } catch (NameNotFoundException nnfe) { + } + } + + @Override + public void onParoleStateChanged(boolean isParoleOn) { synchronized (mRulesLock) { - updateRulesForUidLocked(uid); + updateRulesForAppIdleParoleLocked(); } - } catch (NameNotFoundException nnfe) { - return; } } @@ -2381,12 +2394,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub /** * Add or remove a uid to the firewall blacklist for all network ifaces. */ - private void enableFirewallChain(int chain, boolean enable) { + private void enableFirewallChainLocked(int chain, boolean enable) { if (mFirewallChainStates.indexOfKey(chain) >= 0 && mFirewallChainStates.get(chain) == enable) { // All is the same, nothing to do. return; } + mFirewallChainStates.put(chain, enable); try { mNetworkManager.setFirewallChainEnabled(chain, enable); } catch (IllegalStateException e) { diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java index fdb443e1753d..87b4f8cddc15 100644 --- a/services/core/java/com/android/server/notification/NotificationDelegate.java +++ b/services/core/java/com/android/server/notification/NotificationDelegate.java @@ -16,6 +16,8 @@ package com.android.server.notification; +import com.android.internal.statusbar.NotificationVisibility; + public interface NotificationDelegate { void onSetDisabled(int status); void onClearAll(int callingUid, int callingPid, int userId); @@ -30,6 +32,7 @@ public interface NotificationDelegate { void onPanelHidden(); void clearEffects(); void onNotificationVisibilityChanged( - String[] newlyVisibleKeys, String[] noLongerVisibleKeys); + NotificationVisibility[] newlyVisibleKeys, + NotificationVisibility[] noLongerVisibleKeys); void onNotificationExpansionChanged(String key, boolean userAction, boolean expanded); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 0dcad8219ef1..4524ff895428 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -97,6 +97,7 @@ import android.view.accessibility.AccessibilityManager; import android.widget.Toast; import com.android.internal.R; +import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.util.FastXmlSerializer; import com.android.server.EventLogTags; import com.android.server.LocalServices; @@ -622,22 +623,24 @@ public class NotificationManagerService extends SystemService { } @Override - public void onNotificationVisibilityChanged( - String[] newlyVisibleKeys, String[] noLongerVisibleKeys) { + public void onNotificationVisibilityChanged(NotificationVisibility[] newlyVisibleKeys, + NotificationVisibility[] noLongerVisibleKeys) { synchronized (mNotificationList) { - for (String key : newlyVisibleKeys) { - NotificationRecord r = mNotificationsByKey.get(key); + for (NotificationVisibility nv : newlyVisibleKeys) { + NotificationRecord r = mNotificationsByKey.get(nv.key); if (r == null) continue; - r.setVisibility(true); + r.setVisibility(true, nv.rank); + nv.recycle(); } // Note that we might receive this event after notifications // have already left the system, e.g. after dismissing from the // shade. Hence not finding notifications in // mNotificationsByKey is not an exceptional condition. - for (String key : noLongerVisibleKeys) { - NotificationRecord r = mNotificationsByKey.get(key); + for (NotificationVisibility nv : noLongerVisibleKeys) { + NotificationRecord r = mNotificationsByKey.get(nv.key); if (r == null) continue; - r.setVisibility(false); + r.setVisibility(false, nv.rank); + nv.recycle(); } } } diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java index c4773cacf1ca..b7aea9da1d8b 100644 --- a/services/core/java/com/android/server/notification/NotificationRecord.java +++ b/services/core/java/com/android/server/notification/NotificationRecord.java @@ -314,13 +314,15 @@ public final class NotificationRecord { /** * Set the visibility of the notification. */ - public void setVisibility(boolean visible) { + public void setVisibility(boolean visible, int rank) { final long now = System.currentTimeMillis(); mVisibleSinceMs = visible ? now : mVisibleSinceMs; stats.onVisibilityChanged(visible); EventLogTags.writeNotificationVisibility(getKey(), visible ? 1 : 0, (int) (now - mCreationTimeMs), - (int) (now - mUpdateTimeMs)); + (int) (now - mUpdateTimeMs), + 0, // exposure time + rank); } /** diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java index 2d5c1998c1e2..2f0cc0f00d22 100644 --- a/services/core/java/com/android/server/notification/NotificationUsageStats.java +++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java @@ -16,11 +16,13 @@ package com.android.server.notification; +import android.app.Notification; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -57,8 +59,8 @@ public class NotificationUsageStats { private static final boolean DEBUG = false; public static final int TEN_SECONDS = 1000 * 10; - public static final int ONE_HOUR = 1000 * 60 * 60; - private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : ONE_HOUR; + public static final int FOUR_HOURS = 1000 * 60 * 60 * 4; + private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : FOUR_HOURS; // Guarded by synchronized(this). private final Map<String, AggregatedStats> mStats = new HashMap<>(); @@ -98,6 +100,7 @@ public class NotificationUsageStats { AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification); for (AggregatedStats stats : aggregatedStatsArray) { stats.numPostedByApp++; + stats.countApiUse(notification); } releaseAggregatedStatsLocked(aggregatedStatsArray); if (ENABLE_SQLITE_LOG) { @@ -113,6 +116,7 @@ public class NotificationUsageStats { AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification); for (AggregatedStats stats : aggregatedStatsArray) { stats.numUpdatedByApp++; + stats.countApiUse(notification); } releaseAggregatedStatsLocked(aggregatedStatsArray); } @@ -246,6 +250,7 @@ public class NotificationUsageStats { private final Context mContext; public final String key; + private AggregatedStats mPrevious; // ---- Updated as the respective events occur. public int numPostedByApp; @@ -256,14 +261,103 @@ public class NotificationUsageStats { public int numWithStaredPeople; public int numWithValidPeople; public int numBlocked; - - private AggregatedStats mPrevious; + public int numWithActions; + public int numPrivate; + public int numSecret; + public int numPriorityMax; + public int numPriorityHigh; + public int numPriorityLow; + public int numPriorityMin; + public int numWithBigText; + public int numWithBigPicture; + public int numForegroundService; + public int numOngoing; + public int numAutoCancel; + public int numWithLargeIcon; + public int numWithInbox; + public int numWithMediaSession; + public int numWithTitle; + public int numWithText; + public int numWithSubText; + public int numWithInfoText; + public int numInterrupt; public AggregatedStats(Context context, String key) { this.key = key; mContext = context; } + public void countApiUse(NotificationRecord record) { + final Notification n = record.getNotification(); + if (n.actions != null) { + numWithActions++; + } + + if ((n.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { + numForegroundService++; + } + + if ((n.flags & Notification.FLAG_ONGOING_EVENT) != 0) { + numOngoing++; + } + + if ((n.flags & Notification.FLAG_AUTO_CANCEL) != 0) { + numAutoCancel++; + } + + if ((n.defaults & Notification.DEFAULT_SOUND) != 0 || + (n.defaults & Notification.DEFAULT_VIBRATE) != 0 || + n.sound != null || n.vibrate != null) { + numInterrupt++; + } + + switch (n.visibility) { + case Notification.VISIBILITY_PRIVATE: + numPrivate++; + break; + case Notification.VISIBILITY_SECRET: + numSecret++; + break; + } + + switch (n.priority) { + case Notification.PRIORITY_MAX: + numPriorityMax++; + break; + case Notification.PRIORITY_HIGH: + numPriorityHigh++; + break; + case Notification.PRIORITY_LOW: + numPriorityLow++; + break; + case Notification.PRIORITY_MIN: + numPriorityMin++; + break; + } + + for (String Key : n.extras.keySet()) { + if (Notification.EXTRA_BIG_TEXT.equals(key)) { + numWithBigText++; + } else if (Notification.EXTRA_PICTURE.equals(key)) { + numWithBigPicture++; + } else if (Notification.EXTRA_LARGE_ICON.equals(key)) { + numWithLargeIcon++; + } else if (Notification.EXTRA_TEXT_LINES.equals(key)) { + numWithInbox++; + } else if (Notification.EXTRA_MEDIA_SESSION.equals(key)) { + numWithMediaSession++; + } else if (Notification.EXTRA_TITLE.equals(key)) { + numWithTitle++; + } else if (Notification.EXTRA_TEXT.equals(key)) { + numWithText++; + } else if (Notification.EXTRA_SUB_TEXT.equals(key)) { + numWithSubText++; + } else if (Notification.EXTRA_INFO_TEXT.equals(key)) { + numWithInfoText++; + } + } + } + public void emit() { if (mPrevious == null) { mPrevious = new AggregatedStats(null, key); @@ -277,6 +371,26 @@ public class NotificationUsageStats { maybeCount("people_cache_hit", (numPeopleCacheHit - mPrevious.numPeopleCacheHit)); maybeCount("people_cache_miss", (numPeopleCacheMiss - mPrevious.numPeopleCacheMiss)); maybeCount("note_blocked", (numBlocked - mPrevious.numBlocked)); + maybeCount("note_with_actions", (numWithActions - mPrevious.numWithActions)); + maybeCount("note_private", (numPrivate - mPrevious.numPrivate)); + maybeCount("note_secret", (numSecret - mPrevious.numSecret)); + maybeCount("note_prio_max", (numPriorityMax - mPrevious.numPriorityMax)); + maybeCount("note_prio_high", (numPriorityHigh - mPrevious.numPriorityHigh)); + maybeCount("note_prio_low", (numPriorityLow - mPrevious.numPriorityLow)); + maybeCount("note_prio_min", (numPriorityMin - mPrevious.numPriorityMin)); + maybeCount("note_interupt", (numInterrupt - mPrevious.numInterrupt)); + maybeCount("note_big_text", (numWithBigText - mPrevious.numWithBigText)); + maybeCount("note_big_pic", (numWithBigPicture - mPrevious.numWithBigPicture)); + maybeCount("note_fg", (numForegroundService - mPrevious.numForegroundService)); + maybeCount("note_ongoing", (numOngoing - mPrevious.numOngoing)); + maybeCount("note_auto", (numAutoCancel - mPrevious.numAutoCancel)); + maybeCount("note_large_icon", (numWithLargeIcon - mPrevious.numWithLargeIcon)); + maybeCount("note_inbox", (numWithInbox - mPrevious.numWithInbox)); + maybeCount("note_media", (numWithMediaSession - mPrevious.numWithMediaSession)); + maybeCount("note_title", (numWithTitle - mPrevious.numWithTitle)); + maybeCount("note_text", (numWithText - mPrevious.numWithText)); + maybeCount("note_sub_text", (numWithSubText - mPrevious.numWithSubText)); + maybeCount("note_info_text", (numWithInfoText - mPrevious.numWithInfoText)); mPrevious.numPostedByApp = numPostedByApp; mPrevious.numUpdatedByApp = numUpdatedByApp; @@ -286,6 +400,26 @@ public class NotificationUsageStats { mPrevious.numWithStaredPeople = numWithStaredPeople; mPrevious.numWithValidPeople = numWithValidPeople; mPrevious.numBlocked = numBlocked; + mPrevious.numWithActions = numWithActions; + mPrevious.numPrivate = numPrivate; + mPrevious.numSecret = numSecret; + mPrevious.numPriorityMax = numPriorityMax; + mPrevious.numPriorityHigh = numPriorityHigh; + mPrevious.numPriorityLow = numPriorityLow; + mPrevious.numPriorityMin = numPriorityMin; + mPrevious.numInterrupt = numInterrupt; + mPrevious.numWithBigText = numWithBigText; + mPrevious.numWithBigPicture = numWithBigPicture; + mPrevious.numForegroundService = numForegroundService; + mPrevious.numOngoing = numOngoing; + mPrevious.numAutoCancel = numAutoCancel; + mPrevious.numWithLargeIcon = numWithLargeIcon; + mPrevious.numWithInbox = numWithInbox; + mPrevious.numWithMediaSession = numWithMediaSession; + mPrevious.numWithTitle = numWithTitle; + mPrevious.numWithText = numWithText; + mPrevious.numWithSubText = numWithSubText; + mPrevious.numWithInfoText = numWithInfoText; } void maybeCount(String name, int value) { diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index fe3103bcdc69..3ea384c1a05d 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -45,7 +45,7 @@ import static android.os.Process.FIRST_APPLICATION_UID; * have phone related permission by default. */ final class DefaultPermissionGrantPolicy { - private static final String TAG = "DefaultPermissionGrantPolicy"; + private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars private static final boolean DEBUG = false; private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive"; @@ -106,7 +106,7 @@ final class DefaultPermissionGrantPolicy { private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>(); static { -// STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); + STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE); STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } @@ -133,6 +133,7 @@ final class DefaultPermissionGrantPolicy { private PackagesProvider mImePackagesProvider; private PackagesProvider mLocationPackagesProvider; private PackagesProvider mVoiceInteractionPackagesProvider; + private PackagesProvider mCarrierAppPackagesProvider; public DefaultPermissionGrantPolicy(PackageManagerService service) { mService = service; @@ -150,6 +151,10 @@ final class DefaultPermissionGrantPolicy { mVoiceInteractionPackagesProvider = provider; } + public void setCarrierAppPackagesProviderLPw(PackagesProvider provider) { + mCarrierAppPackagesProvider = provider; + } + public void grantDefaultPermissions(int userId) { grantPermissionsToSysComponentsAndPrivApps(userId); grantDefaultSystemHandlerPermissions(userId); @@ -193,11 +198,13 @@ final class DefaultPermissionGrantPolicy { final PackagesProvider imePackagesProvider; final PackagesProvider locationPackagesProvider; final PackagesProvider voiceInteractionPackagesProvider; + final PackagesProvider carrierAppPackagesProvider; synchronized (mService.mPackages) { imePackagesProvider = mImePackagesProvider; locationPackagesProvider = mLocationPackagesProvider; voiceInteractionPackagesProvider = mVoiceInteractionPackagesProvider; + carrierAppPackagesProvider = mCarrierAppPackagesProvider; } String[] imePackageNames = (imePackagesProvider != null) @@ -206,6 +213,8 @@ final class DefaultPermissionGrantPolicy { ? voiceInteractionPackagesProvider.getPackages(userId) : null; String[] locationPackageNames = (locationPackagesProvider != null) ? locationPackagesProvider.getPackages(userId) : null; + String[] carrierAppPackageNames = (carrierAppPackagesProvider != null) + ? carrierAppPackagesProvider.getPackages(userId) : null; synchronized (mService.mPackages) { // Installers @@ -382,6 +391,18 @@ final class DefaultPermissionGrantPolicy { } } } + + // Carrier apps + if (carrierAppPackageNames != null) { + for (String packageName : carrierAppPackageNames) { + PackageParser.Package carrierPackage = getSystemPackageLPr(packageName); + if (carrierPackage != null + && doesPackageSupportRuntimePermissions(carrierPackage)) { + grantRuntimePermissionsLPw(carrierPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(carrierPackage, LOCATION_PERMISSIONS, userId); + } + } + } } } diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java index c09d6ae7ff8b..c6e7911ea2a7 100644 --- a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java +++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java @@ -19,7 +19,7 @@ package com.android.server.pm; import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.util.ArraySet; -import android.util.Log; +import android.util.Slog; import java.util.ArrayList; @@ -113,7 +113,7 @@ public class IntentFilterVerificationState { setState(state); return true; } - Log.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" + + Slog.d(TAG, "Cannot set verifier response with callerUid:" + callerUid + " and code:" + code + " as required verifierUid is:" + mRequiredVerifierUid); return false; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b593906a214d..dbf0f176dd83 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -100,6 +100,7 @@ import android.content.pm.IPackageInstaller; import android.content.pm.IPackageManager; import android.content.pm.IPackageMoveObserver; import android.content.pm.IPackageStatsObserver; +import android.content.pm.IPackagesProvider; import android.content.pm.InstrumentationInfo; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.KeySet; @@ -212,6 +213,7 @@ import com.android.server.pm.PermissionsState.PermissionState; import com.android.server.storage.DeviceStorageMonitorInternal; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; import java.io.BufferedInputStream; @@ -253,14 +255,14 @@ import java.util.concurrent.atomic.AtomicLong; /** * Keep track of all those .apks everywhere. - * + * * This is very central to the platform's security; please run the unit * tests whenever making modifications here: - * + * mmm frameworks/base/tests/AndroidTests adb install -r -f out/target/product/passion/data/app/AndroidTests.apk adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner - * + * * {@hide} */ public class PackageManagerService extends IPackageManager.Stub { @@ -308,6 +310,7 @@ public class PackageManagerService extends IPackageManager.Stub { static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<10; static final int SCAN_REQUIRE_KNOWN = 1<<12; static final int SCAN_MOVE = 1<<13; + static final int SCAN_INITIAL = 1<<14; static final int REMOVE_CHATTY = 1<<16; @@ -508,7 +511,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Packages whose data we have transfered into another package, thus // should no longer exist. final ArraySet<String> mTransferedPackages = new ArraySet<String>(); - + // Broadcast actions that are only available to the system. final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); @@ -556,6 +559,22 @@ public class PackageManagerService extends IPackageManager.Stub { final DefaultPermissionGrantPolicy mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this); + private static class IFVerificationParams { + PackageParser.Package pkg; + boolean replacing; + int userId; + int verifierUid; + + public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing, + int _userId, int _verifierUid) { + pkg = _pkg; + replacing = _replacing; + userId = _userId; + replacing = _replacing; + verifierUid = _verifierUid; + } + } + private interface IntentFilterVerifier<T extends IntentFilter> { boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, T filter, String packageName); @@ -629,7 +648,7 @@ public class PackageManagerService extends IPackageManager.Stub { UserHandle user = new UserHandle(userId); mContext.sendBroadcastAsUser(verificationIntent, user); if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, - "Sending IntenFilter verification broadcast"); + "Sending IntentFilter verification broadcast"); } public void receiveVerificationResponse(int verificationId) { @@ -639,6 +658,10 @@ public class PackageManagerService extends IPackageManager.Stub { ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters(); final int count = filters.size(); + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Received verification response " + verificationId + + " for " + count + " filters, verified=" + verified); + } for (int n=0; n<count; n++) { PackageParser.ActivityIntentInfo filter = filters.get(n); filter.setVerified(verified); @@ -713,30 +736,27 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override - public boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId, + public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId, ActivityIntentInfo filter, String packageName) { - if (!(filter.hasDataScheme(IntentFilter.SCHEME_HTTP) || - filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) { - if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, - "IntentFilter does not contain HTTP nor HTTPS data scheme"); + if (!hasValidDomains(filter)) { return false; } IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId); if (ivs == null) { - ivs = createDomainVerificationState(verifierId, userId, verificationId, + ivs = createDomainVerificationState(verifierUid, userId, verificationId, packageName); } - if (!hasValidDomains(filter)) { - return false; + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Adding verification filter for " + packageName + " : " + filter); } ivs.addFilter(filter); return true; } - private IntentFilterVerificationState createDomainVerificationState(int verifierId, + private IntentFilterVerificationState createDomainVerificationState(int verifierUid, int userId, int verificationId, String packageName) { IntentFilterVerificationState ivs = new IntentFilterVerificationState( - verifierId, userId, packageName); + verifierUid, userId, packageName); ivs.setPendingState(); synchronized (mPackages) { mIntentFilterVerificationStates.append(verificationId, ivs); @@ -888,8 +908,10 @@ public class PackageManagerService extends IPackageManager.Stub { final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>(); int mNextInstallToken = 1; // nonzero; will be wrapped back to 1 when ++ overflows - // backup/restore of preferred activity state + // XML tags for backup/restore of various bits of state private static final String TAG_PREFERRED_BACKUP = "pa"; + private static final String TAG_DEFAULT_APPS = "da"; + private static final String TAG_INTENT_FILTER_VERIFICATION = "iv"; private final String mRequiredVerifierPackage; @@ -1072,7 +1094,7 @@ public class PackageManagerService extends IPackageManager.Stub { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); } } - + void doHandleMessage(Message msg) { switch (msg.what) { case INIT_COPY: { @@ -1507,11 +1529,9 @@ public class PackageManagerService extends IPackageManager.Stub { break; } case START_INTENT_FILTER_VERIFICATIONS: { - int userId = msg.arg1; - int verifierUid = msg.arg2; - PackageParser.Package pkg = (PackageParser.Package)msg.obj; - - verifyIntentFiltersIfNeeded(userId, verifierUid, pkg); + IFVerificationParams params = (IFVerificationParams) msg.obj; + verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, + params.replacing, params.pkg); break; } case INTENT_FILTER_VERIFIED: { @@ -1821,7 +1841,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Set flag to monitor and not change apk file paths when // scanning install directories. - final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; + final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING | SCAN_INITIAL; final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); @@ -2357,8 +2377,7 @@ public class PackageManagerService extends IPackageManager.Stub { final String packageName = getDefaultBrowserPackageName(myUserId); PackageInfo info = getPackageInfo(packageName, 0, myUserId); if (info == null) { - Slog.w(TAG, "Clearing default Browser as its package is no more installed: " + - packageName); + Slog.w(TAG, "Default browser no longer installed: " + packageName); setDefaultBrowserPackageName(null, myUserId); } } @@ -2485,7 +2504,7 @@ public class PackageManagerService extends IPackageManager.Stub { } return out; } - + @Override public String[] canonicalToCurrentPackageNames(String[] names) { String[] out = new String[names.length]; @@ -2555,7 +2574,7 @@ public class PackageManagerService extends IPackageManager.Stub { pi.protectionLevel = bp.protectionLevel; return pi; } - + @Override public PermissionInfo getPermissionInfo(String name, int flags) { // reader @@ -3035,7 +3054,7 @@ public class PackageManagerService extends IPackageManager.Stub { } return s1.equals(s2); } - + static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) { if (pi1.icon != pi2.icon) return false; if (pi1.logo != pi2.logo) return false; @@ -3337,11 +3356,8 @@ public class PackageManagerService extends IPackageManager.Stub { enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "updatePermissionFlags"); - // Only the system can change policy and system fixed flags. + // Only the system can change system fixed flags. if (getCallingUid() != Process.SYSTEM_UID) { - flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; - flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED; - flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; } @@ -3370,18 +3386,63 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null; + if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) { // Install and runtime permissions are stored in different places, // so figure out what permission changed and persist the change. if (permissionsState.getInstallPermissionState(name) != null) { scheduleWriteSettingsLocked(); - } else if (permissionsState.getRuntimePermissionState(name, userId) != null) { + } else if (permissionsState.getRuntimePermissionState(name, userId) != null + || hadState) { mSettings.writeRuntimePermissionsForUserLPr(userId, false); } } } } + /** + * Update the permission flags for all packages and runtime permissions of a user in order + * to allow device or profile owner to remove POLICY_FIXED. + */ + @Override + public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) { + if (!sUserManager.exists(userId)) { + return; + } + + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, + "updatePermissionFlagsForAllApps"); + + enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + "updatePermissionFlagsForAllApps"); + + // Only the system can change system fixed flags. + if (getCallingUid() != Process.SYSTEM_UID) { + flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED; + } + + synchronized (mPackages) { + boolean changed = false; + final int packageCount = mPackages.size(); + for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) { + final PackageParser.Package pkg = mPackages.valueAt(pkgIndex); + SettingBase sb = (SettingBase) pkg.mExtras; + if (sb == null) { + continue; + } + PermissionsState permissionsState = sb.getPermissionsState(); + changed |= permissionsState.updatePermissionFlagsForAllPermissions( + userId, flagMask, flagValues); + } + if (changed) { + mSettings.writeRuntimePermissionsForUserLPr(userId, false); + } + } + } + @Override public boolean shouldShowRequestPermissionRationale(String permissionName, String packageName, int userId) { @@ -4118,9 +4179,26 @@ public class PackageManagerService extends IPackageManager.Stub { if (matches.get(i).getTargetUserId() == targetUserId) return true; } } + if (hasWebURI(intent)) { + // cross-profile app linking works only towards the parent. + final UserInfo parent = getProfileParent(sourceUserId); + synchronized(mPackages) { + return getCrossProfileDomainPreferredLpr(intent, resolvedType, 0, sourceUserId, + parent.id) != null; + } + } return false; } + private UserInfo getProfileParent(int userId) { + final long identity = Binder.clearCallingIdentity(); + try { + return sUserManager.getProfileParent(userId); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent, String resolvedType, int userId) { CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); @@ -4138,7 +4216,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -4161,11 +4239,11 @@ public class PackageManagerService extends IPackageManager.Stub { List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); // Check for results that need to skip the current profile. - ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, + ResolveInfo xpResolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, resolvedType, flags, userId); - if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { + if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); - result.add(resolveInfo); + result.add(xpResolveInfo); return filterIfNotPrimaryUser(result, userId); } @@ -4174,15 +4252,36 @@ public class PackageManagerService extends IPackageManager.Stub { intent, resolvedType, flags, userId); // Check for cross profile results. - resolveInfo = queryCrossProfileIntents( + xpResolveInfo = queryCrossProfileIntents( matchingFilters, intent, resolvedType, flags, userId); - if (resolveInfo != null && isUserEnabled(resolveInfo.targetUserId)) { - result.add(resolveInfo); + if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) { + result.add(xpResolveInfo); Collections.sort(result, mResolvePrioritySorter); } result = filterIfNotPrimaryUser(result, userId); - if (result.size() > 1 && hasWebURI(intent)) { - return filterCandidatesWithDomainPreferedActivitiesLPr(flags, result); + if (hasWebURI(intent)) { + CrossProfileDomainInfo xpDomainInfo = null; + final UserInfo parent = getProfileParent(userId); + if (parent != null) { + xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType, + flags, userId, parent.id); + } + if (xpDomainInfo != null) { + if (xpResolveInfo != null) { + // If we didn't remove it, the cross-profile ResolveInfo would be twice + // in the result. + result.remove(xpResolveInfo); + } + if (result.size() == 0) { + result.add(xpDomainInfo.resolveInfo); + return result; + } + } else if (result.size() <= 1) { + return result; + } + result = filterCandidatesWithDomainPreferredActivitiesLPr(flags, result, + xpDomainInfo); + Collections.sort(result, mResolvePrioritySorter); } return result; } @@ -4197,6 +4296,67 @@ public class PackageManagerService extends IPackageManager.Stub { } } + private static class CrossProfileDomainInfo { + /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */ + ResolveInfo resolveInfo; + /* Best domain verification status of the activities found in the other profile */ + int bestDomainVerificationStatus; + } + + private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent, + String resolvedType, int flags, int sourceUserId, int parentUserId) { + if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_APP_LINKING, + sourceUserId)) { + return null; + } + List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, + resolvedType, flags, parentUserId); + + if (resultTargetUser == null || resultTargetUser.isEmpty()) { + return null; + } + CrossProfileDomainInfo result = null; + int size = resultTargetUser.size(); + for (int i = 0; i < size; i++) { + ResolveInfo riTargetUser = resultTargetUser.get(i); + // Intent filter verification is only for filters that specify a host. So don't return + // those that handle all web uris. + if (riTargetUser.handleAllWebDataURI) { + continue; + } + String packageName = riTargetUser.activityInfo.packageName; + PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps == null) { + continue; + } + int status = getDomainVerificationStatusLPr(ps, parentUserId); + if (result == null) { + result = new CrossProfileDomainInfo(); + result.resolveInfo = + createForwardingResolveInfo(null, sourceUserId, parentUserId); + result.bestDomainVerificationStatus = status; + } else { + result.bestDomainVerificationStatus = bestDomainVerificationStatus(status, + result.bestDomainVerificationStatus); + } + } + return result; + } + + /** + * Verification statuses are ordered from the worse to the best, except for + * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse. + */ + private int bestDomainVerificationStatus(int status1, int status2) { + if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { + return status2; + } + if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { + return status1; + } + return (int) MathUtils.max(status1, status2); + } + private boolean isUserEnabled(int userId) { long callingId = Binder.clearCallingIdentity(); try { @@ -4236,8 +4396,8 @@ public class PackageManagerService extends IPackageManager.Stub { return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS); } - private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr( - int flags, List<ResolveInfo> candidates) { + private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr( + int flags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo) { if (DEBUG_PREFERRED) { Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " + candidates.size()); @@ -4277,12 +4437,23 @@ public class PackageManagerService extends IPackageManager.Stub { } } } - // First try to add the "always" if there is any + // First try to add the "always" resolution for the current user if there is any if (alwaysList.size() > 0) { result.addAll(alwaysList); + // if there is an "always" for the parent user, add it. + } else if (xpDomainInfo != null && xpDomainInfo.bestDomainVerificationStatus + == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) { + result.add(xpDomainInfo.resolveInfo); } else { // Add all undefined Apps as we want them to appear in the Disambiguation dialog. result.addAll(undefinedList); + if (xpDomainInfo != null && ( + xpDomainInfo.bestDomainVerificationStatus + == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED + || xpDomainInfo.bestDomainVerificationStatus + == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) { + result.add(xpDomainInfo.resolveInfo); + } // Also add Browsers (all of them or only the default one) if ((flags & MATCH_ALL) != 0) { result.addAll(matchAllList); @@ -4600,7 +4771,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -4651,7 +4822,7 @@ public class PackageManagerService extends IPackageManager.Stub { ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { - intent = intent.getSelector(); + intent = intent.getSelector(); comp = intent.getComponent(); } } @@ -6078,7 +6249,7 @@ public class PackageManagerService extends IPackageManager.Stub { + "): packages=" + suid.packages); } } - + // Check if we are renaming from an original package name. PackageSetting origPackage = null; String realName = null; @@ -6098,7 +6269,7 @@ public class PackageManagerService extends IPackageManager.Stub { // it is not already done. pkg.setPackageName(renamed); } - + } else { for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) { if ((origPackage = mSettings.peekPackageLPr( @@ -6128,7 +6299,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } } - + if (mTransferedPackages.contains(pkg.packageName)) { Slog.w(TAG, "Package " + pkg.packageName + " was transferred to another, but its .apk remains"); @@ -6153,24 +6324,24 @@ public class PackageManagerService extends IPackageManager.Stub { // looking up the package under its new name, so getPackageLP // can take care of fiddling things correctly. pkg.setPackageName(origPackage.name); - + // File a report about this. String msg = "New package " + pkgSetting.realName + " renamed to replace old package " + pkgSetting.name; reportSettingsProblem(Log.WARN, msg); - + // Make a note of it. mTransferedPackages.add(origPackage.name); - + // No longer need to retain this. pkgSetting.origPackage = null; } - + if (realName != null) { // Make a note of it. mTransferedPackages.add(pkg.packageName); } - + if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; } @@ -6286,7 +6457,7 @@ public class PackageManagerService extends IPackageManager.Stub { } final String pkgName = pkg.packageName; - + final long scanFileTime = scanFile.lastModified(); final boolean forceDex = (scanFlags & SCAN_FORCE_DEX) != 0; pkg.applicationInfo.processName = fixProcessName( @@ -8206,7 +8377,7 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.ActivityIntentInfo info) { return packageName.equals(info.activity.owner.packageName); } - + @Override protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match, int userId) { @@ -8429,7 +8600,7 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.ServiceIntentInfo info) { return packageName.equals(info.service.owner.packageName); } - + @Override protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, int match, int userId) { @@ -8952,6 +9123,7 @@ public class PackageManagerService extends IPackageManager.Stub { String installerPackageName, int installerUid, UserHandle user) { final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, params.referrerUri, installerUid, null); + verifParams.setInstallerUid(installerUid); final OriginInfo origin; if (stagedDir != null) { @@ -11156,7 +11328,7 @@ public class PackageManagerService extends IPackageManager.Stub { private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) { // Can't rotate keys during boot or if sharedUser. - if (oldPs == null || (scanFlags&SCAN_BOOTING) != 0 || oldPs.sharedUser != null + if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null || !oldPs.keySetData.isUsingUpgradeKeySets()) { return false; } @@ -11540,6 +11712,10 @@ public class PackageManagerService extends IPackageManager.Stub { || (args.volumeUuid != null)); boolean replace = false; int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; + if (args.move != null) { + // moving a complete application; perfom an initial scan on the new install location + scanFlags |= SCAN_INITIAL; + } // Result object to be returned res.returnCode = PackageManager.INSTALL_SUCCEEDED; @@ -11753,7 +11929,7 @@ public class PackageManagerService extends IPackageManager.Stub { return; } - startIntentFilterVerifications(args.user.getIdentifier(), pkg); + startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg); if (replace) { replacePackageLI(pkg, parseFlags, scanFlags, args.user, @@ -11770,7 +11946,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private void startIntentFilterVerifications(int userId, PackageParser.Package pkg) { + private void startIntentFilterVerifications(int userId, boolean replacing, + PackageParser.Package pkg) { if (mIntentFilterVerifierComponent == null) { Slog.w(TAG, "No IntentFilter verification will not be done as " + "there is no IntentFilterVerifier available!"); @@ -11783,14 +11960,11 @@ public class PackageManagerService extends IPackageManager.Stub { mHandler.removeMessages(START_INTENT_FILTER_VERIFICATIONS); final Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS); - msg.obj = pkg; - msg.arg1 = userId; - msg.arg2 = verifierUid; - + msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid); mHandler.sendMessage(msg); } - private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, + private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing, PackageParser.Package pkg) { int size = pkg.activities.size(); if (size == 0) { @@ -11810,13 +11984,26 @@ public class PackageManagerService extends IPackageManager.Stub { + " if any IntentFilter from the " + size + " Activities needs verification ..."); - final int verificationId = mIntentFilterVerificationToken++; int count = 0; final String packageName = pkg.packageName; - boolean needToVerify = false; synchronized (mPackages) { + // If this is a new install and we see that we've already run verification for this + // package, we have nothing to do: it means the state was restored from backup. + if (!replacing) { + IntentFilterVerificationInfo ivi = + mSettings.getIntentFilterVerificationLPr(packageName); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Package " + packageName+ " already verified: status=" + + ivi.getStatusString()); + } + return; + } + } + // If any filters need to be verified, then all need to be. + boolean needToVerify = false; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) { @@ -11828,7 +12015,9 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + if (needToVerify) { + final int verificationId = mIntentFilterVerificationToken++; for (PackageParser.Activity a : pkg.activities) { for (ActivityIntentInfo filter : a.intents) { boolean needsFilterVerification = filter.hasWebDataURI(); @@ -13268,9 +13457,45 @@ public class PackageManagerService extends IPackageManager.Stub { } /** + * Common machinery for picking apart a restored XML blob and passing + * it to a caller-supplied functor to be applied to the running system. + */ + private void restoreFromXml(XmlPullParser parser, int userId, + String expectedStartTag, BlobXmlRestorer functor) + throws IOException, XmlPullParserException { + int type; + while ((type = parser.next()) != XmlPullParser.START_TAG + && type != XmlPullParser.END_DOCUMENT) { + } + if (type != XmlPullParser.START_TAG) { + // oops didn't find a start tag?! + if (DEBUG_BACKUP) { + Slog.e(TAG, "Didn't find start tag during restore"); + } + return; + } + + // this is supposed to be TAG_PREFERRED_BACKUP + if (!expectedStartTag.equals(parser.getName())) { + if (DEBUG_BACKUP) { + Slog.e(TAG, "Found unexpected tag " + parser.getName()); + } + return; + } + + // skip interfering stuff, then we're aligned with the backing implementation + while ((type = parser.next()) == XmlPullParser.TEXT) { } + functor.apply(parser, userId); + } + + private interface BlobXmlRestorer { + public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException; + } + + /** * Non-Binder method, support for the backup/restore mechanism: write the - * full set of preferred activities in its canonical XML format. Returns true - * on success; false otherwise. + * full set of preferred activities in its canonical XML format. Returns the + * XML output as a byte array, or null if there is none. */ @Override public byte[] getPreferredActivityBackup(int userId) { @@ -13311,32 +13536,134 @@ public class PackageManagerService extends IPackageManager.Stub { try { final XmlPullParser parser = Xml.newPullParser(); parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); + restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP, + new BlobXmlRestorer() { + @Override + public void apply(XmlPullParser parser, int userId) + throws XmlPullParserException, IOException { + synchronized (mPackages) { + mSettings.readPreferredActivitiesLPw(parser, userId); + } + } + } ); + } catch (Exception e) { + if (DEBUG_BACKUP) { + Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); + } + } + } - int type; - while ((type = parser.next()) != XmlPullParser.START_TAG - && type != XmlPullParser.END_DOCUMENT) { + /** + * Non-Binder method, support for the backup/restore mechanism: write the + * default browser (etc) settings in its canonical XML format. Returns the default + * browser XML representation as a byte array, or null if there is none. + */ + @Override + public byte[] getDefaultAppsBackup(int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call getDefaultAppsBackup()"); + } + + ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); + try { + final XmlSerializer serializer = new FastXmlSerializer(); + serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); + serializer.startDocument(null, true); + serializer.startTag(null, TAG_DEFAULT_APPS); + + synchronized (mPackages) { + mSettings.writeDefaultAppsLPr(serializer, userId); } - if (type != XmlPullParser.START_TAG) { - // oops didn't find a start tag?! - if (DEBUG_BACKUP) { - Slog.e(TAG, "Didn't find start tag during restore"); - } - return; + + serializer.endTag(null, TAG_DEFAULT_APPS); + serializer.endDocument(); + serializer.flush(); + } catch (Exception e) { + if (DEBUG_BACKUP) { + Slog.e(TAG, "Unable to write default apps for backup", e); } + return null; + } - // this is supposed to be TAG_PREFERRED_BACKUP - if (!TAG_PREFERRED_BACKUP.equals(parser.getName())) { - if (DEBUG_BACKUP) { - Slog.e(TAG, "Found unexpected tag " + parser.getName()); - } - return; + return dataStream.toByteArray(); + } + + @Override + public void restoreDefaultApps(byte[] backup, int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call restoreDefaultApps()"); + } + + try { + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); + restoreFromXml(parser, userId, TAG_DEFAULT_APPS, + new BlobXmlRestorer() { + @Override + public void apply(XmlPullParser parser, int userId) + throws XmlPullParserException, IOException { + synchronized (mPackages) { + mSettings.readDefaultAppsLPw(parser, userId); + } + } + } ); + } catch (Exception e) { + if (DEBUG_BACKUP) { + Slog.e(TAG, "Exception restoring default apps: " + e.getMessage()); } + } + } + + @Override + public byte[] getIntentFilterVerificationBackup(int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()"); + } + + ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); + try { + final XmlSerializer serializer = new FastXmlSerializer(); + serializer.setOutput(dataStream, StandardCharsets.UTF_8.name()); + serializer.startDocument(null, true); + serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION); - // skip interfering stuff, then we're aligned with the backing implementation - while ((type = parser.next()) == XmlPullParser.TEXT) { } synchronized (mPackages) { - mSettings.readPreferredActivitiesLPw(parser, userId); + mSettings.writeAllDomainVerificationsLPr(serializer, userId); } + + serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION); + serializer.endDocument(); + serializer.flush(); + } catch (Exception e) { + if (DEBUG_BACKUP) { + Slog.e(TAG, "Unable to write default apps for backup", e); + } + return null; + } + + return dataStream.toByteArray(); + } + + @Override + public void restoreIntentFilterVerification(byte[] backup, int userId) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only the system may call restorePreferredActivities()"); + } + + try { + final XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name()); + restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION, + new BlobXmlRestorer() { + @Override + public void apply(XmlPullParser parser, int userId) + throws XmlPullParserException, IOException { + synchronized (mPackages) { + mSettings.readAllDomainVerificationsLPr(parser, userId); + mSettings.writeLPr(); + } + } + } ); } catch (Exception e) { if (DEBUG_BACKUP) { Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage()); @@ -13833,7 +14160,7 @@ public class PackageManagerService extends IPackageManager.Stub { boolean checkin = false; String packageName = null; - + int opti = 0; while (opti < args.length) { String opt = args[opti]; @@ -14685,7 +15012,7 @@ public class PackageManagerService extends IPackageManager.Stub { for (PackageSetting ps : packages) { final PackageParser.Package pkg; try { - pkg = scanPackageLI(ps.codePath, parseFlags, 0, 0, null); + pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null); loaded.add(pkg.applicationInfo); } catch (PackageManagerException e) { Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage()); @@ -15479,4 +15806,55 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + @Override + public void grantDefaultPermissions(final int userId) { + enforceSystemOrPhoneCaller("grantDefaultPermissions"); + long token = Binder.clearCallingIdentity(); + try { + // We cannot grant the default permissions with a lock held as + // we query providers from other components for default handlers + // such as enabled IMEs, etc. + mHandler.post(new Runnable() { + @Override + public void run() { + mDefaultPermissionPolicy.grantDefaultPermissions(userId); + } + }); + } finally { + Binder.restoreCallingIdentity(token); + } + } + + @Override + public void setCarrierAppPackagesProvider(final IPackagesProvider provider) { + enforceSystemOrPhoneCaller("setCarrierAppPackagesProvider"); + long token = Binder.clearCallingIdentity(); + try { + PackageManagerInternal.PackagesProvider wrapper = + new PackageManagerInternal.PackagesProvider() { + @Override + public String[] getPackages(int userId) { + try { + return provider.getPackages(userId); + } catch (RemoteException e) { + return null; + } + } + }; + synchronized (mPackages) { + mDefaultPermissionPolicy.setCarrierAppPackagesProviderLPw(wrapper); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + private static void enforceSystemOrPhoneCaller(String tag) { + int callingUid = Binder.getCallingUid(); + if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) { + throw new SecurityException( + "Cannot call " + tag + " from UID " + callingUid); + } + } } diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java index ad662beaaa30..04beafd0da45 100644 --- a/services/core/java/com/android/server/pm/PermissionsState.java +++ b/services/core/java/com/android/server/pm/PermissionsState.java @@ -344,6 +344,22 @@ public final class PermissionsState { return permissionData.updateFlags(userId, flagMask, flagValues); } + public boolean updatePermissionFlagsForAllPermissions( + int userId, int flagMask, int flagValues) { + enforceValidUserId(userId); + + if (mPermissions == null) { + return false; + } + boolean changed = false; + final int permissionCount = mPermissions.size(); + for (int i = 0; i < permissionCount; i++) { + PermissionData permissionData = mPermissions.valueAt(i); + changed |= permissionData.updateFlags(userId, flagMask, flagValues); + } + return changed; + } + /** * Compute the Linux gids for a given device user from the permissions * granted to this user. Note that these are computed to avoid additional diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 6415343916d2..169f6de9b27a 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -174,6 +174,8 @@ final class Settings { "crossProfile-intent-filters"; public static final String TAG_DOMAIN_VERIFICATION = "domain-verification"; public static final String TAG_DEFAULT_APPS= "default-apps"; + public static final String TAG_ALL_INTENT_FILTER_VERIFICATION = + "all-intent-filter-verifications"; public static final String TAG_DEFAULT_BROWSER= "default-browser"; private static final String ATTR_NAME = "name"; @@ -206,10 +208,15 @@ final class Settings { final ArrayMap<String, PackageSetting> mPackages = new ArrayMap<String, PackageSetting>(); + // List of replaced system applications private final ArrayMap<String, PackageSetting> mDisabledSysPackages = new ArrayMap<String, PackageSetting>(); + // Set of restored intent-filter verification states + private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications = + new ArrayMap<String, IntentFilterVerificationInfo>(); + private static int mFirstAvailableUid = 0; // TODO: store SDK versions and fingerprint for each volume UUID @@ -753,7 +760,8 @@ final class Settings { } // Utility method that adds a PackageSetting to mPackages and - // completes updating the shared user attributes + // completes updating the shared user attributes and any restored + // app link verification state private void addPackageSettingLPw(PackageSetting p, String name, SharedUserSetting sharedUser) { mPackages.put(name, p); @@ -776,6 +784,14 @@ final class Settings { p.sharedUser = sharedUser; p.appId = sharedUser.userId; } + IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.get(name); + if (ivi != null) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Applying restored IVI for " + name + " : " + ivi.getStatusString()); + } + mRestoredIntentFilterVerifications.remove(name); + p.setIntentFilterVerificationInfo(ivi); + } } /* @@ -1259,13 +1275,13 @@ final class Settings { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } - String tagName = parser.getName(); + final String tagName = parser.getName(); if (tagName.equals(TAG_ITEM)) { CrossProfileIntentFilter cpif = new CrossProfileIntentFilter(parser); editCrossProfileIntentResolverLPw(userId).addFilter(cpif); } else { String msg = "Unknown element under " + TAG_CROSS_PROFILE_INTENT_FILTERS + ": " + - parser.getName(); + tagName; PackageManagerService.reportSettingsProblem(Log.WARN, msg); XmlUtils.skipCurrentTag(parser); } @@ -1279,7 +1295,31 @@ final class Settings { Log.d(TAG, "Read domain verification for package:" + ivi.getPackageName()); } - private void readDefaultAppsLPw(XmlPullParser parser, int userId) + private void readRestoredIntentFilterVerifications(XmlPullParser parser) + throws XmlPullParserException, IOException { + int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + final String tagName = parser.getName(); + if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { + IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser); + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Restored IVI for " + ivi.getPackageName() + + " status=" + ivi.getStatusString()); + } + mRestoredIntentFilterVerifications.put(ivi.getPackageName(), ivi); + } else { + Slog.w(TAG, "Unknown element: " + tagName); + XmlUtils.skipCurrentTag(parser); + } + } + } + + void readDefaultAppsLPw(XmlPullParser parser, int userId) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; @@ -1563,6 +1603,62 @@ final class Settings { } } + // Specifically for backup/restore + void writeAllDomainVerificationsLPr(XmlSerializer serializer, int userId) + throws IllegalArgumentException, IllegalStateException, IOException { + serializer.startTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION); + final int N = mPackages.size(); + for (int i = 0; i < N; i++) { + PackageSetting ps = mPackages.valueAt(i); + IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo(); + if (ivi != null) { + writeDomainVerificationsLPr(serializer, ivi); + } + } + serializer.endTag(null, TAG_ALL_INTENT_FILTER_VERIFICATION); + } + + // Specifically for backup/restore + void readAllDomainVerificationsLPr(XmlPullParser parser, int userId) + throws XmlPullParserException, IOException { + mRestoredIntentFilterVerifications.clear(); + + int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + + String tagName = parser.getName(); + if (tagName.equals(TAG_DOMAIN_VERIFICATION)) { + IntentFilterVerificationInfo ivi = new IntentFilterVerificationInfo(parser); + final String pkgName = ivi.getPackageName(); + final PackageSetting ps = mPackages.get(pkgName); + if (ps != null) { + // known/existing package; update in place + ps.setIntentFilterVerificationInfo(ivi); + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Restored IVI for existing app " + pkgName + + " status=" + ivi.getStatusString()); + } + } else { + mRestoredIntentFilterVerifications.put(pkgName, ivi); + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.d(TAG, "Restored IVI for pending app " + pkgName + + " status=" + ivi.getStatusString()); + } + } + } else { + PackageManagerService.reportSettingsProblem(Log.WARN, + "Unknown element under <all-intent-filter-verification>: " + + parser.getName()); + XmlUtils.skipCurrentTag(parser); + } + } + } + void writeDefaultAppsLPr(XmlSerializer serializer, int userId) throws IllegalArgumentException, IllegalStateException, IOException { serializer.startTag(null, TAG_DEFAULT_APPS); @@ -2012,6 +2108,23 @@ final class Settings { } } + final int numIVIs = mRestoredIntentFilterVerifications.size(); + if (numIVIs > 0) { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, "Writing restored-ivi entries to packages.xml"); + } + serializer.startTag(null, "restored-ivi"); + for (int i = 0; i < numIVIs; i++) { + IntentFilterVerificationInfo ivi = mRestoredIntentFilterVerifications.valueAt(i); + writeDomainVerificationsLPr(serializer, ivi); + } + serializer.endTag(null, "restored-ivi"); + } else { + if (DEBUG_DOMAIN_VERIFICATION) { + Slog.i(TAG, " no restored IVI entries to write"); + } + } + mKeySetManagerService.writeKeySetManagerServiceLPr(serializer); serializer.endTag(null, "packages"); @@ -2441,6 +2554,8 @@ final class Settings { if (nname != null && oname != null) { mRenamedPackages.put(nname, oname); } + } else if (tagName.equals("restored-ivi")) { + readRestoredIntentFilterVerifications(parser); } else if (tagName.equals("last-platform-version")) { mInternalSdkPlatform = mExternalSdkPlatform = 0; try { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 4082ff3a957a..8a8d2a6b104f 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -972,6 +972,7 @@ public class UserManagerService extends IUserManager.Stub { writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); writeBoolean(serializer, restrictions, UserManager.DISALLOW_WALLPAPER); writeBoolean(serializer, restrictions, UserManager.DISALLOW_SAFE_BOOT); + writeBoolean(serializer, restrictions, UserManager.ALLOW_PARENT_APP_LINKING); serializer.endTag(null, TAG_RESTRICTIONS); } @@ -1103,6 +1104,7 @@ public class UserManagerService extends IUserManager.Stub { readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); readBoolean(parser, restrictions, UserManager.DISALLOW_WALLPAPER); readBoolean(parser, restrictions, UserManager.DISALLOW_SAFE_BOOT); + readBoolean(parser, restrictions, UserManager.ALLOW_PARENT_APP_LINKING); } private void readBoolean(XmlPullParser parser, Bundle restrictions, diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 79dac1446351..93e1f187b543 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -5381,10 +5381,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode) { - if (!wakeInTheaterMode && isTheaterModeEnabled()) { + final boolean theaterModeEnabled = isTheaterModeEnabled(); + if (!wakeInTheaterMode && theaterModeEnabled) { return false; } + if (theaterModeEnabled) { + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0); + } + mPowerManager.wakeUp(wakeTime); return true; } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index a7543790cc10..7640837f4e73 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -29,6 +29,7 @@ import android.util.Slog; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.NotificationVisibility; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.statusbar.StatusBarIconList; import com.android.server.LocalServices; @@ -660,7 +661,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub { @Override public void onNotificationVisibilityChanged( - String[] newlyVisibleKeys, String[] noLongerVisibleKeys) throws RemoteException { + NotificationVisibility[] newlyVisibleKeys, NotificationVisibility[] noLongerVisibleKeys) + throws RemoteException { enforceStatusBarService(); long identity = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index f5c5861a0ebd..51df31fde504 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -34,6 +34,7 @@ import android.content.OperationApplicationException; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.graphics.Rect; @@ -112,8 +113,6 @@ public final class TvInputManagerService extends SystemService { private final Context mContext; private final TvInputHardwareManager mTvInputHardwareManager; - private final ContentResolver mContentResolver; - // A global lock. private final Object mLock = new Object(); @@ -129,9 +128,8 @@ public final class TvInputManagerService extends SystemService { super(context); mContext = context; - mContentResolver = context.getContentResolver(); - mWatchLogHandler = new WatchLogHandler(mContentResolver, IoThread.get().getLooper()); - + mWatchLogHandler = new WatchLogHandler(mContext.getContentResolver(), + IoThread.get().getLooper()); mTvInputHardwareManager = new TvInputHardwareManager(context, new HardwareListener()); synchronized (mLock) { @@ -246,7 +244,8 @@ public final class TvInputManagerService extends SystemService { ContentProviderResult[] results = null; try { - results = mContentResolver.applyBatch(TvContract.AUTHORITY, operations); + ContentResolver cr = getContentResolverForUser(getChangingUserId()); + results = cr.applyBatch(TvContract.AUTHORITY, operations); } catch (RemoteException | OperationApplicationException e) { Slog.e(TAG, "error in applyBatch", e); } @@ -400,17 +399,18 @@ public final class TvInputManagerService extends SystemService { if (mCurrentUserId == userId) { return; } - // final int oldUserId = mCurrentUserId; - // TODO: Release services and sessions in the old user state, if needed. - mCurrentUserId = userId; + clearSessionAndServiceStatesLocked(mUserStates.get(mCurrentUserId)); + mCurrentUserId = userId; UserState userState = mUserStates.get(userId); if (userState == null) { userState = new UserState(mContext, userId); + mUserStates.put(userId, userState); } - mUserStates.put(userId, userState); buildTvInputListLocked(userId, null); buildTvContentRatingSystemListLocked(userId); + mWatchLogHandler.obtainMessage(WatchLogHandler.MSG_SWITCH_CONTENT_RESOLVER, + getContentResolverForUser(userId)).sendToTarget(); } } @@ -420,30 +420,7 @@ public final class TvInputManagerService extends SystemService { if (userState == null) { return; } - // Release created sessions. - for (SessionState state : userState.sessionStateMap.values()) { - if (state.session != null) { - try { - state.session.release(); - } catch (RemoteException e) { - Slog.e(TAG, "error in release", e); - } - } - } - userState.sessionStateMap.clear(); - - // Unregister all callbacks and unbind all services. - for (ServiceState serviceState : userState.serviceStateMap.values()) { - if (serviceState.callback != null) { - try { - serviceState.service.unregisterCallback(serviceState.callback); - } catch (RemoteException e) { - Slog.e(TAG, "error in unregisterCallback", e); - } - } - mContext.unbindService(serviceState.connection); - } - userState.serviceStateMap.clear(); + clearSessionAndServiceStatesLocked(userState); // Clear everything else. userState.inputMap.clear(); @@ -457,6 +434,45 @@ public final class TvInputManagerService extends SystemService { } } + private void clearSessionAndServiceStatesLocked(UserState userState) { + // Release created sessions. + for (SessionState state : userState.sessionStateMap.values()) { + if (state.session != null) { + try { + state.session.release(); + } catch (RemoteException e) { + Slog.e(TAG, "error in release", e); + } + } + } + userState.sessionStateMap.clear(); + + // Unregister all callbacks and unbind all services. + for (ServiceState serviceState : userState.serviceStateMap.values()) { + if (serviceState.callback != null) { + try { + serviceState.service.unregisterCallback(serviceState.callback); + } catch (RemoteException e) { + Slog.e(TAG, "error in unregisterCallback", e); + } + } + mContext.unbindService(serviceState.connection); + } + userState.serviceStateMap.clear(); + } + + private ContentResolver getContentResolverForUser(int userId) { + UserHandle user = new UserHandle(userId); + Context context; + try { + context = mContext.createPackageContextAsUser("android", 0, user); + } catch (NameNotFoundException e) { + Slog.e(TAG, "failed to create package contenxt as user " + user); + context = mContext; + } + return context.getContentResolver(); + } + private UserState getUserStateLocked(int userId) { UserState userState = mUserStates.get(userId); if (userState == null) { @@ -2384,12 +2400,13 @@ public final class TvInputManagerService extends SystemService { // Here the system supplies the database the smallest set of information only that is // sufficient to consolidate the log entries while minimizing database operations in the // system service. - private static final int MSG_LOG_WATCH_START = 1; - private static final int MSG_LOG_WATCH_END = 2; + static final int MSG_LOG_WATCH_START = 1; + static final int MSG_LOG_WATCH_END = 2; + static final int MSG_SWITCH_CONTENT_RESOLVER = 3; - private final ContentResolver mContentResolver; + private ContentResolver mContentResolver; - public WatchLogHandler(ContentResolver contentResolver, Looper looper) { + WatchLogHandler(ContentResolver contentResolver, Looper looper) { super(looper); mContentResolver = contentResolver; } @@ -2419,7 +2436,7 @@ public final class TvInputManagerService extends SystemService { mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); args.recycle(); - return; + break; } case MSG_LOG_WATCH_END: { SomeArgs args = (SomeArgs) msg.obj; @@ -2434,11 +2451,15 @@ public final class TvInputManagerService extends SystemService { mContentResolver.insert(TvContract.WatchedPrograms.CONTENT_URI, values); args.recycle(); - return; + break; + } + case MSG_SWITCH_CONTENT_RESOLVER: { + mContentResolver = (ContentResolver) msg.obj; + break; } default: { - Slog.w(TAG, "Unhandled message code: " + msg.what); - return; + Slog.w(TAG, "unhandled message code: " + msg.what); + break; } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index ace59970d0bf..b285b663bd14 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2671,6 +2671,16 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { mScreenCaptureDisabled.put(userId, disabled); + // Update secure surface for all windows belonging to this user. + for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) { + WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); + for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { + final WindowState win = windows.get(winNdx); + if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) { + win.mWinAnimator.setSecureLocked(disabled); + } + } + } } } diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index f1331e94bd42..d818519d5dfa 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -658,6 +658,11 @@ class WindowStateAnimator { } @Override + public void setSecure(boolean isSecure) { + super.setSecure(isSecure); + } + + @Override public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) { if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," @@ -1663,6 +1668,22 @@ class WindowStateAnimator { } } + void setSecureLocked(boolean isSecure) { + if (mSurfaceControl == null) { + return; + } + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked"); + SurfaceControl.openTransaction(); + try { + if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isSecure=" + isSecure, + null); + mSurfaceControl.setSecure(isSecure); + } finally { + SurfaceControl.closeTransaction(); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked"); + } + } + // This must be called while inside a transaction. boolean performShowLocked() { if (mWin.isHiddenFromUserLocked()) { diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 3b62b61a1f3c..e44a7ab874eb 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -246,6 +246,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.USB_MASS_STORAGE_ENABLED); GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY); GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN); + GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN); } // Keyguard features that when set of a profile will affect the profiles @@ -3231,15 +3232,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final UserHandle caller = Binder.getCallingUserHandle(); - final ComponentName profileOwner = getProfileOwner(caller.getIdentifier()); - - if (profileOwner == null) { + // If there is a profile owner, redirect to that; otherwise query the device owner. + ComponentName aliasChooser = getProfileOwner(caller.getIdentifier()); + if (aliasChooser == null && caller.isOwner()) { + ActiveAdmin deviceOwnerAdmin = getDeviceOwnerAdmin(); + if (deviceOwnerAdmin != null) { + aliasChooser = deviceOwnerAdmin.info.getComponent(); + } + } + if (aliasChooser == null) { sendPrivateKeyAliasResponse(null, response); return; } Intent intent = new Intent(DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS); - intent.setComponent(profileOwner); + intent.setComponent(aliasChooser); intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, uid); intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI, uri); intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias); @@ -4210,11 +4217,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long ident = Binder.clearCallingIdentity(); try { clearUserRestrictions(new UserHandle(UserHandle.USER_OWNER)); + AppGlobals.getPackageManager().updatePermissionFlagsForAllApps( + PackageManager.FLAG_PERMISSION_POLICY_FIXED, + 0, UserHandle.USER_OWNER); if (mDeviceOwner != null) { mDeviceOwner.clearDeviceOwner(); mDeviceOwner.writeOwnerFile(); updateDeviceOwnerLocked(); } + } catch (RemoteException re) { } finally { Binder.restoreCallingIdentity(ident); } @@ -4381,10 +4392,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long ident = Binder.clearCallingIdentity(); try { clearUserRestrictions(callingUser); + AppGlobals.getPackageManager().updatePermissionFlagsForAllApps( + PackageManager.FLAG_PERMISSION_POLICY_FIXED, + 0, callingUser.getIdentifier()); if (mDeviceOwner != null) { mDeviceOwner.removeProfileOwner(userId); mDeviceOwner.writeOwnerFile(); } + } catch (RemoteException re) { } finally { Binder.restoreCallingIdentity(ident); } @@ -6383,21 +6398,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long ident = Binder.clearCallingIdentity(); try { - PackageManager packageManager = mContext.getPackageManager(); + final ApplicationInfo ai = AppGlobals.getPackageManager() + .getApplicationInfo(packageName, 0, user.getIdentifier()); + final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion; + if (targetSdkVersion < android.os.Build.VERSION_CODES.MNC) { + return false; + } + final PackageManager packageManager = mContext.getPackageManager(); switch (grantState) { case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: { + packageManager.grantRuntimePermission(packageName, permission, user); packageManager.updatePermissionFlags(permission, packageName, PackageManager.FLAG_PERMISSION_POLICY_FIXED, PackageManager.FLAG_PERMISSION_POLICY_FIXED, user); - packageManager.grantRuntimePermission(packageName, permission, user); } break; case DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: { + packageManager.revokeRuntimePermission(packageName, + permission, user); packageManager.updatePermissionFlags(permission, packageName, PackageManager.FLAG_PERMISSION_POLICY_FIXED, PackageManager.FLAG_PERMISSION_POLICY_FIXED, user); - packageManager.revokeRuntimePermission(packageName, - permission, user); } break; case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: { diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java index 712db095587d..fb8a5bb82ba3 100644 --- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java @@ -34,6 +34,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; +import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.ContextWrapper; @@ -792,6 +793,30 @@ public class ConnectivityServiceTest extends AndroidTestCase { handlerThread.quit(); } + @LargeTest + public void testNoMutableNetworkRequests() throws Exception { + PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); + NetworkRequest.Builder builder = new NetworkRequest.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); + try { + mCm.requestNetwork(builder.build(), new NetworkCallback()); + fail(); + } catch (IllegalArgumentException expected) {} + try { + mCm.requestNetwork(builder.build(), pendingIntent); + fail(); + } catch (IllegalArgumentException expected) {} + builder = new NetworkRequest.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); + try { + mCm.requestNetwork(builder.build(), new NetworkCallback()); + fail(); + } catch (IllegalArgumentException expected) {} + try { + mCm.requestNetwork(builder.build(), pendingIntent); + fail(); + } catch (IllegalArgumentException expected) {} + } // @Override // public void tearDown() throws Exception { diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 490236e41ac7..c49a5f95708f 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -119,6 +119,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_CHECK_PAROLE_TIMEOUT = 6; static final int MSG_PAROLE_END_TIMEOUT = 7; static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8; + static final int MSG_PAROLE_STATE_CHANGED = 9; private final Object mLock = new Object(); Handler mHandler; @@ -313,7 +314,7 @@ public class UsageStatsService extends SystemService implements mLastAppIdleParoledTime = checkAndGetTimeLocked(); postNextParoleTimeout(); } - postCheckIdleStates(UserHandle.USER_ALL); + postParoleStateChanged(); } } } @@ -338,6 +339,12 @@ public class UsageStatsService extends SystemService implements mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, mAppIdleParoleDurationMillis); } + private void postParoleStateChanged() { + if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_STATE_CHANGED"); + mHandler.removeMessages(MSG_PAROLE_STATE_CHANGED); + mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED); + } + void postCheckIdleStates(int userId) { mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0)); } @@ -756,6 +763,13 @@ public class UsageStatsService extends SystemService implements } } + boolean isAppIdleFilteredOrParoled(String packageName, int userId, long timeNow) { + if (mAppIdleParoled) { + return false; + } + return isAppIdleFiltered(packageName, userId, timeNow); + } + boolean isAppIdleFiltered(String packageName, int userId, long timeNow) { final UserUsageStatsService userService; final long screenOnTime; @@ -782,13 +796,6 @@ public class UsageStatsService extends SystemService implements if (!mAppIdleEnabled) { return false; } - synchronized (mLock) { - // Temporary exemption, probably due to device charging or occasional allowance to - // be allowed to sync, etc. - if (mAppIdleParoled) { - return false; - } - } if (packageName.equals("android")) return false; try { if (mDeviceIdleController.isPowerSaveWhitelistApp(packageName)) { @@ -846,6 +853,12 @@ public class UsageStatsService extends SystemService implements } } + void informParoleStateChanged() { + for (AppIdleStateChangeListener listener : mPackageAccessListeners) { + listener.onParoleStateChanged(mAppIdleParoled); + } + } + private static boolean validRange(long currentTime, long beginTime, long endTime) { return beginTime <= currentTime && beginTime < endTime; } @@ -975,6 +988,11 @@ public class UsageStatsService extends SystemService implements args.recycle(); break; + case MSG_PAROLE_STATE_CHANGED: + if (DEBUG) Slog.d(TAG, "Parole state changed: " + mAppIdleParoled); + informParoleStateChanged(); + break; + default: super.handleMessage(msg); break; @@ -1126,7 +1144,7 @@ public class UsageStatsService extends SystemService implements } final long token = Binder.clearCallingIdentity(); try { - return UsageStatsService.this.isAppIdleFiltered(packageName, userId, -1); + return UsageStatsService.this.isAppIdleFilteredOrParoled(packageName, userId, -1); } finally { Binder.restoreCallingIdentity(token); } @@ -1251,6 +1269,11 @@ public class UsageStatsService extends SystemService implements } @Override + public boolean isAppIdleParoleOn() { + return mAppIdleParoled; + } + + @Override public void prepareShutdown() { // This method *WILL* do IO work, but we must block until it is finished or else // we might not shutdown cleanly. This is ok to do with the 'am' lock held, because @@ -1261,6 +1284,7 @@ public class UsageStatsService extends SystemService implements @Override public void addAppIdleStateChangeListener(AppIdleStateChangeListener listener) { UsageStatsService.this.addListener(listener); + listener.onParoleStateChanged(isAppIdleParoleOn()); } @Override diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index b7ca7499b64c..cec11cfd17d1 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -944,10 +944,17 @@ public class TelephonyManager { /** {@hide} */ @SystemApi public int getCurrentPhoneType(int subId) { - int phoneId = SubscriptionManager.getPhoneId(subId); + int phoneId; + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + // if we don't have any sims, we don't have subscriptions, but we + // still may want to know what type of phone we've got. + phoneId = 0; + } else { + phoneId = SubscriptionManager.getPhoneId(subId); + } try{ ITelephony telephony = getITelephony(); - if (telephony != null) { + if (telephony != null && subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { return telephony.getActivePhoneTypeForSubscriber(subId); } else { // This can happen when the ITelephony interface is not up yet. diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java index 8a723418b591..439ace8e9952 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java @@ -17,7 +17,7 @@ package com.android.test.voiceinteraction; import android.annotation.Nullable; -import android.app.AssistStructure; +import android.app.assist.AssistStructure; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index 3090a119657a..90a781cddbcc 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -18,8 +18,8 @@ package com.android.test.voiceinteraction; import android.app.ActivityManager; import android.app.VoiceInteractor; -import android.app.AssistContent; -import android.app.AssistStructure; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -123,34 +123,8 @@ public class MainInteractionSession extends VoiceInteractionSession } public void onHandleAssist(Bundle assistBundle) { - boolean hasStructure = false; - if (assistBundle != null) { - Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT); - if (assistContext != null) { - mAssistStructure = AssistStructure.getAssistStructure(assistContext); - if (mAssistStructure != null) { - if (mAssistVisualizer != null) { - mAssistVisualizer.setAssistStructure(mAssistStructure); - hasStructure = true; - } - } - AssistContent content = AssistContent.getAssistContent(assistContext); - if (content != null) { - Log.i(TAG, "Assist intent: " + content.getIntent()); - Log.i(TAG, "Assist clipdata: " + content.getClipData()); - } - } - Uri referrer = assistBundle.getParcelable(Intent.EXTRA_REFERRER); - if (referrer != null) { - Log.i(TAG, "Referrer: " + referrer); - } - } - if (!hasStructure && mAssistVisualizer != null) { - mAssistVisualizer.clearAssistData(); - } } - /* @Override public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { mAssistStructure = structure; @@ -158,13 +132,22 @@ public class MainInteractionSession extends VoiceInteractionSession if (mAssistVisualizer != null) { mAssistVisualizer.setAssistStructure(mAssistStructure); } + } else { + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } } if (content != null) { Log.i(TAG, "Assist intent: " + content.getIntent()); Log.i(TAG, "Assist clipdata: " + content.getClipData()); } + if (data != null) { + Uri referrer = data.getParcelable(Intent.EXTRA_REFERRER); + if (referrer != null) { + Log.i(TAG, "Referrer: " + referrer); + } + } } - */ @Override public void onHandleScreenshot(Bitmap screenshot) { diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java index c038414daf8c..943c64797c55 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java @@ -16,6 +16,7 @@ package com.android.test.voiceinteraction; +import android.annotation.Nullable; import android.app.Activity; import android.app.VoiceInteractor; import android.content.ComponentName; @@ -111,38 +112,10 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis @Override public void onClick(View v) { if (v == mAbortButton) { - VoiceInteractor.AbortVoiceRequest req = new VoiceInteractor.AbortVoiceRequest( - new VoiceInteractor.Prompt("Dammit, we suck :("), null) { - @Override - public void onCancel() { - Log.i(TAG, "Canceled!"); - mLog.append("Canceled abort\n"); - } - - @Override - public void onAbortResult(Bundle result) { - Log.i(TAG, "Abort result: result=" + result); - mLog.append("Abort: result=" + result + "\n"); - getActivity().finish(); - } - }; + VoiceInteractor.AbortVoiceRequest req = new TestAbortVoice(); mInteractor.submitRequest(req, REQUEST_ABORT); } else if (v == mCompleteButton) { - VoiceInteractor.CompleteVoiceRequest req = new VoiceInteractor.CompleteVoiceRequest( - new VoiceInteractor.Prompt("Woohoo, completed!"), null) { - @Override - public void onCancel() { - Log.i(TAG, "Canceled!"); - mLog.append("Canceled complete\n"); - } - - @Override - public void onCompleteResult(Bundle result) { - Log.i(TAG, "Complete result: result=" + result); - mLog.append("Complete: result=" + result + "\n"); - getActivity().finish(); - } - }; + VoiceInteractor.CompleteVoiceRequest req = new TestCompleteVoice(); mInteractor.submitRequest(req, REQUEST_COMPLETE); } else if (v == mPickButton) { VoiceInteractor.PickOptionRequest.Option[] options = @@ -152,36 +125,7 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis options[2] = new VoiceInteractor.PickOptionRequest.Option("Three"); options[3] = new VoiceInteractor.PickOptionRequest.Option("Four"); options[4] = new VoiceInteractor.PickOptionRequest.Option("Five"); - VoiceInteractor.PickOptionRequest req = new VoiceInteractor.PickOptionRequest( - new VoiceInteractor.Prompt("Need to pick something"), options, null) { - @Override - public void onCancel() { - Log.i(TAG, "Canceled!"); - mLog.append("Canceled pick\n"); - } - - @Override - public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { - Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections - + " result=" + result); - StringBuilder sb = new StringBuilder(); - if (finished) { - sb.append("Pick final result: "); - } else { - sb.append("Pick intermediate result: "); - } - for (int i=0; i<selections.length; i++) { - if (i >= 1) { - sb.append(", "); - } - sb.append(selections[i].getLabel()); - } - mLog.append(sb.toString()); - if (finished) { - getActivity().finish(); - } - } - }; + VoiceInteractor.PickOptionRequest req = new TestPickOption(options); mInteractor.submitRequest(req, REQUEST_PICK); } else if (v == mJumpOutButton) { Log.i(TAG, "Jump out"); @@ -200,4 +144,66 @@ public class TestInteractionActivity extends Activity implements View.OnClickLis public void onDestroy() { super.onDestroy(); } + + static class TestAbortVoice extends VoiceInteractor.AbortVoiceRequest { + public TestAbortVoice() { + super(new VoiceInteractor.Prompt("Dammit, we suck :("), null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled abort\n"); + } + @Override public void onAbortResult(Bundle result) { + Log.i(TAG, "Abort result: result=" + result); + ((TestInteractionActivity)getActivity()).mLog.append("Abort: result=" + result + "\n"); + getActivity().finish(); + } + } + + static class TestCompleteVoice extends VoiceInteractor.CompleteVoiceRequest { + public TestCompleteVoice() { + super(new VoiceInteractor.Prompt("Woohoo, completed!"), null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled complete\n"); + } + @Override public void onCompleteResult(Bundle result) { + Log.i(TAG, "Complete result: result=" + result); + ((TestInteractionActivity)getActivity()).mLog.append("Complete: result=" + + result + "\n"); + getActivity().finish(); + } + } + + static class TestPickOption extends VoiceInteractor.PickOptionRequest { + public TestPickOption(Option[] options) { + super(new VoiceInteractor.Prompt("Need to pick something"), options, null); + } + @Override public void onCancel() { + Log.i(TAG, "Canceled!"); + ((TestInteractionActivity)getActivity()).mLog.append("Canceled pick\n"); + } + @Override + public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) { + Log.i(TAG, "Pick result: finished=" + finished + " selections=" + selections + + " result=" + result); + StringBuilder sb = new StringBuilder(); + if (finished) { + sb.append("Pick final result: "); + } else { + sb.append("Pick intermediate result: "); + } + for (int i=0; i<selections.length; i++) { + if (i >= 1) { + sb.append(", "); + } + sb.append(selections[i].getLabel()); + } + ((TestInteractionActivity)getActivity()).mLog.append(sb.toString()); + if (finished) { + getActivity().finish(); + } + } + } } diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java index 5dc70bd49baf..fc6a3de753fe 100644 --- a/wifi/java/android/net/wifi/ScanResult.java +++ b/wifi/java/android/net/wifi/ScanResult.java @@ -18,6 +18,7 @@ package android.net.wifi; import android.os.Parcel; import android.os.Parcelable; +import android.util.Log; /** * Describes information about a detected access point. In addition @@ -80,27 +81,30 @@ public class ScanResult implements Parcelable { public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; /** - * AP Channel bandwidth + * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, + * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ} + * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}. */ public int channelWidth; /** * Not used if the AP bandwidth is 20 MHz - * If the AP use 40, 80 or 160 MHz, this is the center frequency - * if the AP use 80 + 80 MHz, this is the center frequency of the first segment + * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz) + * if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz) */ public int centerFreq0; /** * Only used if the AP bandwidth is 80 + 80 MHz - * if the AP use 80 + 80 MHz, this is the center frequency of the second segment + * if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz) */ public int centerFreq1; /** - * Whether the AP support 802.11mc Responder + * @deprecated use is80211mcResponder() instead + * @hide */ - public boolean is80211McRTTResponder; + public boolean is80211McRTTResponder; /** * timestamp in microseconds (since boot) when @@ -123,7 +127,7 @@ public class ScanResult implements Parcelable { /** * @hide * Update RSSI of the scan result - * @param previousRSSI + * @param previousRssi * @param previousSeen * @param maxAge */ @@ -206,26 +210,56 @@ public class ScanResult implements Parcelable { public int distanceCm; /** - * The standard deviation of the distance to the AP, if available. + * The standard deviation of the distance to the access point, if available. * Else {@link UNSPECIFIED}. * {@hide} */ public int distanceSdCm; + public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001; + public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002; + /** - * Indicates if the scan result represents a passpoint AP + * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}. */ - public boolean passpointNetwork; + public long flags; /** - * Indicates if venue name + * sets a flag in {@link #flags} field + * @param flag flag to set + * @hide */ - public String venueName; + public void setFlag(long flag) { + flags |= flag; + } /** - * Indicates operator name + * clears a flag in {@link #flags} field + * @param flag flag to set + * @hide */ - public String operatorFriendlyName; + public void clearFlag(long flag) { + flags &= ~flag; + } + + public boolean is80211mcResponder() { + return (flags & FLAG_80211mc_RESPONDER) != 0; + } + + public boolean isPasspointNetwork() { + return (flags & FLAG_PASSPOINT_NETWORK) != 0; + } + + /** + * Indicates venue name (such as 'San Francisco Airport') published by access point; only + * available on passpoint network and if published by access point. + */ + public CharSequence venueName; + + /** + * Indicates passpoint operator name published by access point. + */ + public CharSequence operatorFriendlyName; /** * {@hide} @@ -267,7 +301,7 @@ public class ScanResult implements Parcelable { **/ public byte[] bytes; - /** information element from beacon + /** information elements from beacon * @hide */ public static class InformationElement { @@ -303,8 +337,7 @@ public class ScanResult implements Parcelable { this.channelWidth = UNSPECIFIED; this.centerFreq0 = UNSPECIFIED; this.centerFreq1 = UNSPECIFIED; - this.is80211McRTTResponder = false; - this.passpointNetwork = false; + this.flags = 0; } /** {@hide} */ @@ -322,8 +355,7 @@ public class ScanResult implements Parcelable { this.channelWidth = UNSPECIFIED; this.centerFreq0 = UNSPECIFIED; this.centerFreq1 = UNSPECIFIED; - this.is80211McRTTResponder = false; - this.passpointNetwork = false; + this.flags = 0; } /** {@hide} */ @@ -342,8 +374,11 @@ public class ScanResult implements Parcelable { this.channelWidth = channelWidth; this.centerFreq0 = centerFreq0; this.centerFreq1 = centerFreq1; - this.is80211McRTTResponder = is80211McRTTResponder; - this.passpointNetwork = false; + if (is80211McRTTResponder) { + this.flags = FLAG_80211mc_RESPONDER; + } else { + this.flags = 0; + } } /** copy constructor {@hide} */ @@ -358,7 +393,6 @@ public class ScanResult implements Parcelable { channelWidth = source.channelWidth; centerFreq0 = source.centerFreq0; centerFreq1 = source.centerFreq1; - is80211McRTTResponder = source.is80211McRTTResponder; timestamp = source.timestamp; distanceCm = source.distanceCm; distanceSdCm = source.distanceSdCm; @@ -369,9 +403,9 @@ public class ScanResult implements Parcelable { numUsage = source.numUsage; numIpConfigFailures = source.numIpConfigFailures; isAutoJoinCandidate = source.isAutoJoinCandidate; - passpointNetwork = source.passpointNetwork; venueName = source.venueName; operatorFriendlyName = source.operatorFriendlyName; + flags = source.flags; } } @@ -405,15 +439,16 @@ public class ScanResult implements Parcelable { sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")). append("(cm)"); - sb.append(", passpoint: ").append(passpointNetwork ? "yes" : "no"); + sb.append(", passpoint: "); + sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no"); if (autoJoinStatus != 0) { sb.append(", status: ").append(autoJoinStatus); } sb.append(", ChannelBandwidth: ").append(channelWidth); sb.append(", centerFreq0: ").append(centerFreq0); sb.append(", centerFreq1: ").append(centerFreq1); - sb.append(", 80211mcResponder: ").append(is80211McRTTResponder? - "is supported":"is not supported"); + sb.append(", 80211mcResponder: "); + sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported"); return sb.toString(); } @@ -440,7 +475,6 @@ public class ScanResult implements Parcelable { dest.writeInt(channelWidth); dest.writeInt(centerFreq0); dest.writeInt(centerFreq1); - dest.writeInt(is80211McRTTResponder ? 1 : 0); dest.writeLong(seen); dest.writeInt(autoJoinStatus); dest.writeInt(untrusted ? 1 : 0); @@ -448,9 +482,9 @@ public class ScanResult implements Parcelable { dest.writeInt(numUsage); dest.writeInt(numIpConfigFailures); dest.writeInt(isAutoJoinCandidate); - dest.writeInt(passpointNetwork ? 1 : 0); - dest.writeString(venueName); - dest.writeString(operatorFriendlyName); + dest.writeString((venueName != null) ? venueName.toString() : ""); + dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : ""); + dest.writeLong(this.flags); if (informationElements != null) { dest.writeInt(informationElements.length); @@ -474,18 +508,19 @@ public class ScanResult implements Parcelable { } ScanResult sr = new ScanResult( wifiSsid, - in.readString(), - in.readString(), - in.readInt(), - in.readInt(), - in.readLong(), - in.readInt(), - in.readInt(), - in.readInt(), - in.readInt(), - in.readInt(), - in.readInt() == 1 + in.readString(), /* BSSID */ + in.readString(), /* capabilities */ + in.readInt(), /* level */ + in.readInt(), /* frequency */ + in.readLong(), /* timestamp */ + in.readInt(), /* distanceCm */ + in.readInt(), /* distanceSdCm */ + in.readInt(), /* channelWidth */ + in.readInt(), /* centerFreq0 */ + in.readInt(), /* centerFreq1 */ + false /* rtt responder, fixed with flags below */ ); + sr.seen = in.readLong(); sr.autoJoinStatus = in.readInt(); sr.untrusted = in.readInt() != 0; @@ -493,9 +528,9 @@ public class ScanResult implements Parcelable { sr.numUsage = in.readInt(); sr.numIpConfigFailures = in.readInt(); sr.isAutoJoinCandidate = in.readInt(); - sr.passpointNetwork = in.readInt() == 1; sr.venueName = in.readString(); sr.operatorFriendlyName = in.readString(); + sr.flags = in.readLong(); int n = in.readInt(); if (n != 0) { sr.informationElements = new InformationElement[n]; diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index 5d55ec611be0..5d834f6bc568 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -344,14 +344,15 @@ public class WifiConfiguration implements Parcelable { public String FQDN; /** - * Service provider name, for Passpoint credential. + * Name of passpoint credential provider */ public String providerFriendlyName; /** - * Roaming Consortium Id, for Passpoint credential. + * Roaming Consortium Id list for passpoint credential; identifies a set of networks where + * passpoint credential will be considered valid */ - public HashSet<Long> roamingConsortiumIds; + public Long[] roamingConsortiumIds; /** * @hide @@ -906,7 +907,7 @@ public class WifiConfiguration implements Parcelable { SSID = null; BSSID = null; FQDN = null; - roamingConsortiumIds = new HashSet<Long>(); + roamingConsortiumIds = new Long[0]; priority = 0; hiddenSSID = false; disableReason = DISABLED_UNKNOWN_REASON; @@ -1437,11 +1438,7 @@ public class WifiConfiguration implements Parcelable { SSID = source.SSID; BSSID = source.BSSID; FQDN = source.FQDN; - roamingConsortiumIds = new HashSet<Long>(); - for (Long roamingConsortiumId : source.roamingConsortiumIds) { - roamingConsortiumIds.add(roamingConsortiumId); - } - + roamingConsortiumIds = source.roamingConsortiumIds.clone(); providerFriendlyName = source.providerFriendlyName; preSharedKey = source.preSharedKey; @@ -1546,7 +1543,7 @@ public class WifiConfiguration implements Parcelable { dest.writeString(autoJoinBSSID); dest.writeString(FQDN); dest.writeString(providerFriendlyName); - dest.writeInt(roamingConsortiumIds.size()); + dest.writeInt(roamingConsortiumIds.length); for (Long roamingConsortiumId : roamingConsortiumIds) { dest.writeLong(roamingConsortiumId); } @@ -1622,8 +1619,9 @@ public class WifiConfiguration implements Parcelable { config.FQDN = in.readString(); config.providerFriendlyName = in.readString(); int numRoamingConsortiumIds = in.readInt(); + config.roamingConsortiumIds = new Long[numRoamingConsortiumIds]; for (int i = 0; i < numRoamingConsortiumIds; i++) { - config.roamingConsortiumIds.add(in.readLong()); + config.roamingConsortiumIds[i] = in.readLong(); } config.preSharedKey = in.readString(); for (int i = 0; i < config.wepKeys.length; i++) { diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 3525ec26f53a..e611ea448497 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -604,12 +604,13 @@ public class WifiEnterpriseConfig implements Parcelable { * Get the domain_suffix_match value. See setDomSuffixMatch. * @return The domain value. */ - public String getDomainSubjectMatch() { + public String getDomainSuffixMatch() { return getFieldValue(DOM_SUFFIX_MATCH_KEY, ""); } /** - * Set realm for passpoint credential + * Set realm for passpoint credential; realm identifies a set of networks where your + * passpoint credential can be used * @param realm the realm */ public void setRealm(String realm) { @@ -617,7 +618,7 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Get realm for passpoint credential + * Get realm for passpoint credential; see {@link #setRealm(String)} for more information * @return the realm */ public String getRealm() { @@ -625,15 +626,16 @@ public class WifiEnterpriseConfig implements Parcelable { } /** - * Set plmn for passpoint credential - * @param plmn the plmn value derived from mcc & mnc + * Set plmn (Public Land Mobile Network) of the provider of passpoint credential + * @param plmn the plmn value derived from mcc (mobile country code) & mnc (mobile network code) */ public void setPlmn(String plmn) { setFieldValue(PLMN_KEY, plmn, ""); } /** - * Get plmn for passpoint credential + * Get plmn (Public Land Mobile Network) for passpoint credential; see {@link #setPlmn + * (String)} for more information * @return the plmn */ public String getPlmn() { diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java index dbfd4ef41ead..2ba38e18fd1c 100644 --- a/wifi/java/android/net/wifi/WifiInfo.java +++ b/wifi/java/android/net/wifi/WifiInfo.java @@ -167,15 +167,24 @@ public class WifiInfo implements Parcelable { long txbad = stats.lostmpdu_be + stats.lostmpdu_bk + stats.lostmpdu_vi + stats.lostmpdu_vo; - txBadRate = (txBadRate * 0.5) - + ((double) (txbad - txBad) * 0.5); - txSuccessRate = (txSuccessRate * 0.5) - + ((double) (txgood - txSuccess) * 0.5); - rxSuccessRate = (rxSuccessRate * 0.5) - + ((double) (rxgood - rxSuccess) * 0.5); - txRetriesRate = (txRetriesRate * 0.5) - + ((double) (txretries - txRetries) * 0.5); - + if (txBad <= txbad + && txSuccess <= txgood + && rxSuccess <= rxgood + && txRetries <= txretries) { + txBadRate = (txBadRate * 0.5) + + ((double) (txbad - txBad) * 0.5); + txSuccessRate = (txSuccessRate * 0.5) + + ((double) (txgood - txSuccess) * 0.5); + rxSuccessRate = (rxSuccessRate * 0.5) + + ((double) (rxgood - rxSuccess) * 0.5); + txRetriesRate = (txRetriesRate * 0.5) + + ((double) (txretries - txRetries) * 0.5); + } else { + txBadRate = 0; + txSuccessRate = 0; + rxSuccessRate = 0; + txRetriesRate = 0; + } txBad = txbad; txSuccess = txgood; rxSuccess = rxgood; @@ -204,11 +213,15 @@ public class WifiInfo implements Parcelable { txRetries = 0; txBadRate = 0; txRetriesRate = 0; - - txSuccessRate = (txSuccessRate * 0.5) - + ((double) (txPackets - txSuccess) * 0.5); - rxSuccessRate = (rxSuccessRate * 0.5) - + ((double) (rxPackets - rxSuccess) * 0.5); + if (txSuccess <= txPackets && rxSuccess <= rxPackets) { + txSuccessRate = (txSuccessRate * 0.5) + + ((double) (txPackets - txSuccess) * 0.5); + rxSuccessRate = (rxSuccessRate * 0.5) + + ((double) (rxPackets - rxSuccess) * 0.5); + } else { + txBadRate = 0; + txRetriesRate = 0; + } txSuccess = txPackets; rxSuccess = rxPackets; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 64fa0e5226e6..d00c65414229 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -399,14 +399,16 @@ public class WifiManager { public static final int CHANGE_REASON_CONFIG_CHANGE = 2; /** * An access point scan has completed, and results are available from the supplicant. - * Call {@link #getScanResults()} to obtain the results. + * Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED} + * indicates if the scan was completed successfully. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS"; /** - * The result of previous scan, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}. - * @return true scan was successful, results updated + * Lookup key for a {@code boolean} representing the result of previous {@link #startScan} + * operation, reported with {@link #SCAN_RESULTS_AVAILABLE_ACTION}. + * @return true scan was successful, results are updated * @return false scan was not successful, results haven't been updated since previous scan */ public static final String EXTRA_RESULTS_UPDATED = "resultsUpdated"; |