diff options
128 files changed, 2138 insertions, 1276 deletions
@@ -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/IOnPermissionsChangeListener.aidl \ core/java/android/database/IContentObserver.aidl \ core/java/android/hardware/ICameraService.aidl \ core/java/android/hardware/ICameraServiceListener.aidl \ diff --git a/api/current.txt b/api/current.txt index 6cd3932..567b172 100644 --- a/api/current.txt +++ b/api/current.txt @@ -222,6 +222,12 @@ package android { ctor public R.attr(); field public static final int __reserved0 = 16844020; // 0x10104f4 field public static final int __reserved1 = 16844019; // 0x10104f3 + field public static final int __reserved2 = 16843999; // 0x10104df + field public static final int __reserved3 = 16844000; // 0x10104e0 + field public static final int __reserved4 = 16844001; // 0x10104e1 + field public static final int __reserved5 = 16844002; // 0x10104e2 + field public static final int __reserved6 = 16844003; // 0x10104e3 + field public static final int __reserved7 = 16844004; // 0x10104e4 field public static final int absListViewStyle = 16842858; // 0x101006a field public static final int accessibilityEventTypes = 16843648; // 0x1010380 field public static final int accessibilityFeedbackType = 16843650; // 0x1010382 @@ -570,7 +576,7 @@ package android { field public static final int fillViewport = 16843130; // 0x101017a field public static final int filter = 16843035; // 0x101011b field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4 - field public static final int fingerprintDrawable = 16844025; // 0x10104f9 + field public static final int fingerprintAuthDrawable = 16844025; // 0x10104f9 field public static final int finishOnCloseSystemDialogs = 16843431; // 0x10102a7 field public static final int finishOnTaskLaunch = 16842772; // 0x1010014 field public static final int firstDayOfWeek = 16843581; // 0x101033d @@ -661,8 +667,6 @@ package android { field public static final int hyphenationFrequency = 16844024; // 0x10104f8 field public static final int icon = 16842754; // 0x1010002 field public static final int iconPreview = 16843337; // 0x1010249 - field public static final int iconTint = 16843999; // 0x10104df - field public static final int iconTintMode = 16844000; // 0x10104e0 field public static final int iconifiedByDefault = 16843514; // 0x10102fa field public static final int id = 16842960; // 0x10100d0 field public static final int ignoreGravity = 16843263; // 0x10101ff @@ -874,8 +878,6 @@ package android { field public static final int navigationContentDescription = 16843969; // 0x10104c1 field public static final int navigationIcon = 16843968; // 0x10104c0 field public static final int navigationMode = 16843471; // 0x10102cf - field public static final int navigationTint = 16844003; // 0x10104e3 - field public static final int navigationTintMode = 16844004; // 0x10104e4 field public static final int negativeButtonText = 16843254; // 0x10101f6 field public static final int nestedScrollingEnabled = 16843830; // 0x1010436 field public static final int nextFocusDown = 16842980; // 0x10100e4 @@ -907,8 +909,6 @@ package android { field public static final int overScrollFooter = 16843459; // 0x10102c3 field public static final int overScrollHeader = 16843458; // 0x10102c2 field public static final int overScrollMode = 16843457; // 0x10102c1 - field public static final int overflowTint = 16844001; // 0x10104e1 - field public static final int overflowTintMode = 16844002; // 0x10104e2 field public static final int overlapAnchor = 16843874; // 0x1010462 field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2 field public static final int packageNames = 16843649; // 0x1010381 @@ -7721,6 +7721,7 @@ package android.content { method public final java.lang.String getString(int, java.lang.Object...); method public abstract java.lang.Object getSystemService(java.lang.String); method public final T getSystemService(java.lang.Class<T>); + method public abstract java.lang.String getSystemServiceName(java.lang.Class<?>); method public final java.lang.CharSequence getText(int); method public abstract android.content.res.Resources.Theme getTheme(); method public abstract deprecated android.graphics.drawable.Drawable getWallpaper(); @@ -17210,7 +17211,7 @@ package android.media.browse { method public void connect(); method public void disconnect(); method public android.os.Bundle getExtras(); - method public void getMediaItem(java.lang.String, android.media.browse.MediaBrowser.MediaItemCallback); + method public void getItem(java.lang.String, android.media.browse.MediaBrowser.ItemCallback); method public java.lang.String getRoot(); method public android.content.ComponentName getServiceComponent(); method public android.media.session.MediaSession.Token getSessionToken(); @@ -17226,6 +17227,12 @@ package android.media.browse { method public void onConnectionSuspended(); } + public static abstract class MediaBrowser.ItemCallback { + ctor public MediaBrowser.ItemCallback(); + method public void onError(java.lang.String); + method public void onItemLoaded(android.media.browse.MediaBrowser.MediaItem); + } + public static class MediaBrowser.MediaItem implements android.os.Parcelable { ctor public MediaBrowser.MediaItem(android.media.MediaDescription, int); method public int describeContents(); @@ -17240,12 +17247,6 @@ package android.media.browse { field public static final int FLAG_PLAYABLE = 2; // 0x2 } - public static abstract class MediaBrowser.MediaItemCallback { - ctor public MediaBrowser.MediaItemCallback(); - method public void onError(); - method public void onMediaItemLoaded(android.media.browse.MediaBrowser.MediaItem); - } - public static abstract class MediaBrowser.SubscriptionCallback { ctor public MediaBrowser.SubscriptionCallback(); method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>); @@ -24476,6 +24477,7 @@ package android.printservice { method protected abstract void onPrintJobQueued(android.printservice.PrintJob); method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob); field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO"; + field public static final java.lang.String EXTRA_PRINT_DOCUMENT_INFO = "android.printservice.extra.PRINT_DOCUMENT_INFO"; field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO"; field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService"; field public static final java.lang.String SERVICE_META_DATA = "android.printservice"; @@ -26537,6 +26539,7 @@ package android.provider { field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS"; field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS"; field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS"; + field public static final java.lang.String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS"; @@ -28786,12 +28789,12 @@ package android.service.media { public abstract class MediaBrowserService extends android.app.Service { ctor public MediaBrowserService(); method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]); - method public void getMediaItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>) throws java.lang.UnsupportedOperationException; method public android.media.session.MediaSession.Token getSessionToken(); method public void notifyChildrenChanged(java.lang.String); method public android.os.IBinder onBind(android.content.Intent); method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle); method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>); + method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>); method public void setSessionToken(android.media.session.MediaSession.Token); field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService"; } @@ -30734,7 +30737,7 @@ package android.telephony { field public static final java.lang.String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool"; field public static final java.lang.String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool"; field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool"; - field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_BOOL = "voice_privacy_disable_bool"; + field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool"; field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int"; field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool"; } @@ -35490,8 +35493,6 @@ package android.view { method public abstract android.view.MenuItem setEnabled(boolean); method public abstract android.view.MenuItem setIcon(android.graphics.drawable.Drawable); method public abstract android.view.MenuItem setIcon(int); - method public abstract android.view.MenuItem setIconTintList(android.content.res.ColorStateList); - method public abstract android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); @@ -39552,14 +39553,14 @@ package android.widget { ctor public ActionMenuView(android.content.Context, android.util.AttributeSet); method public void dismissPopupMenus(); method public android.view.Menu getMenu(); + method public android.graphics.drawable.Drawable getOverflowIcon(); method public int getPopupTheme(); method public boolean hideOverflowMenu(); method public boolean isOverflowMenuShowing(); method public void onConfigurationChanged(android.content.res.Configuration); method public void onDetachedFromWindow(); method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener); - method public void setOverflowTintList(android.content.res.ColorStateList); - method public void setOverflowTintMode(android.graphics.PorterDuff.Mode); + method public void setOverflowIcon(android.graphics.drawable.Drawable); method public void setPopupTheme(int); method public boolean showOverflowMenu(); } @@ -41849,6 +41850,7 @@ package android.widget { method public android.view.Menu getMenu(); method public java.lang.CharSequence getNavigationContentDescription(); method public android.graphics.drawable.Drawable getNavigationIcon(); + method public android.graphics.drawable.Drawable getOverflowIcon(); method public int getPopupTheme(); method public java.lang.CharSequence getSubtitle(); method public java.lang.CharSequence getTitle(); @@ -41868,11 +41870,8 @@ package android.widget { method public void setNavigationIcon(int); method public void setNavigationIcon(android.graphics.drawable.Drawable); method public void setNavigationOnClickListener(android.view.View.OnClickListener); - method public void setNavigationTintList(android.content.res.ColorStateList); - method public void setNavigationTintMode(android.graphics.PorterDuff.Mode); method public void setOnMenuItemClickListener(android.widget.Toolbar.OnMenuItemClickListener); - method public void setOverflowTintList(android.content.res.ColorStateList); - method public void setOverflowTintMode(android.graphics.PorterDuff.Mode); + method public void setOverflowIcon(android.graphics.drawable.Drawable); method public void setPopupTheme(int); method public void setSubtitle(int); method public void setSubtitle(java.lang.CharSequence); diff --git a/api/system-current.txt b/api/system-current.txt index 810bed4..a4e4848 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -297,6 +297,12 @@ package android { ctor public R.attr(); field public static final int __reserved0 = 16844020; // 0x10104f4 field public static final int __reserved1 = 16844019; // 0x10104f3 + field public static final int __reserved2 = 16843999; // 0x10104df + field public static final int __reserved3 = 16844000; // 0x10104e0 + field public static final int __reserved4 = 16844001; // 0x10104e1 + field public static final int __reserved5 = 16844002; // 0x10104e2 + field public static final int __reserved6 = 16844003; // 0x10104e3 + field public static final int __reserved7 = 16844004; // 0x10104e4 field public static final int absListViewStyle = 16842858; // 0x101006a field public static final int accessibilityEventTypes = 16843648; // 0x1010380 field public static final int accessibilityFeedbackType = 16843650; // 0x1010382 @@ -645,7 +651,7 @@ package android { field public static final int fillViewport = 16843130; // 0x101017a field public static final int filter = 16843035; // 0x101011b field public static final int filterTouchesWhenObscured = 16843460; // 0x10102c4 - field public static final int fingerprintDrawable = 16844025; // 0x10104f9 + field public static final int fingerprintAuthDrawable = 16844025; // 0x10104f9 field public static final int finishOnCloseSystemDialogs = 16843431; // 0x10102a7 field public static final int finishOnTaskLaunch = 16842772; // 0x1010014 field public static final int firstDayOfWeek = 16843581; // 0x101033d @@ -736,8 +742,6 @@ package android { field public static final int hyphenationFrequency = 16844024; // 0x10104f8 field public static final int icon = 16842754; // 0x1010002 field public static final int iconPreview = 16843337; // 0x1010249 - field public static final int iconTint = 16843999; // 0x10104df - field public static final int iconTintMode = 16844000; // 0x10104e0 field public static final int iconifiedByDefault = 16843514; // 0x10102fa field public static final int id = 16842960; // 0x10100d0 field public static final int ignoreGravity = 16843263; // 0x10101ff @@ -949,8 +953,6 @@ package android { field public static final int navigationContentDescription = 16843969; // 0x10104c1 field public static final int navigationIcon = 16843968; // 0x10104c0 field public static final int navigationMode = 16843471; // 0x10102cf - field public static final int navigationTint = 16844003; // 0x10104e3 - field public static final int navigationTintMode = 16844004; // 0x10104e4 field public static final int negativeButtonText = 16843254; // 0x10101f6 field public static final int nestedScrollingEnabled = 16843830; // 0x1010436 field public static final int nextFocusDown = 16842980; // 0x10100e4 @@ -982,8 +984,6 @@ package android { field public static final int overScrollFooter = 16843459; // 0x10102c3 field public static final int overScrollHeader = 16843458; // 0x10102c2 field public static final int overScrollMode = 16843457; // 0x10102c1 - field public static final int overflowTint = 16844001; // 0x10104e1 - field public static final int overflowTintMode = 16844002; // 0x10104e2 field public static final int overlapAnchor = 16843874; // 0x1010462 field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2 field public static final int packageNames = 16843649; // 0x1010381 @@ -7944,6 +7944,7 @@ package android.content { method public final java.lang.String getString(int, java.lang.Object...); method public abstract java.lang.Object getSystemService(java.lang.String); method public final T getSystemService(java.lang.Class<T>); + method public abstract java.lang.String getSystemServiceName(java.lang.Class<?>); method public final java.lang.CharSequence getText(int); method public abstract android.content.res.Resources.Theme getTheme(); method public abstract deprecated android.graphics.drawable.Drawable getWallpaper(); @@ -9521,6 +9522,7 @@ package android.content.pm { public abstract class PackageManager { ctor public PackageManager(); + method public abstract void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract deprecated void addPackageToPreferred(java.lang.String); method public abstract boolean addPermission(android.content.pm.PermissionInfo); method public abstract boolean addPermissionAsync(android.content.pm.PermissionInfo); @@ -9594,6 +9596,7 @@ package android.content.pm { method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(android.content.Intent, int); method public abstract java.util.List<android.content.pm.ResolveInfo> queryIntentServices(android.content.Intent, int); method public abstract java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public abstract void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public abstract deprecated void removePackageFromPreferred(java.lang.String); method public abstract void removePermission(java.lang.String); method public abstract android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int); @@ -9769,6 +9772,10 @@ package android.content.pm { ctor public PackageManager.NameNotFoundException(java.lang.String); } + public static abstract interface PackageManager.OnPermissionsChangedListener { + method public abstract void onPermissionsChanged(int); + } + public static abstract class PackageManager.PermissionFlags implements java.lang.annotation.Annotation { } @@ -18522,7 +18529,7 @@ package android.media.browse { method public void connect(); method public void disconnect(); method public android.os.Bundle getExtras(); - method public void getMediaItem(java.lang.String, android.media.browse.MediaBrowser.MediaItemCallback); + method public void getItem(java.lang.String, android.media.browse.MediaBrowser.ItemCallback); method public java.lang.String getRoot(); method public android.content.ComponentName getServiceComponent(); method public android.media.session.MediaSession.Token getSessionToken(); @@ -18538,6 +18545,12 @@ package android.media.browse { method public void onConnectionSuspended(); } + public static abstract class MediaBrowser.ItemCallback { + ctor public MediaBrowser.ItemCallback(); + method public void onError(java.lang.String); + method public void onItemLoaded(android.media.browse.MediaBrowser.MediaItem); + } + public static class MediaBrowser.MediaItem implements android.os.Parcelable { ctor public MediaBrowser.MediaItem(android.media.MediaDescription, int); method public int describeContents(); @@ -18552,12 +18565,6 @@ package android.media.browse { field public static final int FLAG_PLAYABLE = 2; // 0x2 } - public static abstract class MediaBrowser.MediaItemCallback { - ctor public MediaBrowser.MediaItemCallback(); - method public void onError(); - method public void onMediaItemLoaded(android.media.browse.MediaBrowser.MediaItem); - } - public static abstract class MediaBrowser.SubscriptionCallback { ctor public MediaBrowser.SubscriptionCallback(); method public void onChildrenLoaded(java.lang.String, java.util.List<android.media.browse.MediaBrowser.MediaItem>); @@ -19194,7 +19201,9 @@ package android.media.tv { method public android.content.Intent createSettingsIntent(); method public android.content.Intent createSetupIntent(); method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.hardware.hdmi.HdmiDeviceInfo, java.lang.String, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, java.lang.String, android.net.Uri) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; + method public static android.media.tv.TvInputInfo createTvInputInfo(android.content.Context, android.content.pm.ResolveInfo, android.media.tv.TvInputHardwareInfo, int, android.graphics.drawable.Icon) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public int describeContents(); method public android.hardware.hdmi.HdmiDeviceInfo getHdmiDeviceInfo(); method public java.lang.String getId(); @@ -26406,6 +26415,7 @@ package android.printservice { method protected abstract void onPrintJobQueued(android.printservice.PrintJob); method protected abstract void onRequestCancelPrintJob(android.printservice.PrintJob); field public static final java.lang.String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO"; + field public static final java.lang.String EXTRA_PRINT_DOCUMENT_INFO = "android.printservice.extra.PRINT_DOCUMENT_INFO"; field public static final java.lang.String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO"; field public static final java.lang.String SERVICE_INTERFACE = "android.printservice.PrintService"; field public static final java.lang.String SERVICE_META_DATA = "android.printservice"; @@ -28569,6 +28579,7 @@ package android.provider { field public static final java.lang.String ACTION_DISPLAY_SETTINGS = "android.settings.DISPLAY_SETTINGS"; field public static final java.lang.String ACTION_DREAM_SETTINGS = "android.settings.DREAM_SETTINGS"; field public static final java.lang.String ACTION_HOME_SETTINGS = "android.settings.HOME_SETTINGS"; + field public static final java.lang.String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SETTINGS = "android.settings.INPUT_METHOD_SETTINGS"; field public static final java.lang.String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS = "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS"; field public static final java.lang.String ACTION_INTERNAL_STORAGE_SETTINGS = "android.settings.INTERNAL_STORAGE_SETTINGS"; @@ -30819,12 +30830,12 @@ package android.service.media { public abstract class MediaBrowserService extends android.app.Service { ctor public MediaBrowserService(); method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]); - method public void getMediaItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>) throws java.lang.UnsupportedOperationException; method public android.media.session.MediaSession.Token getSessionToken(); method public void notifyChildrenChanged(java.lang.String); method public android.os.IBinder onBind(android.content.Intent); method public abstract android.service.media.MediaBrowserService.BrowserRoot onGetRoot(java.lang.String, int, android.os.Bundle); method public abstract void onLoadChildren(java.lang.String, android.service.media.MediaBrowserService.Result<java.util.List<android.media.browse.MediaBrowser.MediaItem>>); + method public void onLoadItem(java.lang.String, android.service.media.MediaBrowserService.Result<android.media.browse.MediaBrowser.MediaItem>); method public void setSessionToken(android.media.session.MediaSession.Token); field public static final java.lang.String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService"; } @@ -32950,7 +32961,7 @@ package android.telephony { field public static final java.lang.String KEY_USE_HFA_FOR_PROVISIONING_BOOL = "use_hfa_for_provisioning_bool"; field public static final java.lang.String KEY_USE_OTASP_FOR_PROVISIONING_BOOL = "use_otasp_for_provisioning_bool"; field public static final java.lang.String KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL = "voicemail_notification_persistent_bool"; - field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_BOOL = "voice_privacy_disable_bool"; + field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool"; field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int"; field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool"; } @@ -33515,6 +33526,10 @@ package android.telephony { field public static final int CALL_STATE_IDLE = 0; // 0x0 field public static final int CALL_STATE_OFFHOOK = 2; // 0x2 field public static final int CALL_STATE_RINGING = 1; // 0x1 + field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe + field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1 + field public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; // 0x0 + field public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; // 0xffffffff field public static final int DATA_ACTIVITY_DORMANT = 4; // 0x4 field public static final int DATA_ACTIVITY_IN = 1; // 0x1 field public static final int DATA_ACTIVITY_INOUT = 3; // 0x3 @@ -34152,6 +34167,7 @@ package android.test.mock { public class MockPackageManager extends android.content.pm.PackageManager { ctor public MockPackageManager(); + method public void addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public void addPackageToPreferred(java.lang.String); method public boolean addPermission(android.content.pm.PermissionInfo); method public boolean addPermissionAsync(android.content.pm.PermissionInfo); @@ -34226,6 +34242,7 @@ package android.test.mock { method public java.util.List<android.content.pm.ResolveInfo> queryIntentContentProviders(android.content.Intent, int); method public java.util.List<android.content.pm.ResolveInfo> queryIntentServices(android.content.Intent, int); method public java.util.List<android.content.pm.PermissionInfo> queryPermissionsByGroup(java.lang.String, int) throws android.content.pm.PackageManager.NameNotFoundException; + method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener); method public void removePackageFromPreferred(java.lang.String); method public void removePermission(java.lang.String); method public android.content.pm.ResolveInfo resolveActivity(android.content.Intent, int); @@ -37756,8 +37773,6 @@ package android.view { method public abstract android.view.MenuItem setEnabled(boolean); method public abstract android.view.MenuItem setIcon(android.graphics.drawable.Drawable); method public abstract android.view.MenuItem setIcon(int); - method public abstract android.view.MenuItem setIconTintList(android.content.res.ColorStateList); - method public abstract android.view.MenuItem setIconTintMode(android.graphics.PorterDuff.Mode); method public abstract android.view.MenuItem setIntent(android.content.Intent); method public abstract android.view.MenuItem setNumericShortcut(char); method public abstract android.view.MenuItem setOnActionExpandListener(android.view.MenuItem.OnActionExpandListener); @@ -42132,14 +42147,14 @@ package android.widget { ctor public ActionMenuView(android.content.Context, android.util.AttributeSet); method public void dismissPopupMenus(); method public android.view.Menu getMenu(); + method public android.graphics.drawable.Drawable getOverflowIcon(); method public int getPopupTheme(); method public boolean hideOverflowMenu(); method public boolean isOverflowMenuShowing(); method public void onConfigurationChanged(android.content.res.Configuration); method public void onDetachedFromWindow(); method public void setOnMenuItemClickListener(android.widget.ActionMenuView.OnMenuItemClickListener); - method public void setOverflowTintList(android.content.res.ColorStateList); - method public void setOverflowTintMode(android.graphics.PorterDuff.Mode); + method public void setOverflowIcon(android.graphics.drawable.Drawable); method public void setPopupTheme(int); method public boolean showOverflowMenu(); } @@ -44429,6 +44444,7 @@ package android.widget { method public android.view.Menu getMenu(); method public java.lang.CharSequence getNavigationContentDescription(); method public android.graphics.drawable.Drawable getNavigationIcon(); + method public android.graphics.drawable.Drawable getOverflowIcon(); method public int getPopupTheme(); method public java.lang.CharSequence getSubtitle(); method public java.lang.CharSequence getTitle(); @@ -44448,11 +44464,8 @@ package android.widget { method public void setNavigationIcon(int); method public void setNavigationIcon(android.graphics.drawable.Drawable); method public void setNavigationOnClickListener(android.view.View.OnClickListener); - method public void setNavigationTintList(android.content.res.ColorStateList); - method public void setNavigationTintMode(android.graphics.PorterDuff.Mode); method public void setOnMenuItemClickListener(android.widget.Toolbar.OnMenuItemClickListener); - method public void setOverflowTintList(android.content.res.ColorStateList); - method public void setOverflowTintMode(android.graphics.PorterDuff.Mode); + method public void setOverflowIcon(android.graphics.drawable.Drawable); method public void setPopupTheme(int); method public void setSubtitle(int); method public void setSubtitle(java.lang.CharSequence); diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index b0a7dc7..bf3b455 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -305,11 +305,23 @@ public class Am extends BaseCommand { " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" + " [--ecn <EXTRA_KEY> <EXTRA_COMPONENT_NAME_VALUE>]\n" + " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + + " (mutiple extras passed as Integer[])\n" + + " [--eial <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + + " (mutiple extras passed as List<Integer>)\n" + " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + + " (mutiple extras passed as Long[])\n" + + " [--elal <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + + " (mutiple extras passed as List<Long>)\n" + " [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" + + " (mutiple extras passed as Float[])\n" + + " [--efal <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" + + " (mutiple extras passed as List<Float>)\n" + " [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" + - " (to embed a comma into a string escape it using \"\\,\")\n" + - " [-n <COMPONENT>] [-p <PACKAGE>] [-f <FLAGS>]\n" + + " (mutiple extras passed as String[]; to embed a comma into a string,\n" + + " escape it using \"\\,\")\n" + + " [--esal <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" + + " (mutiple extras passed as List<String>; to embed a comma into a string,\n" + + " escape it using \"\\,\")\n" + " [--grant-read-uri-permission] [--grant-write-uri-permission]\n" + " [--grant-persistable-uri-permission] [--grant-prefix-uri-permission]\n" + " [--debug-log-resolution] [--exclude-stopped-packages]\n" + @@ -490,6 +502,15 @@ public class Am extends BaseCommand { list[i] = Integer.decode(strings[i]); } intent.putExtra(key, list); + } else if (opt.equals("--eial")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Integer> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Integer.decode(strings[i])); + } + intent.putExtra(key, list); } else if (opt.equals("--el")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -504,6 +525,16 @@ public class Am extends BaseCommand { } intent.putExtra(key, list); hasIntentInfo = true; + } else if (opt.equals("--elal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Long> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Long.valueOf(strings[i])); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--ef")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -519,6 +550,16 @@ public class Am extends BaseCommand { } intent.putExtra(key, list); hasIntentInfo = true; + } else if (opt.equals("--efal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + String[] strings = value.split(","); + ArrayList<Float> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(Float.valueOf(strings[i])); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--esa")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -528,6 +569,19 @@ public class Am extends BaseCommand { String[] strings = value.split("(?<!\\\\),"); intent.putExtra(key, strings); hasIntentInfo = true; + } else if (opt.equals("--esal")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + // Split on commas unless they are preceeded by an escape. + // The escape character must be escaped for the string and + // again for the regex, thus four escape characters become one. + String[] strings = value.split("(?<!\\\\),"); + ArrayList<String> list = new ArrayList<>(strings.length); + for (int i = 0; i < strings.length; i++) { + list.add(strings[i]); + } + intent.putExtra(key, list); + hasIntentInfo = true; } else if (opt.equals("--ez")) { String key = nextArgRequired(); String value = nextArgRequired().toLowerCase(); diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 41e3db8..cb1e7aa 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -31,6 +31,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.ContainerEncryptionParams; import android.content.pm.FeatureInfo; +import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageDeleteObserver; import android.content.pm.IPackageInstallObserver; @@ -88,6 +89,7 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Objects; /*package*/ @@ -1048,6 +1050,38 @@ final class ApplicationPackageManager extends PackageManager { } } + @Override + public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) { + synchronized (mPermissionListeners) { + if (mPermissionListeners.get(listener) != null) { + return; + } + OnPermissionsChangeListenerDelegate delegate = + new OnPermissionsChangeListenerDelegate(listener, Looper.getMainLooper()); + try { + mPM.addOnPermissionsChangeListener(delegate); + mPermissionListeners.put(listener, delegate); + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + } + } + + @Override + public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) { + synchronized (mPermissionListeners) { + IOnPermissionsChangeListener delegate = mPermissionListeners.get(listener); + if (delegate != null) { + try { + mPM.removeOnPermissionsChangeListener(delegate); + mPermissionListeners.remove(listener); + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + } + } + } + static void configurationChanged() { synchronized (sSync) { sIconCache.clear(); @@ -2139,4 +2173,39 @@ final class ApplicationPackageManager extends PackageManager { = new ArrayMap<ResourceName, WeakReference<Drawable.ConstantState>>(); private static ArrayMap<ResourceName, WeakReference<CharSequence>> sStringCache = new ArrayMap<ResourceName, WeakReference<CharSequence>>(); + + private final Map<OnPermissionsChangedListener, IOnPermissionsChangeListener> + mPermissionListeners = new ArrayMap<>(); + + public class OnPermissionsChangeListenerDelegate extends IOnPermissionsChangeListener.Stub + implements Handler.Callback{ + private static final int MSG_PERMISSIONS_CHANGED = 1; + + private final OnPermissionsChangedListener mListener; + private final Handler mHandler; + + + public OnPermissionsChangeListenerDelegate(OnPermissionsChangedListener listener, + Looper looper) { + mListener = listener; + mHandler = new Handler(looper, this); + } + + @Override + public void onPermissionsChanged(int uid) { + mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); + } + + @Override + public boolean handleMessage(Message msg) { + switch (msg.what) { + case MSG_PERMISSIONS_CHANGED: { + final int uid = msg.arg1; + mListener.onPermissionsChanged(uid); + return true; + } + } + return false; + } + } } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 3ab0e01..bf44746 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2275,7 +2275,7 @@ public class DevicePolicyManager { if (mService != null) { try { final String alias = getCaCertAlias(certBuffer); - mService.uninstallCaCert(admin, alias); + mService.uninstallCaCerts(admin, new String[] {alias}); } catch (CertificateException e) { Log.w(TAG, "Unable to parse certificate", e); } catch (RemoteException e) { @@ -2322,12 +2322,11 @@ public class DevicePolicyManager { */ public void uninstallAllUserCaCerts(@Nullable ComponentName admin) { if (mService != null) { - for (String alias : new TrustedCertificateStore().userAliases()) { - try { - mService.uninstallCaCert(admin, alias); - } catch (RemoteException re) { - Log.w(TAG, "Failed talking with device policy service", re); - } + try { + mService.uninstallCaCerts(admin, new TrustedCertificateStore().userAliases() + .toArray(new String[0])); + } catch (RemoteException re) { + Log.w(TAG, "Failed talking with device policy service", re); } } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 8c7b20a..a700806 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -128,7 +128,7 @@ interface IDevicePolicyManager { boolean hasUserSetupCompleted(); boolean installCaCert(in ComponentName admin, in byte[] certBuffer); - void uninstallCaCert(in ComponentName admin, in String alias); + void uninstallCaCerts(in ComponentName admin, in String[] aliases); void enforceCanManageCaCerts(in ComponentName admin); boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias); diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index 49ac062..fd1e24a 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -28,6 +28,11 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +/** + * Represents a single operation to be performed as part of a batch of operations. + * + * @see ContentProvider#applyBatch(ArrayList) + */ public class ContentProviderOperation implements Parcelable { /** @hide exposed for unit tests */ public final static int TYPE_INSERT = 1; @@ -195,10 +200,19 @@ public class ContentProviderOperation implements Parcelable { return new Builder(TYPE_ASSERT, uri); } + /** + * Gets the Uri for the target of the operation. + */ public Uri getUri() { return mUri; } + /** + * Returns true if the operation allows yielding the database to other transactions + * if the database is contended. + * + * @see android.database.sqlite.SQLiteDatabase#yieldIfContendedSafely() + */ public boolean isYieldAllowed() { return mYieldAllowed; } @@ -208,26 +222,58 @@ public class ContentProviderOperation implements Parcelable { return mType; } + /** + * Returns true if the operation represents an insertion. + * + * @see #newInsert + */ public boolean isInsert() { return mType == TYPE_INSERT; } + /** + * Returns true if the operation represents a deletion. + * + * @see #newDelete + */ public boolean isDelete() { return mType == TYPE_DELETE; } + /** + * Returns true if the operation represents an update. + * + * @see #newUpdate + */ public boolean isUpdate() { return mType == TYPE_UPDATE; } + /** + * Returns true if the operation represents an assert query. + * + * @see #newAssertQuery + */ public boolean isAssertQuery() { return mType == TYPE_ASSERT; } + /** + * Returns true if the operation represents an insertion, deletion, or update. + * + * @see #isInsert + * @see #isDelete + * @see #isUpdate + */ public boolean isWriteOperation() { return mType == TYPE_DELETE || mType == TYPE_INSERT || mType == TYPE_UPDATE; } + /** + * Returns true if the operation represents an assert query. + * + * @see #isAssertQuery + */ public boolean isReadOperation() { return mType == TYPE_ASSERT; } @@ -617,7 +663,7 @@ public class ContentProviderOperation implements Parcelable { } /** - * If set then if the number of rows affected by this operation do not match + * If set then if the number of rows affected by this operation does not match * this count {@link OperationApplicationException} will be throw. * This can only be used with builders of type update, delete, or assert. * @return this builder, to allow for chaining. @@ -631,6 +677,12 @@ public class ContentProviderOperation implements Parcelable { return this; } + /** + * If set to true then the operation allows yielding the database to other transactions + * if the database is contended. + * @return this builder, to allow for chaining. + * @see android.database.sqlite.SQLiteDatabase#yieldIfContendedSafely() + */ public Builder withYieldAllowed(boolean yieldAllowed) { mYieldAllowed = yieldAllowed; return this; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index a434c7b..970623a 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1256,7 +1256,7 @@ public abstract class Context { * @param intent The description of the activity to start. * * @throws ActivityNotFoundException - * + *` * @see #startActivity(Intent, Bundle) * @see PackageManager#resolveActivity */ @@ -2443,8 +2443,6 @@ public abstract class Context { * * @param serviceClass The class of the desired service. * @return The service name or null if the class is not a supported system service. - * - * @hide */ public abstract String getSystemServiceName(Class<?> serviceClass); diff --git a/core/java/android/content/pm/IOnPermissionsChangeListener.aidl b/core/java/android/content/pm/IOnPermissionsChangeListener.aidl new file mode 100644 index 0000000..7791b50 --- /dev/null +++ b/core/java/android/content/pm/IOnPermissionsChangeListener.aidl @@ -0,0 +1,25 @@ +/* + * 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.content.pm; + +/** + * Listener for changes in the permissions for installed packages. + * {@hide} + */ +oneway interface IOnPermissionsChangeListener { + void onPermissionsChanged(int uid); +} diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 00b8c71..0c07bc3 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.IOnPermissionsChangeListener; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.InstrumentationInfo; import android.content.pm.KeySet; @@ -490,4 +491,7 @@ interface IPackageManager { KeySet getSigningKeySet(String packageName); boolean isPackageSignedByKeySet(String packageName, in KeySet ks); boolean isPackageSignedByKeySetExactly(String packageName, in KeySet ks); + + void addOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); + void removeOnPermissionsChangeListener(in IOnPermissionsChangeListener listener); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 68092c8..bd50ca0 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -16,11 +16,13 @@ package android.content.pm; +import android.Manifest; import android.annotation.CheckResult; import android.annotation.DrawableRes; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.StringRes; @@ -78,6 +80,21 @@ public abstract class PackageManager { } /** + * Listener for changes in permissions granted to a UID. + * + * @hide + */ + @SystemApi + public interface OnPermissionsChangedListener { + + /** + * Called when the permissions for a UID change. + * @param uid The UID with a change. + */ + public void onPermissionsChanged(int uid); + } + + /** * {@link PackageInfo} flag: return information about * activities in the package in {@link PackageInfo#activities}. */ @@ -2636,7 +2653,7 @@ public abstract class PackageManager { /** * Retrieve the official name associated with a user id. This name is - * guaranteed to never change, though it is possibly for the underlying + * guaranteed to never change, though it is possible for the underlying * user id to be changed. That is, if you are storing information about * user ids in persistent storage, you should use the string returned * by this function instead of the raw user-id. @@ -4295,6 +4312,27 @@ public abstract class PackageManager { public abstract boolean isSafeMode(); /** + * Adds a listener for permission changes for installed packages. + * + * @param listener The listener to add. + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS) + public abstract void addOnPermissionsChangeListener(OnPermissionsChangedListener listener); + + /** + * Remvoes a listener for permission changes for installed packages. + * + * @param listener The listener to remove. + * + * @hide + */ + @SystemApi + public abstract void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener); + + /** * Return the {@link KeySet} associated with the String alias for this * application. * diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index fda889f..d6b1142 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -1577,7 +1577,7 @@ public abstract class SensorManager { * Significant Motion, Step Counter etc. * * The tests which call this API need to have {@code - * android.permission.HARDWARE_TEST} permission which isn't + * android.permission.LOCATION_HADWARE} permission which isn't * available for third party applications. * * @param enable True to set the HAL in DATA_INJECTION mode. @@ -1607,7 +1607,7 @@ public abstract class SensorManager { * the HAL is already in data injection mode. * * The tests which call this API need to have {@code - * android.permission.HARDWARE_TEST} permission which isn't + * android.permission.LOCATION_HARDWARE} permission which isn't * available for third party applications. * * @param sensor The sensor to inject. diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 22a9e9c..d7960af 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -80,7 +80,7 @@ public class SystemSensorManager extends SensorManager { nativeClassInit(); } mHasDataInjectionPermissions = context.checkSelfPermission( - Manifest.permission.HARDWARE_TEST) == PackageManager.PERMISSION_GRANTED; + Manifest.permission.LOCATION_HARDWARE) == PackageManager.PERMISSION_GRANTED; } // initialize the sensor list @@ -233,7 +233,7 @@ public class SystemSensorManager extends SensorManager { protected boolean enableDataInjectionImpl(boolean enable) { if (!mHasDataInjectionPermissions) { throw new SecurityException("Permission denial. Calling enableDataInjection without " - + Manifest.permission.HARDWARE_TEST); + + Manifest.permission.LOCATION_HARDWARE); } synchronized (mLock) { int ret = nativeEnableDataInjection(mNativeInstance, enable); @@ -256,7 +256,7 @@ public class SystemSensorManager extends SensorManager { long timestamp) { if (!mHasDataInjectionPermissions) { throw new SecurityException("Permission denial. Calling injectSensorData without " - + Manifest.permission.HARDWARE_TEST); + + Manifest.permission.LOCATION_HARDWARE); } synchronized (mLock) { if (!mDataInjectionMode) { diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index c073ba5..ed167f0 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -1924,6 +1924,28 @@ public class CameraDeviceImpl extends CameraDevice { return mCharacteristics; } + /** + * A high speed output surface can only be preview or hardware encoder surface. + * + * @param surface The high speed output surface to be checked. + */ + private void checkHighSpeedSurfaceFormat(Surface surface) { + // TODO: remove this override since the default format should be + // ImageFormat.PRIVATE. b/9487482 + final int HAL_FORMAT_RGB_START = 1; // HAL_PIXEL_FORMAT_RGBA_8888 from graphics.h + final int HAL_FORMAT_RGB_END = 5; // HAL_PIXEL_FORMAT_BGRA_8888 from graphics.h + int surfaceFormat = SurfaceUtils.getSurfaceFormat(surface); + if (surfaceFormat >= HAL_FORMAT_RGB_START && + surfaceFormat <= HAL_FORMAT_RGB_END) { + surfaceFormat = ImageFormat.PRIVATE; + } + + if (surfaceFormat != ImageFormat.PRIVATE) { + throw new IllegalArgumentException("Surface format(" + surfaceFormat + ") is not" + + " for preview or hardware video encoding!"); + } + } + private void checkConstrainedHighSpeedSurfaces(Collection<Surface> surfaces, Range<Integer> fpsRange) { if (surfaces == null || surfaces.size() == 0 || surfaces.size() > 2) { @@ -1948,15 +1970,10 @@ public class CameraDeviceImpl extends CameraDevice { } for (Surface surface : surfaces) { + checkHighSpeedSurfaceFormat(surface); + // Surface size must be supported high speed sizes. Size surfaceSize = SurfaceUtils.getSurfaceSize(surface); - int surfaceFormat = SurfaceUtils.getSurfaceFormat(surface); - - if (surfaceFormat != ImageFormat.PRIVATE) { - throw new IllegalArgumentException("Surface format is not for preview or" - + " hardware video encoding" + surfaceFormat); - } - if (!highSpeedSizes.contains(surfaceSize)) { throw new IllegalArgumentException("Surface size " + surfaceSize.toString() + " is" + " not part of the high speed supported size list " + diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index cc9d496..a3a998e 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -565,7 +565,7 @@ public class LegacyCameraDevice implements AutoCloseable { throw new IllegalArgumentException("Surface was abandoned", e); } - return previewConsumer && (surfaceFormat == ImageFormat.PRIVATE); + return previewConsumer; } public static boolean isVideoEncoderConsumer(Surface output) { @@ -583,7 +583,7 @@ public class LegacyCameraDevice implements AutoCloseable { throw new IllegalArgumentException("Surface was abandoned", e); } - return videoEncoderConsumer && (surfaceFormat == ImageFormat.PRIVATE); + return videoEncoderConsumer; } /** diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java index 32e74e2..40005a5 100644 --- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java +++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java @@ -16,6 +16,7 @@ package android.hardware.camera2.utils; +import android.graphics.ImageFormat; import android.hardware.camera2.legacy.LegacyCameraDevice; import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException; import android.util.Size; @@ -27,7 +28,7 @@ import android.view.Surface; public class SurfaceUtils { /** - * Check if a surface is for preview consumer. + * Check if a surface is for preview consumer based on consumer end point Gralloc usage flags. * * @param surface The surface to be checked. * @return true if the surface is for preview consumer, false otherwise. @@ -37,7 +38,8 @@ public class SurfaceUtils { } /** - * Check if the surface is for hardware video encoder consumer. + * Check if the surface is for hardware video encoder consumer based on consumer end point + * Gralloc usage flags. * * @param surface The surface to be checked. * @return true if the surface is for hardware video encoder consumer, false otherwise. diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl index 881dc0f..31a6a96 100644 --- a/core/java/android/hardware/usb/IUsbManager.aidl +++ b/core/java/android/hardware/usb/IUsbManager.aidl @@ -85,6 +85,16 @@ interface IUsbManager /* Sets the current USB function. */ void setCurrentFunction(String function); + /* Sets whether USB data (for example, MTP exposed pictures) should be made + * available on the USB connection. Unlocking data should only be done with + * user involvement, since exposing pictures or other data could leak sensitive + * user information. + */ + void setUsbDataUnlocked(boolean unlock); + + /* Returns true iff sensitive user data is exposed on the USB connection. */ + boolean isUsbDataUnlocked(); + /* Allow USB debugging from the attached host. If alwaysAllow is true, add the * the public key to list of host keys that the user has approved. */ diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java index 000d41f..c83f466 100644 --- a/core/java/android/hardware/usb/UsbManager.java +++ b/core/java/android/hardware/usb/UsbManager.java @@ -142,6 +142,16 @@ public class UsbManager { public static final String USB_CONFIGURED = "configured"; /** + * Boolean extra indicating whether confidential user data, such as photos, should be + * made available on the USB connection. This variable will only be set when the user + * has explicitly asked for this data to be unlocked. + * Used in extras for the {@link #ACTION_USB_STATE} broadcast. + * + * {@hide} + */ + public static final String USB_DATA_UNLOCKED = "unlocked"; + + /** * Name of the USB mass storage USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * @@ -464,4 +474,34 @@ public class UsbManager { Log.e(TAG, "RemoteException in setCurrentFunction", e); } } + + /** + * Sets whether USB data (for example, MTP exposed pictures) should be made available + * on the USB connection. Unlocking usb data should only be done with user involvement, + * since exposing pictures or other data could leak sensitive user information. + * + * {@hide} + */ + public void setUsbDataUnlocked(boolean unlocked) { + try { + mService.setUsbDataUnlocked(unlocked); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in setUsbDataUnlocked", e); + } + } + + /** + * Returns {@code true} iff access to sensitive USB data is currently allowed. + * + * {@hide} + */ + public boolean isUsbDataUnlocked() { + try { + return mService.isUsbDataUnlocked(); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in isUsbDataUnlocked", e); + } + return false; + } + } diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java index e47220b..5f46c73 100644 --- a/core/java/android/net/NetworkFactory.java +++ b/core/java/android/net/NetworkFactory.java @@ -24,8 +24,13 @@ import android.os.Messenger; import android.util.Log; import android.util.SparseArray; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Protocol; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * A NetworkFactory is an entity that creates NetworkAgent objects. * The bearers register with ConnectivityService using {@link #register} and @@ -157,6 +162,11 @@ public class NetworkFactory extends Handler { this.score = score; this.requested = false; } + + @Override + public String toString() { + return "{" + request + ", score=" + score + ", requested=" + requested + "}"; + } } private void handleAddRequest(NetworkRequest request, int score) { @@ -176,9 +186,9 @@ public class NetworkFactory extends Handler { private void handleRemoveRequest(NetworkRequest request) { NetworkRequestInfo n = mNetworkRequests.get(request.requestId); - if (n != null && n.requested) { + if (n != null) { mNetworkRequests.remove(request.requestId); - releaseNetworkFor(n.request); + if (n.requested) releaseNetworkFor(n.request); } } @@ -273,15 +283,31 @@ public class NetworkFactory extends Handler { sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap))); } + @VisibleForTesting + protected int getRequestCount() { + return mNetworkRequests.size(); + } + protected void log(String s) { Log.d(LOG_TAG, s); } + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); + pw.println(toString()); + pw.increaseIndent(); + for (int i = 0; i < mNetworkRequests.size(); i++) { + pw.println(mNetworkRequests.valueAt(i)); + } + pw.decreaseIndent(); + } + @Override public String toString() { StringBuilder sb = new StringBuilder("{").append(LOG_TAG).append(" - ScoreFilter="). append(mScore).append(", Filter=").append(mCapabilityFilter).append(", requests="). - append(mNetworkRequests.size()).append("}"); + append(mNetworkRequests.size()).append(", refCount=").append(mRefCount). + append("}"); return sb.toString(); } } diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index c9609e5..a6efc58 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -3489,57 +3489,90 @@ public abstract class BatteryStats implements Parcelable { pw.println(); for (int i=0; i<sippers.size(); i++) { final BatterySipper bs = sippers.get(i); + pw.print(prefix); switch (bs.drainType) { case IDLE: - pw.print(prefix); pw.print(" Idle: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Idle: "); break; case CELL: - pw.print(prefix); pw.print(" Cell standby: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Cell standby: "); break; case PHONE: - pw.print(prefix); pw.print(" Phone calls: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Phone calls: "); break; case WIFI: - pw.print(prefix); pw.print(" Wifi: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Wifi: "); break; case BLUETOOTH: - pw.print(prefix); pw.print(" Bluetooth: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Bluetooth: "); break; case SCREEN: - pw.print(prefix); pw.print(" Screen: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Screen: "); break; case FLASHLIGHT: - pw.print(prefix); pw.print(" Flashlight: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Flashlight: "); break; case APP: - pw.print(prefix); pw.print(" Uid "); + pw.print(" Uid "); UserHandle.formatUid(pw, bs.uidObj.getUid()); - pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println(); + pw.print(": "); break; case USER: - pw.print(prefix); pw.print(" User "); pw.print(bs.userId); - pw.print(": "); printmAh(pw, bs.totalPowerMah); pw.println(); + pw.print(" User "); pw.print(bs.userId); + pw.print(": "); break; case UNACCOUNTED: - pw.print(prefix); pw.print(" Unaccounted: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Unaccounted: "); break; case OVERCOUNTED: - pw.print(prefix); pw.print(" Over-counted: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Over-counted: "); break; case CAMERA: - pw.print(prefix); pw.print(" Camera: "); printmAh(pw, bs.totalPowerMah); - pw.println(); + pw.print(" Camera: "); + break; + default: + pw.print(" ???: "); break; } + printmAh(pw, bs.totalPowerMah); + + if (bs.drainType == BatterySipper.DrainType.APP) { + pw.print(" ("); + if (bs.cpuPowerMah != 0) { + pw.print(" cpu="); + printmAh(pw, bs.cpuPowerMah); + } + if (bs.wakeLockPowerMah != 0) { + pw.print(" wake="); + printmAh(pw, bs.wakeLockPowerMah); + } + if (bs.mobileRadioPowerMah != 0) { + pw.print(" radio="); + printmAh(pw, bs.mobileRadioPowerMah); + } + if (bs.wifiPowerMah != 0) { + pw.print(" wifi="); + printmAh(pw, bs.wifiPowerMah); + } + if (bs.gpsPowerMah != 0) { + pw.print(" gps="); + printmAh(pw, bs.gpsPowerMah); + } + if (bs.sensorPowerMah != 0) { + pw.print(" sensor="); + printmAh(pw, bs.sensorPowerMah); + } + if (bs.cameraPowerMah != 0) { + pw.print(" camera="); + printmAh(pw, bs.cameraPowerMah); + } + if (bs.flashlightPowerMah != 0) { + pw.print(" flash="); + printmAh(pw, bs.flashlightPowerMah); + } + pw.print(" )"); + } + pw.println(); } pw.println(); } diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java index d2a9cdc..5849350 100644 --- a/core/java/android/os/RemoteCallbackList.java +++ b/core/java/android/os/RemoteCallbackList.java @@ -77,7 +77,6 @@ public class RemoteCallbackList<E extends IInterface> { public boolean register(E callback) { return register(callback, null); } - /** * Add a new callback to the list. This callback will remain in the list * until a corresponding call to {@link #unregister} or its hosting process diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index 2622ee0..372725f 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -32,7 +32,9 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.DebugUtils; import android.util.SparseArray; +import android.util.SparseIntArray; +import com.android.internal.R; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; @@ -80,6 +82,7 @@ public class VolumeInfo implements Parcelable { private static SparseArray<String> sStateToEnvironment = new SparseArray<>(); private static ArrayMap<String, String> sEnvironmentToBroadcast = new ArrayMap<>(); + private static SparseIntArray sStateToDescrip = new SparseIntArray(); private static final Comparator<VolumeInfo> sDescriptionComparator = new Comparator<VolumeInfo>() { @@ -116,6 +119,16 @@ public class VolumeInfo implements Parcelable { sEnvironmentToBroadcast.put(Environment.MEDIA_UNMOUNTABLE, Intent.ACTION_MEDIA_UNMOUNTABLE); sEnvironmentToBroadcast.put(Environment.MEDIA_REMOVED, Intent.ACTION_MEDIA_REMOVED); sEnvironmentToBroadcast.put(Environment.MEDIA_BAD_REMOVAL, Intent.ACTION_MEDIA_BAD_REMOVAL); + + sStateToDescrip.put(VolumeInfo.STATE_UNMOUNTED, R.string.ext_media_status_unmounted); + sStateToDescrip.put(VolumeInfo.STATE_CHECKING, R.string.ext_media_status_checking); + sStateToDescrip.put(VolumeInfo.STATE_MOUNTED, R.string.ext_media_status_mounted); + sStateToDescrip.put(VolumeInfo.STATE_MOUNTED_READ_ONLY, R.string.ext_media_status_mounted_ro); + sStateToDescrip.put(VolumeInfo.STATE_FORMATTING, R.string.ext_media_status_formatting); + sStateToDescrip.put(VolumeInfo.STATE_EJECTING, R.string.ext_media_status_ejecting); + sStateToDescrip.put(VolumeInfo.STATE_UNMOUNTABLE, R.string.ext_media_status_unmountable); + sStateToDescrip.put(VolumeInfo.STATE_REMOVED, R.string.ext_media_status_removed); + sStateToDescrip.put(VolumeInfo.STATE_BAD_REMOVAL, R.string.ext_media_status_bad_removal); } /** vold state */ @@ -201,6 +214,10 @@ public class VolumeInfo implements Parcelable { return state; } + public int getStateDescription() { + return sStateToDescrip.get(state, 0); + } + public @Nullable String getFsUuid() { return fsUuid; } diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java index 9a08827..eeb69a3 100644 --- a/core/java/android/preference/SeekBarDialogPreference.java +++ b/core/java/android/preference/SeekBarDialogPreference.java @@ -18,29 +18,28 @@ package android.preference; import android.content.Context; import android.graphics.drawable.Drawable; -import android.preference.DialogPreference; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.SeekBar; +import com.android.internal.R; + /** * @hide */ public class SeekBarDialogPreference extends DialogPreference { - private static final String TAG = "SeekBarDialogPreference"; - - private Drawable mMyIcon; + private final Drawable mMyIcon; public SeekBarDialogPreference( Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); - setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog); createActionButtons(); // Steal the XML dialogIcon attribute's value mMyIcon = getDialogIcon(); + setDialogIcon(null); } @@ -49,7 +48,7 @@ public class SeekBarDialogPreference extends DialogPreference { } public SeekBarDialogPreference(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle); + this(context, attrs, R.attr.seekBarDialogPreferenceStyle); } public SeekBarDialogPreference(Context context) { @@ -58,15 +57,15 @@ public class SeekBarDialogPreference extends DialogPreference { // Allow subclasses to override the action buttons public void createActionButtons() { - setPositiveButtonText(android.R.string.ok); - setNegativeButtonText(android.R.string.cancel); + setPositiveButtonText(R.string.ok); + setNegativeButtonText(R.string.cancel); } @Override protected void onBindDialogView(View view) { super.onBindDialogView(view); - final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); + final ImageView iconView = (ImageView) view.findViewById(R.id.icon); if (mMyIcon != null) { iconView.setImageDrawable(mMyIcon); } else { @@ -75,6 +74,6 @@ public class SeekBarDialogPreference extends DialogPreference { } protected static SeekBar getSeekBar(View dialogView) { - return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar); + return (SeekBar) dialogView.findViewById(R.id.seekbar); } } diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 4bd085f..979c828 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -16,6 +16,7 @@ package android.preference; +import android.app.NotificationManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -31,6 +32,7 @@ import android.os.HandlerThread; import android.os.Message; import android.preference.VolumePreference.VolumeStore; import android.provider.Settings; +import android.provider.Settings.Global; import android.provider.Settings.System; import android.util.Log; import android.widget.SeekBar; @@ -46,7 +48,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba public interface Callback { void onSampleStarting(SeekBarVolumizer sbv); void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch); - void onMuted(boolean muted); + void onMuted(boolean muted, boolean zenMuted); } private final Context mContext; @@ -54,6 +56,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba private final Callback mCallback; private final Uri mDefaultUri; private final AudioManager mAudioManager; + private final NotificationManager mNotificationManager; private final int mStreamType; private final int mMaxStreamVolume; private boolean mAffectedByRingerMode; @@ -63,12 +66,14 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba private Handler mHandler; private Observer mVolumeObserver; private int mOriginalStreamVolume; + private int mLastAudibleStreamVolume; private Ringtone mRingtone; private int mLastProgress = -1; private boolean mMuted; private SeekBar mSeekBar; private int mVolumeBeforeMute = -1; private int mRingerMode; + private int mZenMode; private static final int MSG_SET_STREAM_VOLUME = 0; private static final int MSG_START_SAMPLE = 1; @@ -78,19 +83,22 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) { mContext = context; - mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + mAudioManager = context.getSystemService(AudioManager.class); + mNotificationManager = context.getSystemService(NotificationManager.class); mStreamType = streamType; mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType); mNotificationOrRing = isNotificationOrRing(mStreamType); if (mNotificationOrRing) { mRingerMode = mAudioManager.getRingerModeInternal(); } + mZenMode = mNotificationManager.getZenMode(); mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType); mCallback = callback; mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType); + mLastAudibleStreamVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType); mMuted = mAudioManager.isStreamMute(mStreamType); if (mCallback != null) { - mCallback.onMuted(mMuted); + mCallback.onMuted(mMuted, isZenMuted()); } if (defaultUri == null) { if (mStreamType == AudioManager.STREAM_RING) { @@ -119,8 +127,17 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mSeekBar.setOnSeekBarChangeListener(this); } + private boolean isZenMuted() { + return mNotificationOrRing && mZenMode == Global.ZEN_MODE_ALARMS + || mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS; + } + protected void updateSeekBar() { - if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { + final boolean zenMuted = isZenMuted(); + mSeekBar.setEnabled(!zenMuted); + if (zenMuted) { + mSeekBar.setProgress(mLastAudibleStreamVolume); + } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { mSeekBar.setProgress(0); } else if (mMuted) { mSeekBar.setProgress(0); @@ -316,11 +333,12 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba if (msg.what == UPDATE_SLIDER) { if (mSeekBar != null) { mLastProgress = msg.arg1; - final boolean muted = msg.arg2 != 0; + mLastAudibleStreamVolume = Math.abs(msg.arg2); + final boolean muted = msg.arg2 < 0; if (muted != mMuted) { mMuted = muted; if (mCallback != null) { - mCallback.onMuted(mMuted); + mCallback.onMuted(mMuted, isZenMuted()); } } updateSeekBar(); @@ -328,16 +346,18 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } } - public void postUpdateSlider(int volume, boolean mute) { - obtainMessage(UPDATE_SLIDER, volume, mute ? 1 : 0).sendToTarget(); + public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) { + final int arg2 = lastAudibleVolume * (mute ? -1 : 1); + obtainMessage(UPDATE_SLIDER, volume, arg2).sendToTarget(); } } private void updateSlider() { if (mSeekBar != null && mAudioManager != null) { final int volume = mAudioManager.getStreamVolume(mStreamType); + final int lastAudibleVolume = mAudioManager.getLastAudibleStreamVolume(mStreamType); final boolean mute = mAudioManager.isStreamMute(mStreamType); - mUiHandler.postUpdateSlider(volume, mute); + mUiHandler.postUpdateSlider(volume, lastAudibleVolume, mute); } } @@ -362,6 +382,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba if (listening) { final IntentFilter filter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION); filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION); + filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED); mContext.registerReceiver(this, filter); } else { mContext.unregisterReceiver(this); @@ -379,7 +400,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba if (mSeekBar != null && streamMatch && streamValue != -1) { final boolean muted = mAudioManager.isStreamMute(mStreamType) || streamValue == 0; - mUiHandler.postUpdateSlider(streamValue, muted); + mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted); } } else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) { if (mNotificationOrRing) { @@ -388,6 +409,9 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba if (mAffectedByRingerMode) { updateSlider(); } + } else if (NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED.equals(action)) { + mZenMode = mNotificationManager.getZenMode(); + updateSlider(); } } } diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index a2da01b..8a66c24 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -26,14 +26,13 @@ import android.view.KeyEvent; import android.view.View; import android.widget.SeekBar; +import com.android.internal.R; + /** * @hide */ public class VolumePreference extends SeekBarDialogPreference implements PreferenceManager.OnActivityStopListener, View.OnKeyListener, SeekBarVolumizer.Callback { - - static final String TAG = "VolumePreference"; - private int mStreamType; /** May be null if the dialog isn't visible. */ @@ -44,7 +43,7 @@ public class VolumePreference extends SeekBarDialogPreference implements super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.VolumePreference, defStyleAttr, defStyleRes); + R.styleable.VolumePreference, defStyleAttr, defStyleRes); mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0); a.recycle(); } @@ -54,7 +53,11 @@ public class VolumePreference extends SeekBarDialogPreference implements } public VolumePreference(Context context, AttributeSet attrs) { - this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle); + this(context, attrs, R.attr.seekBarDialogPreferenceStyle); + } + + public VolumePreference(Context context) { + this(context, null); } public void setStreamType(int streamType) { @@ -65,7 +68,7 @@ public class VolumePreference extends SeekBarDialogPreference implements protected void onBindDialogView(View view) { super.onBindDialogView(view); - final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); + final SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar); mSeekBarVolumizer = new SeekBarVolumizer(getContext(), mStreamType, null, this); mSeekBarVolumizer.start(); mSeekBarVolumizer.setSeekBar(seekBar); @@ -128,14 +131,17 @@ public class VolumePreference extends SeekBarDialogPreference implements getPreferenceManager().unregisterOnActivityStopListener(this); if (mSeekBarVolumizer != null) { - Dialog dialog = getDialog(); + final Dialog dialog = getDialog(); if (dialog != null && dialog.isShowing()) { - View view = dialog.getWindow().getDecorView() - .findViewById(com.android.internal.R.id.seekbar); - if (view != null) view.setOnKeyListener(null); + final View view = dialog.getWindow().getDecorView().findViewById(R.id.seekbar); + if (view != null) { + view.setOnKeyListener(null); + } + // Stopped while dialog was showing, revert changes mSeekBarVolumizer.revertVolume(); } + mSeekBarVolumizer.stop(); mSeekBarVolumizer = null; } @@ -155,7 +161,7 @@ public class VolumePreference extends SeekBarDialogPreference implements } @Override - public void onMuted(boolean muted) { + public void onMuted(boolean muted, boolean zenMuted) { // noop } diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index 527c8ae..6295822 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -231,6 +231,19 @@ public abstract class PrintService extends Service { */ public static final String EXTRA_PRINTER_INFO = "android.intent.extra.print.EXTRA_PRINTER_INFO"; + /** + * If you declared an optional activity with advanced print options via the + * {@link android.R.attr#advancedPrintOptionsActivity advancedPrintOptionsActivity} + * attribute, this extra is used to pass in the meta-data for the currently printed + * document as a {@link android.print.PrintDocumentInfo} to your activity allowing + * you to inspect it. + * + * @see #EXTRA_PRINT_JOB_INFO + * @see #EXTRA_PRINTER_INFO + */ + public static final String EXTRA_PRINT_DOCUMENT_INFO = + "android.printservice.extra.PRINT_DOCUMENT_INFO"; + private Handler mHandler; private IPrintServiceClient mClient; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 640f434..167d8e5 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -577,6 +577,21 @@ public final class Settings { "android.settings.APPLICATION_DETAILS_SETTINGS"; /** + * Activity Action: Show screen for controlling which apps can ignore battery optimizations. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: The Intent's data URI specifies the application package name + * to be shown, with the "package" scheme. That is "package:com.my.app". + * <p> + * Output: Nothing. + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS = + "android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS"; + + /** * @hide * Activity Action: Show the "app ops" settings screen. * <p> diff --git a/core/java/android/text/Spanned.java b/core/java/android/text/Spanned.java index b4622e0..a785d1b 100644 --- a/core/java/android/text/Spanned.java +++ b/core/java/android/text/Spanned.java @@ -187,12 +187,11 @@ extends CharSequence public int getSpanFlags(Object tag); /** - * Return the first offset greater than or equal to <code>start</code> - * where a markup object of class <code>type</code> begins or ends, - * or <code>limit</code> if there are no starts or ends greater than or - * equal to <code>start</code> but less than <code>limit</code>. Specify - * <code>null</code> or Object.class for the type if you want every - * transition regardless of type. + * Return the first offset greater than <code>start</code> where a markup + * object of class <code>type</code> begins or ends, or <code>limit</code> + * if there are no starts or ends greater than <code>start</code> but less + * than <code>limit</code>. Specify <code>null</code> or Object.class for + * the type if you want every transition regardless of type. */ public int nextSpanTransition(int start, int limit, Class type); } diff --git a/core/java/android/view/MenuInflater.java b/core/java/android/view/MenuInflater.java index dc8cadf..1c67ba7 100644 --- a/core/java/android/view/MenuInflater.java +++ b/core/java/android/view/MenuInflater.java @@ -25,11 +25,8 @@ import android.annotation.MenuRes; import android.app.Activity; import android.content.Context; import android.content.ContextWrapper; -import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.util.Xml; @@ -337,11 +334,6 @@ public class MenuInflater { private ActionProvider itemActionProvider; - private ColorStateList itemIconTintList; - private boolean itemIconTintListSet; - private PorterDuff.Mode itemIconTintMode; - private boolean itemIconTintModeSet; - private static final int defaultGroupId = NO_ID; private static final int defaultItemId = NO_ID; private static final int defaultItemCategory = 0; @@ -432,23 +424,6 @@ public class MenuInflater { itemActionProvider = null; } - if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTint)) { - itemIconTintList = a.getColorStateList( - com.android.internal.R.styleable.MenuItem_iconTint); - itemIconTintListSet = true; - } else { - itemIconTintList = null; - itemIconTintListSet = false; - } - if (a.hasValueOrEmpty(com.android.internal.R.styleable.MenuItem_iconTintMode)) { - itemIconTintMode = Drawable.parseTintMode( - a.getInt(com.android.internal.R.styleable.MenuItem_iconTintMode, -1), null); - itemIconTintModeSet = true; - } else { - itemIconTintMode = null; - itemIconTintModeSet = false; - } - a.recycle(); itemAdded = false; @@ -511,13 +486,6 @@ public class MenuInflater { if (itemActionProvider != null) { item.setActionProvider(itemActionProvider); } - - if (itemIconTintListSet) { - item.setIconTintList(itemIconTintList); - } - if (itemIconTintModeSet) { - item.setIconTintMode(itemIconTintMode); - } } public MenuItem addItem() { diff --git a/core/java/android/view/MenuItem.java b/core/java/android/view/MenuItem.java index 2948007..9e8b97e 100644 --- a/core/java/android/view/MenuItem.java +++ b/core/java/android/view/MenuItem.java @@ -21,8 +21,6 @@ import android.annotation.LayoutRes; import android.annotation.StringRes; import android.app.Activity; import android.content.Intent; -import android.content.res.ColorStateList; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.view.ContextMenu.ContextMenuInfo; import android.view.View.OnCreateContextMenuListener; @@ -601,26 +599,4 @@ public interface MenuItem { * @return This menu item instance for call chaining */ public MenuItem setOnActionExpandListener(OnActionExpandListener listener); - - /** - * Applies a tint to the icon drawable. Does not modify the current tint - * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. - * <p> - * Subsequent calls to {@link android.view.MenuItem#setIcon(android.graphics.drawable.Drawable)} - * will automatically mutate the drawable and apply the specified tint and tint mode. - * - * @param tint the tint to apply, may be {@code null} to clear tint - * @return This menu item instance for call chaining - */ - public MenuItem setIconTintList(ColorStateList tint); - - /** - * Specifies the blending mode used to apply the tint specified by {@link - * #setIconTintList(ColorStateList)} to the icon drawable. The default mode is {@link - * PorterDuff.Mode#SRC_IN}. - * - * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint - * @return This menu item instance for call chaining - */ - public MenuItem setIconTintMode(PorterDuff.Mode tintMode); } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index f18b7ac..bd45007 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -80,18 +80,12 @@ public class ViewPropertyAnimator { /** * The interpolator of the underlying Animator object. By default, we don't set the interpolator - * on the Animator and just use its default interpolator. If the interpolator is ever set on - * this Animator, then we use the interpolator that it was set to. + * on the Animator and just use its default interpolator. If the interpolator is set to a + * non-null value on this Animator, then we use the interpolator that it was set to. */ private TimeInterpolator mInterpolator; /** - * A flag indicating whether the interpolator has been set on this object. If not, we don't set - * the interpolator on the underlying Animator, but instead just use its default interpolator. - */ - private boolean mInterpolatorSet = false; - - /** * Listener for the lifecycle events of the underlying ValueAnimator object. */ private Animator.AnimatorListener mListener = null; @@ -338,7 +332,6 @@ public class ViewPropertyAnimator { * @return This object, allowing calls to methods in this class to be chained. */ public ViewPropertyAnimator setInterpolator(TimeInterpolator interpolator) { - mInterpolatorSet = true; mInterpolator = interpolator; return this; } @@ -349,7 +342,7 @@ public class ViewPropertyAnimator { * @return The timing interpolator for this animation. */ public TimeInterpolator getInterpolator() { - if (mInterpolatorSet) { + if (mInterpolator != null) { return mInterpolator; } else { // Just return the default from ValueAnimator, since that's what we'd get if @@ -897,7 +890,7 @@ public class ViewPropertyAnimator { if (mDurationSet) { animator.setDuration(mDuration); } - if (mInterpolatorSet) { + if (mInterpolator != null) { animator.setInterpolator(mInterpolator); } animator.start(); diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java index f08141c..a5696ee 100644 --- a/core/java/android/widget/ActionMenuPresenter.java +++ b/core/java/android/widget/ActionMenuPresenter.java @@ -21,10 +21,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -64,6 +62,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter private static final boolean ACTIONBAR_ANIMATIONS_ENABLED = false; private OverflowMenuButton mOverflowButton; + private Drawable mPendingOverflowIcon; + private boolean mPendingOverflowIconSet; private boolean mReserveOverflow; private boolean mReserveOverflowSet; private int mWidthLimit; @@ -85,8 +85,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter private OpenOverflowRunnable mPostedOpenRunnable; private ActionMenuPopupCallback mPopupCallback; - private TintInfo mOverflowTintInfo; - final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); int mOpenSubMenuId; @@ -154,9 +152,13 @@ public class ActionMenuPresenter extends BaseMenuPresenter if (mReserveOverflow) { if (mOverflowButton == null) { mOverflowButton = new OverflowMenuButton(mSystemContext); + if (mPendingOverflowIconSet) { + mOverflowButton.setImageDrawable(mPendingOverflowIcon); + mPendingOverflowIcon = null; + mPendingOverflowIconSet = false; + } final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); mOverflowButton.measure(spec, spec); - applyOverflowTint(); } width -= mOverflowButton.getMeasuredWidth(); } else { @@ -198,6 +200,24 @@ public class ActionMenuPresenter extends BaseMenuPresenter mExpandedActionViewsExclusive = isExclusive; } + public void setOverflowIcon(Drawable icon) { + if (mOverflowButton != null) { + mOverflowButton.setImageDrawable(icon); + } else { + mPendingOverflowIconSet = true; + mPendingOverflowIcon = icon; + } + } + + public Drawable getOverflowIcon() { + if (mOverflowButton != null) { + return mOverflowButton.getDrawable(); + } else if (mPendingOverflowIconSet) { + return mPendingOverflowIcon; + } + return null; + } + @Override public MenuView getMenuView(ViewGroup root) { MenuView oldMenuView = mMenuView; @@ -449,7 +469,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter if (hasOverflow) { if (mOverflowButton == null) { mOverflowButton = new OverflowMenuButton(mSystemContext); - applyOverflowTint(); } ViewGroup parent = (ViewGroup) mOverflowButton.getParent(); if (parent != mMenuView) { @@ -764,40 +783,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter } } - public void setOverflowTintList(ColorStateList tint) { - if (mOverflowTintInfo == null) { - mOverflowTintInfo = new TintInfo(); - } - mOverflowTintInfo.mTintList = tint; - mOverflowTintInfo.mHasTintList = true; - - applyOverflowTint(); - } - - public void setOverflowTintMode(PorterDuff.Mode tintMode) { - if (mOverflowTintInfo == null) { - mOverflowTintInfo = new TintInfo(); - } - mOverflowTintInfo.mTintMode = tintMode; - mOverflowTintInfo.mHasTintMode = true; - - applyOverflowTint(); - } - - private void applyOverflowTint() { - final TintInfo tintInfo = mOverflowTintInfo; - if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) { - if (mOverflowButton != null) { - if (tintInfo.mHasTintList) { - mOverflowButton.setImageTintList(tintInfo.mTintList); - } - if (tintInfo.mHasTintMode) { - mOverflowButton.setImageTintMode(tintInfo.mTintMode); - } - } - } - } - private static class SavedState implements Parcelable { public int openSubMenuId; @@ -1023,13 +1008,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter } } - private static class TintInfo { - ColorStateList mTintList; - PorterDuff.Mode mTintMode; - boolean mHasTintMode; - boolean mHasTintList; - } - /** * This class holds layout information for a menu item. This is used to determine * pre- and post-layout information about menu items, which will then be used to @@ -1077,5 +1055,4 @@ public class ActionMenuPresenter extends BaseMenuPresenter this.animType = animType; } } - } diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java index 278a8fb..1f02c3b 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -16,11 +16,11 @@ package android.widget; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.StyleRes; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.Configuration; -import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.ContextThemeWrapper; import android.view.Gravity; @@ -541,39 +541,35 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo dismissPopupMenus(); } - /** @hide */ - public boolean isOverflowReserved() { - return mReserveOverflow; - } - - /** @hide */ - public void setOverflowReserved(boolean reserveOverflow) { - mReserveOverflow = reserveOverflow; - } - /** - * Applies a tint to the overflow drawable. Does not modify the current tint - * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. + * Set the icon to use for the overflow button. * - * @param tint the tint to apply, may be {@code null} to clear tint + * @param icon Drawable to set, may be null to clear the icon */ - public void setOverflowTintList(ColorStateList tint) { - if (mPresenter != null) { - mPresenter.setOverflowTintList(tint); - } + public void setOverflowIcon(@Nullable Drawable icon) { + getMenu(); + mPresenter.setOverflowIcon(icon); } /** - * Specifies the blending mode used to apply the tint specified by {@link - * #setOverflowTintList(ColorStateList)} to the overflow drawable. - * The default mode is {@link PorterDuff.Mode#SRC_IN}. + * Return the current drawable used as the overflow icon. * - * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint + * @return The overflow icon drawable */ - public void setOverflowTintMode(PorterDuff.Mode tintMode) { - if (mPresenter != null) { - mPresenter.setOverflowTintMode(tintMode); - } + @Nullable + public Drawable getOverflowIcon() { + getMenu(); + return mPresenter.getOverflowIcon(); + } + + /** @hide */ + public boolean isOverflowReserved() { + return mReserveOverflow; + } + + /** @hide */ + public void setOverflowReserved(boolean reserveOverflow) { + mReserveOverflow = reserveOverflow; } @Override diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 94b9416..afc683a 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -618,12 +618,11 @@ public class ListPopupWindow { heightSpec = mDropDownHeight; } - mPopup.setWidth(widthSpec); - mPopup.setHeight(heightSpec); mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.update(getAnchorView(), mDropDownHorizontalOffset, - mDropDownVerticalOffset, -1, -1); + mDropDownVerticalOffset, (widthSpec < 0)? -1 : widthSpec, + (heightSpec < 0)? -1 : heightSpec); } else { final int widthSpec; if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) { diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index 62d948d..8ace0f3 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -25,9 +25,8 @@ import android.annotation.StringRes; import android.annotation.StyleRes; import android.app.ActionBar; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.TypedArray; -import android.graphics.PorterDuff; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; @@ -110,9 +109,6 @@ public class Toolbar extends ViewGroup { private ImageButton mNavButtonView; private ImageView mLogoView; - private TintInfo mOverflowTintInfo; - private TintInfo mNavTintInfo; - private Drawable mCollapseIcon; private CharSequence mCollapseDescription; private ImageButton mCollapseButtonView; @@ -275,21 +271,6 @@ public class Toolbar extends ViewGroup { if (!TextUtils.isEmpty(navDesc)) { setNavigationContentDescription(navDesc); } - - if (a.hasValue(R.styleable.Toolbar_overflowTint)) { - setOverflowTintList(a.getColorStateList(R.styleable.Toolbar_overflowTint)); - } - if (a.hasValue(R.styleable.Toolbar_overflowTintMode)) { - setOverflowTintMode(Drawable.parseTintMode( - a.getInt(R.styleable.Toolbar_overflowTintMode, -1), null)); - } - if (a.hasValue(R.styleable.Toolbar_navigationTint)) { - setNavigationTintList(a.getColorStateList(R.styleable.Toolbar_navigationTint)); - } - if (a.hasValue(R.styleable.Toolbar_navigationTintMode)) { - setNavigationTintMode(Drawable.parseTintMode( - a.getInt(R.styleable.Toolbar_navigationTintMode, -1), null)); - } a.recycle(); } @@ -830,101 +811,37 @@ public class Toolbar extends ViewGroup { } /** - * Applies a tint to the icon drawable. Does not modify the current tint - * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. - * <p> - * Subsequent calls to {@link #setNavigationIcon(Drawable)} will automatically mutate - * the drawable and apply the specified tint and tint mode. - * - * @param tint the tint to apply, may be {@code null} to clear tint - * - * @attr ref android.R.styleable#Toolbar_navigationTint - */ - public void setNavigationTintList(ColorStateList tint) { - if (mNavTintInfo == null) { - mNavTintInfo = new TintInfo(); - } - mNavTintInfo.mTintList = tint; - mNavTintInfo.mHasTintList = true; - - applyNavigationTint(); - } - - /** - * Specifies the blending mode used to apply the tint specified by {@link - * #setNavigationTintList(ColorStateList)} to the navigation drawable. - * The default mode is {@link PorterDuff.Mode#SRC_IN}. - * - * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint - * - * @attr ref android.R.styleable#Toolbar_navigationTintMode - */ - public void setNavigationTintMode(PorterDuff.Mode tintMode) { - if (mNavTintInfo == null) { - mNavTintInfo = new TintInfo(); - } - mNavTintInfo.mTintMode = tintMode; - mNavTintInfo.mHasTintMode = true; - - applyNavigationTint(); - } - - /** - * Applies a tint to the overflow drawable. Does not modify the current tint - * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. + * Return the Menu shown in the toolbar. * - * @param tint the tint to apply, may be {@code null} to clear tint + * <p>Applications that wish to populate the toolbar's menu can do so from here. To use + * an XML menu resource, use {@link #inflateMenu(int)}.</p> * - * @attr ref android.R.styleable#Toolbar_overflowTint + * @return The toolbar's Menu */ - public void setOverflowTintList(ColorStateList tint) { - if (mMenuView != null) { - // If the menu view is available, directly set the tint - mMenuView.setOverflowTintList(tint); - } else { - // Otherwise we will record the value - if (mOverflowTintInfo == null) { - mOverflowTintInfo = new TintInfo(); - } - mOverflowTintInfo.mTintList = tint; - mOverflowTintInfo.mHasTintList = true; - } + public Menu getMenu() { + ensureMenu(); + return mMenuView.getMenu(); } /** - * Specifies the blending mode used to apply the tint specified by {@link - * #setOverflowTintList(ColorStateList)} to the overflow drawable. - * The default mode is {@link PorterDuff.Mode#SRC_IN}. - * - * @param tintMode the blending mode used to apply the tint, may be {@code null} to clear tint + * Set the icon to use for the overflow button. * - * @attr ref android.R.styleable#Toolbar_overflowTintMode + * @param icon Drawable to set, may be null to clear the icon */ - public void setOverflowTintMode(PorterDuff.Mode tintMode) { - if (mMenuView != null) { - // If the menu view is available, directly set the tint mode - mMenuView.setOverflowTintMode(tintMode); - } else { - // Otherwise we will record the value - if (mOverflowTintInfo == null) { - mOverflowTintInfo = new TintInfo(); - } - mOverflowTintInfo.mTintMode = tintMode; - mOverflowTintInfo.mHasTintMode = true; - } + public void setOverflowIcon(@Nullable Drawable icon) { + ensureMenu(); + mMenuView.setOverflowIcon(icon); } /** - * Return the Menu shown in the toolbar. - * - * <p>Applications that wish to populate the toolbar's menu can do so from here. To use - * an XML menu resource, use {@link #inflateMenu(int)}.</p> + * Return the current drawable used as the overflow icon. * - * @return The toolbar's Menu + * @return The overflow icon drawable */ - public Menu getMenu() { + @Nullable + public Drawable getOverflowIcon() { ensureMenu(); - return mMenuView.getMenu(); + return mMenuView.getOverflowIcon(); } private void ensureMenu() { @@ -950,17 +867,6 @@ public class Toolbar extends ViewGroup { lp.gravity = Gravity.END | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK); mMenuView.setLayoutParams(lp); addSystemView(mMenuView); - - if (mOverflowTintInfo != null) { - // If we have tint info for the overflow, set it on the menu view now - if (mOverflowTintInfo.mHasTintList) { - mMenuView.setOverflowTintList(mOverflowTintInfo.mTintList); - } - if (mOverflowTintInfo.mHasTintMode) { - mMenuView.setOverflowTintMode(mOverflowTintInfo.mTintMode); - } - mOverflowTintInfo = null; - } } } @@ -1114,7 +1020,6 @@ public class Toolbar extends ViewGroup { final LayoutParams lp = generateDefaultLayoutParams(); lp.gravity = Gravity.START | (mButtonGravity & Gravity.VERTICAL_GRAVITY_MASK); mNavButtonView.setLayoutParams(lp); - applyNavigationTint(); } } @@ -1133,7 +1038,6 @@ public class Toolbar extends ViewGroup { collapseActionView(); } }); - applyNavigationTint(); } } @@ -1885,30 +1789,6 @@ public class Toolbar extends ViewGroup { return mPopupContext; } - private void applyNavigationTint() { - final TintInfo tintInfo = mNavTintInfo; - if (tintInfo != null && (tintInfo.mHasTintList || tintInfo.mHasTintMode)) { - if (mNavButtonView != null) { - if (tintInfo.mHasTintList) { - mNavButtonView.setImageTintList(tintInfo.mTintList); - } - if (tintInfo.mHasTintMode) { - mNavButtonView.setImageTintMode(tintInfo.mTintMode); - } - } - - if (mCollapseButtonView != null) { - // We will use the same tint for the collapse button - if (tintInfo.mHasTintList) { - mCollapseButtonView.setImageTintList(tintInfo.mTintList); - } - if (tintInfo.mHasTintMode) { - mCollapseButtonView.setImageTintMode(tintInfo.mTintMode); - } - } - } - } - /** * Interface responsible for receiving menu item click events if the items themselves * do not have individual item click listeners. @@ -2136,11 +2016,4 @@ public class Toolbar extends ViewGroup { public void onRestoreInstanceState(Parcelable state) { } } - - private static class TintInfo { - ColorStateList mTintList; - PorterDuff.Mode mTintMode; - boolean mHasTintMode; - boolean mHasTintList; - } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index ba4af89..39c86f9 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -18,8 +18,6 @@ package com.android.internal.app; import android.app.Activity; import android.app.ActivityThread; -import android.app.usage.UsageStats; -import android.app.usage.UsageStatsManager; import android.os.AsyncTask; import android.provider.Settings; import android.text.TextUtils; @@ -64,14 +62,11 @@ import android.widget.TextView; import android.widget.Toast; import com.android.internal.widget.ResolverDrawerLayout; -import java.text.Collator; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; @@ -100,10 +95,7 @@ public class ResolverActivity extends Activity { private boolean mResolvingHome = false; private int mProfileSwitchMessageId = -1; private final ArrayList<Intent> mIntents = new ArrayList<>(); - - private UsageStatsManager mUsm; - private Map<String, UsageStats> mStats; - private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; + private ResolverComparator mResolverComparator; private boolean mRegistered; private final PackageMonitor mPackageMonitor = new PackageMonitor() { @@ -222,10 +214,6 @@ public class ResolverActivity extends Activity { } mPm = getPackageManager(); - mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); - - final long sinceTime = System.currentTimeMillis() - USAGE_STATS_PERIOD; - mStats = mUsm.queryAndAggregateUsageStats(sinceTime, System.currentTimeMillis()); mPackageMonitor.register(this, getMainLooper(), false); mRegistered = true; @@ -236,6 +224,10 @@ public class ResolverActivity extends Activity { // Add our initial intent as the first item, regardless of what else has already been added. mIntents.add(0, new Intent(intent)); + final String referrerPackage = getReferrerPackageName(); + + mResolverComparator = new ResolverComparator(this, getTargetIntent(), referrerPackage); + configureContentView(mIntents, initialIntents, rList, alwaysUseOption); // Prevent the Resolver window from becoming the top fullscreen window and thus from taking @@ -265,7 +257,6 @@ public class ResolverActivity extends Activity { // Try to initialize the title icon if we have a view for it and a title to match final ImageView titleIcon = (ImageView) findViewById(R.id.title_icon); if (titleIcon != null) { - final String referrerPackage = getReferrerPackageName(); ApplicationInfo ai = null; try { if (!TextUtils.isEmpty(referrerPackage)) { @@ -1175,8 +1166,8 @@ public class ResolverActivity extends Activity { } } if (N > 1) { - Collections.sort(currentResolveList, - new ResolverComparator(ResolverActivity.this, getTargetIntent())); + mResolverComparator.compute(currentResolveList); + Collections.sort(currentResolveList, mResolverComparator); } // First put the initial items at the top. if (mInitialIntents != null) { @@ -1651,63 +1642,4 @@ public class ResolverActivity extends Activity { && match <= IntentFilter.MATCH_CATEGORY_PATH; } - class ResolverComparator implements Comparator<ResolvedComponentInfo> { - private final Collator mCollator; - private final boolean mHttp; - - public ResolverComparator(Context context, Intent intent) { - mCollator = Collator.getInstance(context.getResources().getConfiguration().locale); - String scheme = intent.getScheme(); - mHttp = "http".equals(scheme) || "https".equals(scheme); - } - - @Override - public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) { - final ResolveInfo lhs = lhsp.getResolveInfoAt(0); - final ResolveInfo rhs = rhsp.getResolveInfoAt(0); - - // We want to put the one targeted to another user at the end of the dialog. - if (lhs.targetUserId != UserHandle.USER_CURRENT) { - return 1; - } - - if (mHttp) { - // Special case: we want filters that match URI paths/schemes to be - // ordered before others. This is for the case when opening URIs, - // to make native apps go above browsers. - final boolean lhsSpecific = isSpecificUriMatch(lhs.match); - final boolean rhsSpecific = isSpecificUriMatch(rhs.match); - if (lhsSpecific != rhsSpecific) { - return lhsSpecific ? -1 : 1; - } - } - - if (mStats != null) { - final long timeDiff = - getPackageTimeSpent(rhs.activityInfo.packageName) - - getPackageTimeSpent(lhs.activityInfo.packageName); - - if (timeDiff != 0) { - return timeDiff > 0 ? 1 : -1; - } - } - - CharSequence sa = lhs.loadLabel(mPm); - if (sa == null) sa = lhs.activityInfo.name; - CharSequence sb = rhs.loadLabel(mPm); - if (sb == null) sb = rhs.activityInfo.name; - - return mCollator.compare(sa.toString(), sb.toString()); - } - - private long getPackageTimeSpent(String packageName) { - if (mStats != null) { - final UsageStats stats = mStats.get(packageName); - if (stats != null) { - return stats.getTotalTimeInForeground(); - } - } - return 0; - } - } } diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java new file mode 100644 index 0000000..42668f1 --- /dev/null +++ b/core/java/com/android/internal/app/ResolverComparator.java @@ -0,0 +1,215 @@ +/* + * 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.app; + +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; +import android.content.pm.ComponentInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; +import android.text.TextUtils; +import android.util.Log; +import com.android.internal.app.ResolverActivity.ResolvedComponentInfo; + +import java.text.Collator; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Ranks and compares packages based on usage stats. + */ +class ResolverComparator implements Comparator<ResolvedComponentInfo> { + private static final String TAG = "ResolverComparator"; + + private static final boolean DEBUG = true; + + // Two weeks + private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 14; + + private static final long RECENCY_TIME_PERIOD = 1000 * 60 * 60 * 12; + + private static final float RECENCY_MULTIPLIER = 3.f; + + private final Collator mCollator; + private final boolean mHttp; + private final PackageManager mPm; + private final UsageStatsManager mUsm; + private final Map<String, UsageStats> mStats; + private final long mCurrentTime; + private final long mSinceTime; + private final LinkedHashMap<ComponentName, ScoredTarget> mScoredTargets = new LinkedHashMap<>(); + private final String mReferrerPackage; + + public ResolverComparator(Context context, Intent intent, String referrerPackage) { + mCollator = Collator.getInstance(context.getResources().getConfiguration().locale); + String scheme = intent.getScheme(); + mHttp = "http".equals(scheme) || "https".equals(scheme); + mReferrerPackage = referrerPackage; + + mPm = context.getPackageManager(); + mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); + + mCurrentTime = System.currentTimeMillis(); + mSinceTime = mCurrentTime - USAGE_STATS_PERIOD; + mStats = mUsm.queryAndAggregateUsageStats(mSinceTime, mCurrentTime); + } + + public void compute(List<ResolvedComponentInfo> targets) { + mScoredTargets.clear(); + + final long recentSinceTime = mCurrentTime - RECENCY_TIME_PERIOD; + + long mostRecentlyUsedTime = recentSinceTime + 1; + long mostTimeSpent = 1; + int mostLaunched = 1; + + for (ResolvedComponentInfo target : targets) { + final ScoredTarget scoredTarget + = new ScoredTarget(target.getResolveInfoAt(0).activityInfo); + mScoredTargets.put(target.name, scoredTarget); + final UsageStats pkStats = mStats.get(target.name.getPackageName()); + if (pkStats != null) { + // Only count recency for apps that weren't the caller + // since the caller is always the most recent. + // Persistent processes muck this up, so omit them too. + if (!target.name.getPackageName().equals(mReferrerPackage) + && !isPersistentProcess(target)) { + final long lastTimeUsed = pkStats.getLastTimeUsed(); + scoredTarget.lastTimeUsed = lastTimeUsed; + if (lastTimeUsed > mostRecentlyUsedTime) { + mostRecentlyUsedTime = lastTimeUsed; + } + } + final long timeSpent = pkStats.getTotalTimeInForeground(); + scoredTarget.timeSpent = timeSpent; + if (timeSpent > mostTimeSpent) { + mostTimeSpent = timeSpent; + } + final int launched = pkStats.mLaunchCount; + scoredTarget.launchCount = launched; + if (launched > mostLaunched) { + mostLaunched = launched; + } + } + } + + + if (DEBUG) { + Log.d(TAG, "compute - mostRecentlyUsedTime: " + mostRecentlyUsedTime + + " mostTimeSpent: " + mostTimeSpent + + " recentSinceTime: " + recentSinceTime + + " mostLaunched: " + mostLaunched); + } + + for (ScoredTarget target : mScoredTargets.values()) { + final float recency = (float) Math.max(target.lastTimeUsed - recentSinceTime, 0) + / (mostRecentlyUsedTime - recentSinceTime); + final float recencyScore = recency * recency * RECENCY_MULTIPLIER; + final float usageTimeScore = (float) target.timeSpent / mostTimeSpent; + final float launchCountScore = (float) target.launchCount / mostLaunched; + + target.score = recencyScore + usageTimeScore + launchCountScore; + if (DEBUG) { + Log.d(TAG, "Scores: recencyScore: " + recencyScore + + " usageTimeScore: " + usageTimeScore + + " launchCountScore: " + launchCountScore + + " - " + target); + } + } + } + + static boolean isPersistentProcess(ResolvedComponentInfo rci) { + if (rci != null && rci.getCount() > 0) { + return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags & + ApplicationInfo.FLAG_PERSISTENT) != 0; + } + return false; + } + + @Override + public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) { + final ResolveInfo lhs = lhsp.getResolveInfoAt(0); + final ResolveInfo rhs = rhsp.getResolveInfoAt(0); + + // We want to put the one targeted to another user at the end of the dialog. + if (lhs.targetUserId != UserHandle.USER_CURRENT) { + return 1; + } + + if (mHttp) { + // Special case: we want filters that match URI paths/schemes to be + // ordered before others. This is for the case when opening URIs, + // to make native apps go above browsers. + final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match); + final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match); + if (lhsSpecific != rhsSpecific) { + return lhsSpecific ? -1 : 1; + } + } + + if (mStats != null) { + final ScoredTarget lhsTarget = mScoredTargets.get(new ComponentName( + lhs.activityInfo.packageName, lhs.activityInfo.name)); + final ScoredTarget rhsTarget = mScoredTargets.get(new ComponentName( + rhs.activityInfo.packageName, rhs.activityInfo.name)); + final float diff = rhsTarget.score - lhsTarget.score; + + if (diff != 0) { + return diff > 0 ? 1 : -1; + } + } + + CharSequence sa = lhs.loadLabel(mPm); + if (sa == null) sa = lhs.activityInfo.name; + CharSequence sb = rhs.loadLabel(mPm); + if (sb == null) sb = rhs.activityInfo.name; + + return mCollator.compare(sa.toString().trim(), sb.toString().trim()); + } + + static class ScoredTarget { + public final ComponentInfo componentInfo; + public float score; + public long lastTimeUsed; + public long timeSpent; + public long launchCount; + + public ScoredTarget(ComponentInfo ci) { + componentInfo = ci; + } + + @Override + public String toString() { + return "ScoredTarget{" + componentInfo + + " score: " + score + + " lastTimeUsed: " + lastTimeUsed + + " timeSpent: " + timeSpent + + " launchCount: " + launchCount + + "}"; + } + } +} diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java index 00af401..ed676bb 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuItem.java +++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java @@ -18,8 +18,6 @@ package com.android.internal.view.menu; import android.content.Context; import android.content.Intent; -import android.content.res.ColorStateList; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.view.ActionProvider; import android.view.ContextMenu.ContextMenuInfo; @@ -44,7 +42,6 @@ public class ActionMenuItem implements MenuItem { private Drawable mIconDrawable; private int mIconResId = NO_ICON; - private TintInfo mIconTintInfo; private Context mContext; @@ -161,14 +158,12 @@ public class ActionMenuItem implements MenuItem { public MenuItem setIcon(Drawable icon) { mIconDrawable = icon; mIconResId = NO_ICON; - applyIconTint(); return this; } public MenuItem setIcon(int iconRes) { mIconResId = iconRes; mIconDrawable = mContext.getDrawable(iconRes); - applyIconTint(); return this; } @@ -279,48 +274,4 @@ public class ActionMenuItem implements MenuItem { // No need to save the listener; ActionMenuItem does not support collapsing items. return this; } - - @Override - public MenuItem setIconTintList(ColorStateList tintList) { - if (mIconTintInfo == null) { - mIconTintInfo = new TintInfo(); - } - mIconTintInfo.mTintList = tintList; - mIconTintInfo.mHasTintList = true; - applyIconTint(); - return this; - } - - @Override - public MenuItem setIconTintMode(PorterDuff.Mode tintMode) { - if (mIconTintInfo == null) { - mIconTintInfo = new TintInfo(); - } - mIconTintInfo.mTintMode = tintMode; - mIconTintInfo.mHasTintMode = true; - applyIconTint(); - return this; - } - - private void applyIconTint() { - final TintInfo tintInfo = mIconTintInfo; - if (mIconDrawable != null && tintInfo != null) { - if (tintInfo.mHasTintList || tintInfo.mHasTintMode) { - mIconDrawable = mIconDrawable.mutate(); - if (tintInfo.mHasTintList) { - mIconDrawable.setTintList(tintInfo.mTintList); - } - if (tintInfo.mHasTintMode) { - mIconDrawable.setTintMode(tintInfo.mTintMode); - } - } - } - } - - private static class TintInfo { - ColorStateList mTintList; - PorterDuff.Mode mTintMode; - boolean mHasTintMode; - boolean mHasTintList; - } } diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java index ef4e546..3b1f20d 100644 --- a/core/java/com/android/internal/view/menu/MenuItemImpl.java +++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java @@ -21,8 +21,6 @@ import com.android.internal.view.menu.MenuView.ItemView; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.res.ColorStateList; -import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.ActionProvider; @@ -62,11 +60,6 @@ public final class MenuItemImpl implements MenuItem { * needed). */ private int mIconResId = NO_ICON; - - /** - * Tint info for the icon - */ - private TintInfo mIconTintInfo; /** The menu to which this item belongs */ private MenuBuilder mMenu; @@ -392,10 +385,10 @@ public final class MenuItemImpl implements MenuItem { } if (mIconResId != NO_ICON) { - mIconDrawable = mMenu.getContext().getDrawable(mIconResId); + Drawable icon = mMenu.getContext().getDrawable(mIconResId); mIconResId = NO_ICON; - applyIconTint(); - return mIconDrawable; + mIconDrawable = icon; + return icon; } return null; @@ -404,7 +397,6 @@ public final class MenuItemImpl implements MenuItem { public MenuItem setIcon(Drawable icon) { mIconResId = NO_ICON; mIconDrawable = icon; - applyIconTint(); mMenu.onItemsChanged(false); return this; @@ -678,48 +670,4 @@ public final class MenuItemImpl implements MenuItem { public boolean isActionViewExpanded() { return mIsActionViewExpanded; } - - @Override - public MenuItem setIconTintList(ColorStateList tintList) { - if (mIconTintInfo == null) { - mIconTintInfo = new TintInfo(); - } - mIconTintInfo.mTintList = tintList; - mIconTintInfo.mHasTintList = true; - applyIconTint(); - return this; - } - - @Override - public MenuItem setIconTintMode(PorterDuff.Mode tintMode) { - if (mIconTintInfo == null) { - mIconTintInfo = new TintInfo(); - } - mIconTintInfo.mTintMode = tintMode; - mIconTintInfo.mHasTintMode = true; - applyIconTint(); - return this; - } - - private void applyIconTint() { - final TintInfo tintInfo = mIconTintInfo; - if (mIconDrawable != null && tintInfo != null) { - if (tintInfo.mHasTintList || tintInfo.mHasTintMode) { - mIconDrawable = mIconDrawable.mutate(); - if (tintInfo.mHasTintList) { - mIconDrawable.setTintList(tintInfo.mTintList); - } - if (tintInfo.mHasTintMode) { - mIconDrawable.setTintMode(tintInfo.mTintMode); - } - } - } - } - - private static class TintInfo { - ColorStateList mTintList; - PorterDuff.Mode mTintMode; - boolean mHasTintMode; - boolean mHasTintList; - } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 709de9e..0911d42 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1979,6 +1979,10 @@ <permission android:name="android.permission.GRANT_REVOKE_PERMISSIONS" android:protectionLevel="signature" /> + <!-- @hide Allows an application to observe permission changes. --> + <permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" + android:protectionLevel="signatureOrSystem" /> + <!-- Allows an application to use SurfaceFlinger's low level features. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_SURFACE_FLINGER" diff --git a/core/res/res/drawable-hdpi/ic_fingerprint_light_overlay.png b/core/res/res/drawable-hdpi/ic_fingerprint_light_overlay.png Binary files differdeleted file mode 100644 index 0253c77..0000000 --- a/core/res/res/drawable-hdpi/ic_fingerprint_light_overlay.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/ic_fingerprint_light_overlay.png b/core/res/res/drawable-mdpi/ic_fingerprint_light_overlay.png Binary files differdeleted file mode 100644 index 5a1c61e..0000000 --- a/core/res/res/drawable-mdpi/ic_fingerprint_light_overlay.png +++ /dev/null diff --git a/core/res/res/drawable-xhdpi/ic_fingerprint_light_overlay.png b/core/res/res/drawable-xhdpi/ic_fingerprint_light_overlay.png Binary files differdeleted file mode 100644 index 5f0c362..0000000 --- a/core/res/res/drawable-xhdpi/ic_fingerprint_light_overlay.png +++ /dev/null diff --git a/core/res/res/drawable-xxhdpi/ic_fingerprint_light_overlay.png b/core/res/res/drawable-xxhdpi/ic_fingerprint_light_overlay.png Binary files differdeleted file mode 100644 index f4cf906..0000000 --- a/core/res/res/drawable-xxhdpi/ic_fingerprint_light_overlay.png +++ /dev/null diff --git a/core/res/res/drawable-xxxhdpi/ic_fingerprint_light_overlay.png b/core/res/res/drawable-xxxhdpi/ic_fingerprint_light_overlay.png Binary files differdeleted file mode 100644 index dcdbed9..0000000 --- a/core/res/res/drawable-xxxhdpi/ic_fingerprint_light_overlay.png +++ /dev/null diff --git a/core/res/res/drawable/ic_fingerprint.xml b/core/res/res/drawable/ic_fingerprint.xml new file mode 100644 index 0000000..c19f00f --- /dev/null +++ b/core/res/res/drawable/ic_fingerprint.xml @@ -0,0 +1,37 @@ +<!-- + ~ 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:tint="?attr/colorControlNormal" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#ffffff" + android:pathData="M17.5,4.47c-0.08,0.0 -0.16,-0.02 -0.24,-0.06C15.45,3.42 13.88,3.0 12.01,3.0c-1.87,0.0 -3.64,0.47 -5.25,1.4C6.52,4.54 6.22,4.46 6.08,4.22C5.94,3.98 6.02,3.67 6.26,3.54C8.03,2.52 9.96,2.0 12.01,2.0c2.02,0.0 3.79,0.47 5.73,1.53c0.24,0.13 0.33,0.44 0.2,0.68C17.85,4.38 17.68,4.47 17.5,4.47z"/> + <path + android:fillColor="#ffffff" + android:pathData="M3.95,9.72c-0.1,0.0 -0.19,-0.03 -0.28,-0.08C3.44,9.48 3.38,9.17 3.54,8.94c0.94,-1.4 2.14,-2.5 3.56,-3.28c2.99,-1.63 6.82,-1.63 9.81,-0.01c1.42,0.77 2.61,1.87 3.56,3.26c0.15,0.23 0.09,0.54 -0.13,0.69c-0.23,0.16 -0.54,0.09 -0.69,-0.13c-0.85,-1.26 -1.93,-2.24 -3.2,-2.94c-2.7,-1.47 -6.16,-1.46 -8.86,0.01C6.3,7.24 5.22,8.23 4.37,9.5C4.27,9.64 4.11,9.72 3.95,9.72z"/> + <path + android:fillColor="#ffffff" + android:pathData="M9.86,21.79c-0.13,0.0 -0.27,-0.05 -0.36,-0.16c-0.82,-0.87 -1.26,-1.43 -1.9,-2.63c-0.65,-1.23 -1.0,-2.73 -1.0,-4.33c0.0,-2.97 2.42,-5.39 5.39,-5.39s5.39,2.42 5.39,5.39c0.0,0.28 -0.22,0.5 -0.5,0.5s-0.5,-0.22 -0.5,-0.5c0.0,-2.42 -1.97,-4.39 -4.39,-4.39S7.6,12.24 7.6,14.66c0.0,1.44 0.3,2.78 0.88,3.86c0.61,1.15 1.02,1.64 1.75,2.42c0.19,0.2 0.18,0.52 -0.02,0.71C10.11,21.74 9.98,21.79 9.86,21.79z"/> + <path + android:fillColor="#ffffff" + android:pathData="M16.7,19.94c-1.14,0.0 -2.13,-0.3 -2.96,-0.89c-1.41,-1.01 -2.25,-2.65 -2.25,-4.38c0.0,-0.28 0.22,-0.5 0.5,-0.5s0.5,0.22 0.5,0.5c0.0,1.41 0.69,2.75 1.83,3.57c0.66,0.48 1.44,0.71 2.38,0.71c0.23,0.0 0.6,-0.02 0.98,-0.1c0.27,-0.05 0.53,0.13 0.58,0.4c0.05,0.27 -0.13,0.53 -0.4,0.58C17.3,19.93 16.83,19.94 16.7,19.94z"/> + <path + android:fillColor="#ffffff" + android:pathData="M14.76,22.0c-0.05,0.0 -0.09,-0.01 -0.14,-0.02c-1.51,-0.44 -2.51,-1.03 -3.53,-2.11c-1.32,-1.39 -2.05,-3.24 -2.05,-5.21c0.0,-1.62 1.32,-2.94 2.94,-2.94c1.62,0.0 2.94,1.32 2.94,2.94c0.0,1.07 0.87,1.94 1.94,1.94s1.94,-0.87 1.94,-1.94c0.0,-3.77 -3.07,-6.83 -6.83,-6.83c-2.68,0.0 -5.12,1.58 -6.23,4.02c-0.37,0.81 -0.56,1.76 -0.56,2.81c0.0,0.78 0.07,2.01 0.63,3.61c0.09,0.26 -0.04,0.55 -0.3,0.64c-0.26,0.09 -0.55,-0.04 -0.64,-0.3c-0.46,-1.31 -0.69,-2.6 -0.69,-3.95c0.0,-1.2 0.22,-2.28 0.65,-3.23c1.27,-2.8 4.07,-4.61 7.14,-4.61c4.32,0.0 7.83,3.51 7.83,7.83c0.0,1.62 -1.32,2.94 -2.94,2.94c-1.62,0.0 -2.94,-1.32 -2.94,-2.94c0.0,-1.07 -0.87,-1.94 -1.94,-1.94s-1.94,0.87 -1.94,1.94c0.0,1.71 0.63,3.32 1.77,4.52c0.9,0.95 1.74,1.45 3.08,1.84c0.27,0.08 0.42,0.35 0.34,0.62C15.18,21.86 14.98,22.0 14.76,22.0z"/> +</vector> diff --git a/core/res/res/drawable/ic_fingerprint_dark.xml b/core/res/res/drawable/ic_fingerprint_dark.xml deleted file mode 100644 index 6eb6ada..0000000 --- a/core/res/res/drawable/ic_fingerprint_dark.xml +++ /dev/null @@ -1,37 +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 - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="32.0dp" - android:height="32.0dp" - android:viewportWidth="32.0" - android:viewportHeight="32.0"> - <path - android:fillColor="?attr/colorControlNormal" - android:pathData="M23.7,5.9c-0.1,0.0 -0.2,0.0 -0.3,-0.1C21.0,4.5 18.6,3.9 16.0,3.9c-2.5,0.0 -4.6,0.6 -6.9,1.9C8.8,6.0 8.3,5.9 8.1,5.5C7.9,5.2 8.0,4.7 8.4,4.5c2.5,-1.4 4.9,-2.1 7.7,-2.1c2.8,0.0 5.4,0.7 8.0,2.1c0.4,0.2 0.5,0.6 0.3,1.0C24.2,5.7 24.0,5.9 23.7,5.9z"/> - <path - android:fillColor="?attr/colorControlNormal" - android:pathData="M5.3,13.2c-0.1,0.0 -0.3,0.0 -0.4,-0.1c-0.3,-0.2 -0.4,-0.7 -0.2,-1.0c1.3,-1.9 2.9,-3.4 4.9,-4.5c4.1,-2.2 9.3,-2.2 13.4,0.0c1.9,1.1 3.6,2.5 4.9,4.4c0.2,0.3 0.1,0.8 -0.2,1.0c-0.3,0.2 -0.8,0.1 -1.0,-0.2c-1.2,-1.7 -2.6,-3.0 -4.3,-4.0c-3.7,-2.0 -8.3,-2.0 -12.0,0.0c-1.7,0.9 -3.2,2.3 -4.3,4.0C5.7,13.1 5.5,13.2 5.3,13.2z"/> - <path - android:fillColor="?attr/colorControlNormal" - android:pathData="M13.3,29.6c-0.2,0.0 -0.4,-0.1 -0.5,-0.2c-1.1,-1.2 -1.7,-2.0 -2.6,-3.6c-0.9,-1.7 -1.4,-3.7 -1.4,-5.9c0.0,-4.1 3.3,-7.4 7.4,-7.4c4.1,0.0 7.4,3.3 7.4,7.4c0.0,0.4 -0.3,0.7 -0.7,0.7s-0.7,-0.3 -0.7,-0.7c0.0,-3.3 -2.7,-5.9 -5.9,-5.9c-3.3,0.0 -5.9,2.7 -5.9,5.9c0.0,2.0 0.4,3.8 1.2,5.2c0.8,1.6 1.4,2.2 2.4,3.3c0.3,0.3 0.3,0.8 0.0,1.0C13.7,29.5 13.5,29.6 13.3,29.6z"/> - <path - android:fillColor="?attr/colorControlNormal" - android:pathData="M22.6,27.1c-1.6,0.0 -2.9,-0.4 -4.1,-1.2c-1.9,-1.4 -3.1,-3.6 -3.1,-6.0c0.0,-0.4 0.3,-0.7 0.7,-0.7s0.7,0.3 0.7,0.7c0.0,1.9 0.9,3.7 2.5,4.8c0.9,0.6 1.9,1.0 3.2,1.0c0.3,0.0 0.8,0.0 1.3,-0.1c0.4,-0.1 0.8,0.2 0.8,0.6c0.1,0.4 -0.2,0.8 -0.6,0.8C23.4,27.1 22.8,27.1 22.6,27.1z"/> - <path - android:fillColor="?attr/colorControlNormal" - android:pathData="M20.0,29.9c-0.1,0.0 -0.1,0.0 -0.2,0.0c-2.1,-0.6 -3.4,-1.4 -4.8,-2.9c-1.8,-1.9 -2.8,-4.4 -2.8,-7.1c0.0,-2.2 1.8,-4.1 4.1,-4.1c2.2,0.0 4.1,1.8 4.1,4.1c0.0,1.4 1.2,2.6 2.6,2.6c1.4,0.0 2.6,-1.2 2.6,-2.6c0.0,-5.1 -4.2,-9.3 -9.3,-9.3c-3.6,0.0 -6.9,2.1 -8.4,5.4C7.3,17.1 7.0,18.4 7.0,19.8c0.0,1.1 0.1,2.7 0.9,4.9c0.1,0.4 -0.1,0.8 -0.4,0.9c-0.4,0.1 -0.8,-0.1 -0.9,-0.4c-0.6,-1.8 -0.9,-3.6 -0.9,-5.4c0.0,-1.6 0.3,-3.1 0.9,-4.4c1.7,-3.8 5.6,-6.3 9.8,-6.3c5.9,0.0 10.7,4.8 10.7,10.7c0.0,2.2 -1.8,4.1 -4.1,4.1s-4.0,-1.8 -4.0,-4.1c0.0,-1.4 -1.2,-2.6 -2.6,-2.6c-1.4,0.0 -2.6,1.2 -2.6,2.6c0.0,2.3 0.9,4.5 2.4,6.1c1.2,1.3 2.4,2.0 4.2,2.5c0.4,0.1 0.6,0.5 0.5,0.9C20.6,29.7 20.3,29.9 20.0,29.9z"/> -</vector> diff --git a/core/res/res/drawable/ic_fingerprint_light.xml b/core/res/res/drawable/ic_fingerprint_light.xml deleted file mode 100644 index 223d16b..0000000 --- a/core/res/res/drawable/ic_fingerprint_light.xml +++ /dev/null @@ -1,28 +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. ---> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item> - <shape android:shape="oval"> - <solid android:color="?attr/colorAccent"/> - <size - android:width="40dp" - android:height="40dp"/> - </shape> - </item> - <item> - <bitmap android:src="@drawable/ic_fingerprint_light_overlay"/> - </item> -</layer-list> diff --git a/core/res/res/layout/seekbar_dialog.xml b/core/res/res/layout/preference_dialog_seekbar.xml index 84352a5..4e366c4 100644 --- a/core/res/res/layout/seekbar_dialog.xml +++ b/core/res/res/layout/preference_dialog_seekbar.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project +<!-- 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. @@ -15,20 +15,21 @@ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <ImageView + android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="20dp" /> + + <SeekBar + android:id="@+id/seekbar" android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical" - android:gravity="center_horizontal"> - - <ImageView android:id="@+id/icon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingTop="20dip" /> - - <SeekBar android:id="@+id/seekbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:padding="20dip" /> - + android:layout_height="wrap_content" + android:padding="20dp" /> + </LinearLayout> - diff --git a/core/res/res/layout/preference_dialog_seekbar_material.xml b/core/res/res/layout/preference_dialog_seekbar_material.xml new file mode 100644 index 0000000..a98a995 --- /dev/null +++ b/core/res/res/layout/preference_dialog_seekbar_material.xml @@ -0,0 +1,37 @@ +<?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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="vertical"> + + <ImageView + android:id="@+id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="?attr/dialogPreferredPadding" /> + + <SeekBar + android:id="@+id/seekbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="?attr/dialogPreferredPadding" + android:paddingStart="?attr/dialogPreferredPadding" + android:paddingEnd="?attr/dialogPreferredPadding" /> + +</LinearLayout> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index a13f494..52e2cf0 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -561,15 +561,18 @@ <!-- Image elements --> <!-- ============== --> <eat-comment /> - +i <!-- Background that can be used behind parts of a UI that provide details on data the user is selecting. For example, this is the background element of PreferenceActivity's embedded preference fragment. --> <attr name="detailsElementBackground" format="reference" /> - <!-- Drawable that should be used to indicate that an app is waiting for a fingerprint scan. --> - <attr name="fingerprintDrawable" format="reference" /> + <!-- Icon that should be used to indicate that an app is waiting for a fingerprint scan. + This should be used whenever an app is requesting the user to place a finger on the + fingerprint sensor. It can be combined with other drawables such as colored circles, so + the appearance matches the branding of the app requesting the fingerprint scan.--> + <attr name="fingerprintAuthDrawable" format="reference" /> <!-- ============ --> <!-- Panel styles --> @@ -868,6 +871,8 @@ <attr name="dialogPreferenceStyle" format="reference" /> <!-- Default style for EditTextPreference. --> <attr name="editTextPreferenceStyle" format="reference" /> + <!-- @hide Default style for SeekBarDialogPreference. --> + <attr name="seekBarDialogPreferenceStyle" format="reference" /> <!-- Default style for RingtonePreference. --> <attr name="ringtonePreferenceStyle" format="reference" /> <!-- The preference layout that has the child/tabbed effect. --> @@ -6646,33 +6651,6 @@ for more info. --> <attr name="actionProviderClass" format="string" /> - <!-- An optional tint for the item's icon. - See {@link android.view.MenuItem#setIconTintList(android.content.res.ColorStateList)} - for more info. --> - <attr name="iconTint" format="color" /> - - <!-- The blending mode used for tinting the item's icon - See {@link android.view.MenuItem#setIconTintMode(android.graphics.PorterDuff.Mode)} - for more info. --> - <attr name="iconTintMode"> - <!-- The tint is drawn on top of the drawable. - [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] --> - <enum name="src_over" value="3" /> - <!-- The tint is masked by the alpha channel of the drawable. The drawable’s - color channels are thrown out. [Sa * Da, Sc * Da] --> - <enum name="src_in" value="5" /> - <!-- The tint is drawn above the drawable, but with the drawable’s alpha - channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] --> - <enum name="src_atop" value="9" /> - <!-- Multiplies the color and alpha channels of the drawable with those of - the tint. [Sa * Da, Sc * Dc] --> - <enum name="multiply" value="14" /> - <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] --> - <enum name="screen" value="15" /> - <!-- Combines the tint and drawable color and alpha channels, clamping the - result to valid color values. Saturate(S + D) --> - <enum name="add" value="16" /> - </attr> </declare-styleable> <!-- Attrbitutes for a ActvityChooserView. --> @@ -7786,52 +7764,6 @@ <!-- Text to set as the content description for the navigation button located at the start of the toolbar. --> <attr name="navigationContentDescription" format="string" /> - - <!-- Tint used for the navigation button --> - <attr name="navigationTint" format="color" /> - <!-- The blending mode used for tinting the navigation button --> - <attr name="navigationTintMode"> - <!-- The tint is drawn on top of the drawable. - [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] --> - <enum name="src_over" value="3" /> - <!-- The tint is masked by the alpha channel of the drawable. The drawable’s - color channels are thrown out. [Sa * Da, Sc * Da] --> - <enum name="src_in" value="5" /> - <!-- The tint is drawn above the drawable, but with the drawable’s alpha - channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] --> - <enum name="src_atop" value="9" /> - <!-- Multiplies the color and alpha channels of the drawable with those of - the tint. [Sa * Da, Sc * Dc] --> - <enum name="multiply" value="14" /> - <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] --> - <enum name="screen" value="15" /> - <!-- Combines the tint and drawable color and alpha channels, clamping the - result to valid color values. Saturate(S + D). Only works on APIv 11+ --> - <enum name="add" value="16" /> - </attr> - - <!-- Tint used for the overflow button --> - <attr name="overflowTint" format="color" /> - <!-- The blending mode used for tinting the overflow button --> - <attr name="overflowTintMode"> - <!-- The tint is drawn on top of the drawable. - [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] --> - <enum name="src_over" value="3" /> - <!-- The tint is masked by the alpha channel of the drawable. The drawable’s - color channels are thrown out. [Sa * Da, Sc * Da] --> - <enum name="src_in" value="5" /> - <!-- The tint is drawn above the drawable, but with the drawable’s alpha - channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] --> - <enum name="src_atop" value="9" /> - <!-- Multiplies the color and alpha channels of the drawable with those of - the tint. [Sa * Da, Sc * Dc] --> - <enum name="multiply" value="14" /> - <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] --> - <enum name="screen" value="15" /> - <!-- Combines the tint and drawable color and alpha channels, clamping the - result to valid color values. Saturate(S + D). Only works on APIv 11+ --> - <enum name="add" value="16" /> - </attr> </declare-styleable> <declare-styleable name="Toolbar_LayoutParams"> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index bbf4005..bbe27a4 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2614,12 +2614,20 @@ <public type="attr" name="end" /> <public type="attr" name="windowLightStatusBar" /> <public type="attr" name="numbersInnerTextColor" /> - <public type="attr" name="iconTint" /> - <public type="attr" name="iconTintMode" /> - <public type="attr" name="overflowTint" /> - <public type="attr" name="overflowTintMode" /> - <public type="attr" name="navigationTint" /> - <public type="attr" name="navigationTintMode" /> + + <attr name="__reserved2" format="boolean" /> + <public type="attr" name="__reserved2" /> + <attr name="__reserved3" format="boolean" /> + <public type="attr" name="__reserved3" /> + <attr name="__reserved4" format="boolean" /> + <public type="attr" name="__reserved4" /> + <attr name="__reserved5" format="boolean" /> + <public type="attr" name="__reserved5" /> + <attr name="__reserved6" format="boolean" /> + <public type="attr" name="__reserved6" /> + <attr name="__reserved7" format="boolean" /> + <public type="attr" name="__reserved7" /> + <public type="attr" name="fullBackupContent" /> <public type="style" name="Widget.Material.Button.Colored" /> @@ -2690,5 +2698,5 @@ <public type="attr" name="supportsLaunchVoiceAssistFromKeyguard" /> <public type="attr" name="scrollIndicators" /> <public type="attr" name="hyphenationFrequency" /> - <public type="attr" name="fingerprintDrawable" /> + <public type="attr" name="fingerprintAuthDrawable" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 2326968..28274ae 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1519,10 +1519,10 @@ <string name="policylab_disableCamera">Disable cameras</string> <!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]--> <string name="policydesc_disableCamera">Prevent use of all device cameras.</string> - <!-- Title of policy access to disable all device cameras [CHAR LIMIT=30]--> - <string name="policylab_disableKeyguardFeatures">Disable features of screen lock</string> - <!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]--> - <string name="policydesc_disableKeyguardFeatures">Prevent use of some features of screen lock.</string> + <!-- Title of policy access to disable keyguard features [CHAR LIMIT=30]--> + <string name="policylab_disableKeyguardFeatures">Disable some screen lock features</string> + <!-- Description of policy access to disable keyguard features. [CHAR LIMIT=110]--> + <string name="policydesc_disableKeyguardFeatures">Prevent use of some screen lock features.</string> <!-- The order of these is important, don't reorder without changing Contacts.java --> <skip /> <!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. --> @@ -3028,9 +3028,14 @@ <string name="ext_media_ready_notification_message">For transferring photos and media</string> <!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] --> - <string name="ext_media_unmountable_notification_title">Damaged <xliff:g id="name" example="SD card">%s</xliff:g></string> + <string name="ext_media_unmountable_notification_title">Corrupted <xliff:g id="name" example="SD card">%s</xliff:g></string> <!-- Notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] --> - <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is damaged; try reformatting it</string> + <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Touch to fix.</string> + + <!-- Notification title when external media is unsupported [CHAR LIMIT=30] --> + <string name="ext_media_unsupported_notification_title">Unsupported <xliff:g id="name" example="SD card">%s</xliff:g></string> + <!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] --> + <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Touch to set up in a supported format.</string> <!-- Notification title when external media is unsafely removed [CHAR LIMIT=30] --> <string name="ext_media_badremoval_notification_title"><xliff:g id="name" example="SD card">%s</xliff:g> unexpectedly removed</string> @@ -3048,7 +3053,7 @@ <string name="ext_media_unmounting_notification_message">Don\'t remove</string> <!-- Notification action to setup external media [CHAR LIMIT=20] --> - <string name="ext_media_init_action">Setup</string> + <string name="ext_media_init_action">Set up</string> <!-- Notification action to unmount external media [CHAR LIMIT=20] --> <string name="ext_media_unmount_action">Eject</string> <!-- Notification action to browse external media [CHAR LIMIT=20] --> @@ -3074,6 +3079,29 @@ <!-- Notification title when moving data to external storage failed [CHAR LIMIT=64] --> <string name="ext_media_move_failure_message">Data left at original location</string> + <!-- Short summary of storage media status when removed [CHAR LIMIT=32] --> + <string name="ext_media_status_removed">Removed</string> + <!-- Short summary of storage media status when unmounted [CHAR LIMIT=32] --> + <string name="ext_media_status_unmounted">Ejected</string> + <!-- Short summary of storage media status when checking [CHAR LIMIT=32] --> + <string name="ext_media_status_checking">Checking\u2026</string> + <!-- Short summary of storage media status when mounted [CHAR LIMIT=32] --> + <string name="ext_media_status_mounted">Ready</string> + <!-- Short summary of storage media status when mounted read-only [CHAR LIMIT=32] --> + <string name="ext_media_status_mounted_ro">Read-only</string> + <!-- Short summary of storage media status when removed unsafely [CHAR LIMIT=32] --> + <string name="ext_media_status_bad_removal">Removed unsafely</string> + <!-- Short summary of storage media status when unmountable [CHAR LIMIT=32] --> + <string name="ext_media_status_unmountable">Corrupted</string> + <!-- Short summary of storage media status when unsupported [CHAR LIMIT=32] --> + <string name="ext_media_status_unsupported">Unsupported</string> + <!-- Short summary of storage media status when ejecting [CHAR LIMIT=32] --> + <string name="ext_media_status_ejecting">Ejecting\u2026</string> + <!-- Short summary of storage media status when formatting [CHAR LIMIT=32] --> + <string name="ext_media_status_formatting">Formatting\u2026</string> + <!-- Short summary of storage media status when missing [CHAR LIMIT=32] --> + <string name="ext_media_status_missing">Not inserted</string> + <!-- Shown in LauncherActivity when the requested target Intent didn't return any matching Activities, leaving the list empty. --> <string name="activity_list_empty">No matching activities found.</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 4eba117..4bad16d 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1017,6 +1017,10 @@ please see styles_device_defaults.xml. <item name="negativeButtonText">@string/no</item> </style> + <style name="Preference.DialogPreference.SeekBarPreference"> + <item name="dialogLayout">@layout/preference_dialog_seekbar</item> + </style> + <style name="Preference.DialogPreference.EditTextPreference"> <item name="dialogLayout">@layout/preference_dialog_edittext</item> </style> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index df4106e..70f9c02 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -87,6 +87,10 @@ please see styles_device_defaults.xml. <item name="negativeButtonText">@string/no</item> </style> + <style name="Preference.Material.DialogPreference.SeekBarPreference"> + <item name="dialogLayout">@layout/preference_dialog_seekbar_material</item> + </style> + <style name="Preference.Material.DialogPreference.EditTextPreference"> <item name="dialogLayout">@layout/preference_dialog_edittext_material</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 15b253d..8900688 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1341,7 +1341,6 @@ <java-symbol type="layout" name="preference_widget_seekbar" /> <java-symbol type="layout" name="progress_dialog" /> <java-symbol type="layout" name="resolve_list_item" /> - <java-symbol type="layout" name="seekbar_dialog" /> <java-symbol type="layout" name="select_dialog_singlechoice_holo" /> <java-symbol type="layout" name="ssl_certificate" /> <java-symbol type="layout" name="tab_content" /> @@ -2292,4 +2291,20 @@ <java-symbol type="string" name="config_radio_access_family" /> <java-symbol type="string" name="notification_inbox_ellipsis" /> <java-symbol type="bool" name="config_mainBuiltInDisplayIsRound" /> + + <java-symbol type="attr" name="seekBarDialogPreferenceStyle" /> + <java-symbol type="string" name="ext_media_status_removed" /> + <java-symbol type="string" name="ext_media_status_unmounted" /> + <java-symbol type="string" name="ext_media_status_checking" /> + <java-symbol type="string" name="ext_media_status_mounted" /> + <java-symbol type="string" name="ext_media_status_mounted_ro" /> + <java-symbol type="string" name="ext_media_status_bad_removal" /> + <java-symbol type="string" name="ext_media_status_unmountable" /> + <java-symbol type="string" name="ext_media_status_unsupported" /> + <java-symbol type="string" name="ext_media_status_ejecting" /> + <java-symbol type="string" name="ext_media_status_formatting" /> + <java-symbol type="string" name="ext_media_status_missing" /> + <java-symbol type="string" name="ext_media_unsupported_notification_message" /> + <java-symbol type="string" name="ext_media_unsupported_notification_title" /> + </resources> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 9e87b4d..ecf00f0 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -331,6 +331,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child</item> @@ -386,6 +387,7 @@ please see themes_device_defaults.xml. <item name="buttonBarNegativeButtonStyle">?attr/buttonBarButtonStyle</item> <item name="buttonBarNeutralButtonStyle">?attr/buttonBarButtonStyle</item> <item name="segmentedButtonStyle">@style/SegmentedButton</item> + <item name="fingerprintAuthDrawable">@drawable/ic_fingerprint</item> <!-- SearchView attributes --> <item name="searchViewStyle">@style/Widget.Holo.SearchView</item> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index 9f3668d..295b453 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -295,6 +295,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.Material.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.Material.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child_material</item> @@ -304,7 +305,6 @@ please see themes_device_defaults.xml. <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList.Material</item> <item name="preferenceFragmentPaddingSide">@dimen/preference_fragment_padding_side_material</item> <item name="detailsElementBackground">?attr/colorBackground</item> - <item name="fingerprintDrawable">@drawable/ic_fingerprint_dark</item> <!-- PreferenceFrameLayout attributes --> <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item> @@ -651,6 +651,7 @@ please see themes_device_defaults.xml. <item name="seekBarPreferenceStyle">@style/Preference.Material.SeekBarPreference</item> <item name="yesNoPreferenceStyle">@style/Preference.Material.DialogPreference.YesNoPreference</item> <item name="dialogPreferenceStyle">@style/Preference.Material.DialogPreference</item> + <item name="seekBarDialogPreferenceStyle">@style/Preference.Material.DialogPreference.SeekBarPreference</item> <item name="editTextPreferenceStyle">@style/Preference.Material.DialogPreference.EditTextPreference</item> <item name="ringtonePreferenceStyle">@style/Preference.Material.RingtonePreference</item> <item name="preferenceLayoutChild">@layout/preference_child_material</item> @@ -660,7 +661,6 @@ please see themes_device_defaults.xml. <item name="preferenceFragmentListStyle">@style/PreferenceFragmentList.Material</item> <item name="preferenceFragmentPaddingSide">@dimen/preference_fragment_padding_side_material</item> <item name="detailsElementBackground">?attr/colorBackground</item> - <item name="fingerprintDrawable">@drawable/ic_fingerprint_light</item> <!-- PreferenceFrameLayout attributes --> <item name="preferenceFrameLayoutStyle">@style/Widget.Material.PreferenceFrameLayout</item> diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index 1af48ca..134451b 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -333,17 +333,29 @@ public class RippleDrawable extends LayerDrawable { */ @Override public boolean isProjected() { - // If the maximum radius is contained entirely within the bounds, we - // don't need to project this ripple. + // If the layer is bounded, then we don't need to project. + if (isBounded()) { + return false; + } + + // Otherwise, if the maximum radius is contained entirely within the + // bounds then we don't need to project. This is sort of a hack to + // prevent check box ripples from being projected across the edges of + // scroll views. It does not impact rendering performance, and it can + // be removed once we have better handling of projection in scrollable + // views. final int radius = mState.mMaxRadius; - final Rect bounds = getBounds(); - if (radius != RADIUS_AUTO && radius <= bounds.width() / 2 - && radius <= bounds.height() / 2) { + final Rect drawableBounds = getBounds(); + final Rect hotspotBounds = mHotspotBounds; + if (radius != RADIUS_AUTO + && radius <= hotspotBounds.width() / 2 + && radius <= hotspotBounds.height() / 2 + && (drawableBounds.equals(hotspotBounds) + || drawableBounds.contains(hotspotBounds))) { return false; } - // Otherwise, if the layer is bounded then we don't need to project. - return !isBounded(); + return true; } private boolean isBounded() { diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 89d419a..6c26220 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -1382,7 +1382,7 @@ public final class MediaCodecInfo { // upper limit. // for now we are keeping the profile specific "width/height // in macroblocks" limits. - if (Integer.valueOf(1).equals(map.get("feature-can-swap-width-height"))) { + if (map.containsKey("feature-can-swap-width-height")) { if (widths != null) { mSmallerDimensionUpperLimit = Math.min(widths.getUpper(), heights.getUpper()); diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 64863c2..1355635 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -35,6 +35,7 @@ import android.os.ServiceManager; import android.util.AndroidRuntimeException; import android.util.Log; +import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; @@ -125,10 +126,12 @@ public class SoundPool { private EventHandler mEventHandler; private SoundPool.OnLoadCompleteListener mOnLoadCompleteListener; + private boolean mHasAppOpsPlayAudio; private final Object mLock; private final AudioAttributes mAttributes; private final IAppOpsService mAppOps; + private final IAppOpsCallback mAppOpsCallback; /** * Constructor. Constructs a SoundPool object with the following @@ -159,6 +162,24 @@ public class SoundPool { mAttributes = attributes; IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); mAppOps = IAppOpsService.Stub.asInterface(b); + // initialize mHasAppOpsPlayAudio + updateAppOpsPlayAudio(); + // register a callback to monitor whether the OP_PLAY_AUDIO is still allowed + mAppOpsCallback = new IAppOpsCallback.Stub() { + public void opChanged(int op, String packageName) { + synchronized (mLock) { + if (op == AppOpsManager.OP_PLAY_AUDIO) { + updateAppOpsPlayAudio(); + } + } + } + }; + try { + mAppOps.startWatchingMode(AppOpsManager.OP_PLAY_AUDIO, + ActivityThread.currentPackageName(), mAppOpsCallback); + } catch (RemoteException e) { + mHasAppOpsPlayAudio = false; + } } /** @@ -168,7 +189,16 @@ public class SoundPool { * object. The SoundPool can no longer be used and the reference * should be set to null. */ - public native final void release(); + public final void release() { + try { + mAppOps.stopWatchingMode(mAppOpsCallback); + } catch (RemoteException e) { + // nothing to do here, the SoundPool is being released anyway + } + native_release(); + } + + private native final void native_release(); protected void finalize() { release(); } @@ -466,13 +496,17 @@ public class SoundPool { if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { return false; } + return !mHasAppOpsPlayAudio; + } + + private void updateAppOpsPlayAudio() { try { final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, mAttributes.getUsage(), Process.myUid(), ActivityThread.currentPackageName()); - return mode != AppOpsManager.MODE_ALLOWED; + mHasAppOpsPlayAudio = (mode == AppOpsManager.MODE_ALLOWED); } catch (RemoteException e) { - return false; + mHasAppOpsPlayAudio = false; } } diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java index ef8d169..ba867e1 100644 --- a/media/java/android/media/browse/MediaBrowser.java +++ b/media/java/android/media/browse/MediaBrowser.java @@ -375,7 +375,7 @@ public final class MediaBrowser { * @param mediaId The id of the item to retrieve. * @param cb The callback to receive the result on. */ - public void getMediaItem(@NonNull String mediaId, @NonNull final MediaItemCallback cb) { + public void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb) { if (TextUtils.isEmpty(mediaId)) { throw new IllegalArgumentException("mediaId is empty."); } @@ -387,7 +387,7 @@ public final class MediaBrowser { mHandler.post(new Runnable() { @Override public void run() { - cb.onError(); + cb.onError(mediaId); } }); return; @@ -397,15 +397,15 @@ public final class MediaBrowser { protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode != 0 || resultData == null || !resultData.containsKey(MediaBrowserService.KEY_MEDIA_ITEM)) { - cb.onError(); + cb.onError(mediaId); return; } Parcelable item = resultData.getParcelable(MediaBrowserService.KEY_MEDIA_ITEM); if (!(item instanceof MediaItem)) { - cb.onError(); + cb.onError(mediaId); + return; } - cb.onMediaItemLoaded((MediaItem) resultData.getParcelable( - MediaBrowserService.KEY_MEDIA_ITEM)); + cb.onItemLoaded((MediaItem)item); } }; try { @@ -415,7 +415,7 @@ public final class MediaBrowser { mHandler.post(new Runnable() { @Override public void run() { - cb.onError(); + cb.onError(mediaId); } }); } @@ -728,6 +728,9 @@ public final class MediaBrowser { public static abstract class SubscriptionCallback { /** * Called when the list of children is loaded or updated. + * + * @param parentId The media id of the parent media item. + * @param children The children which were loaded. */ public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaItem> children) { @@ -739,29 +742,32 @@ public final class MediaBrowser { * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe} * called, because some errors may heal themselves. * </p> + * + * @param parentId The media id of the parent media item whose children could + * not be loaded. */ - public void onError(@NonNull String id) { + public void onError(@NonNull String parentId) { } } /** - * Callback for receiving the result of {@link #getMediaItem}. + * Callback for receiving the result of {@link #getItem}. */ - public static abstract class MediaItemCallback { - + public static abstract class ItemCallback { /** * Called when the item has been returned by the browser service. * * @param item The item that was returned or null if it doesn't exist. */ - public void onMediaItemLoaded(MediaItem item) { + public void onItemLoaded(MediaItem item) { } /** - * Called when the id doesn't exist or there was an error retrieving the - * item. + * Called when the item doesn't exist or there was an error retrieving it. + * + * @param itemId The media id of the media item which could not be loaded. */ - public void onError() { + public void onError(@NonNull String itemId) { } } diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index c537dd6..5d1aa14 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -29,6 +29,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.hardware.hdmi.HdmiDeviceInfo; import android.net.Uri; import android.os.Parcel; @@ -125,7 +126,9 @@ public final class TvInputInfo implements Parcelable { private String mSettingsActivity; private HdmiDeviceInfo mHdmiDeviceInfo; + private int mLabelRes; private String mLabel; + private Icon mIcon; private Uri mIconUri; private boolean mIsConnectedToHdmiSwitch; @@ -155,7 +158,7 @@ public final class TvInputInfo implements Parcelable { throws XmlPullParserException, IOException { return createTvInputInfo(context, service, generateInputIdForComponentName( new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name)), - null, TYPE_TUNER, false, null, null, false); + null, TYPE_TUNER, false, 0, null, null, null, false); } /** @@ -165,11 +168,11 @@ public final class TvInputInfo implements Parcelable { * @param service The ResolveInfo returned from the package manager about this TV input service. * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device. * @param parentId The ID of this TV input's parent input. {@code null} if none exists. + * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service} + * label will be loaded. * @param iconUri The {@link android.net.Uri} to load the icon image. See * {@link android.content.ContentResolver#openInputStream}. If it is {@code null}, * the application icon of {@code service} will be loaded. - * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service} - * label will be loaded. * @hide */ @SystemApi @@ -179,7 +182,34 @@ public final class TvInputInfo implements Parcelable { boolean isConnectedToHdmiSwitch = (hdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0; TvInputInfo input = createTvInputInfo(context, service, generateInputIdForHdmiDevice( new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name), - hdmiDeviceInfo), parentId, TYPE_HDMI, true, label, iconUri, isConnectedToHdmiSwitch); + hdmiDeviceInfo), parentId, TYPE_HDMI, true, 0, label, null, iconUri, + isConnectedToHdmiSwitch); + input.mHdmiDeviceInfo = hdmiDeviceInfo; + return input; + } + + /** + * Create a new instance of the TvInputInfo class, instantiating it from the given Context, + * ResolveInfo, and HdmiDeviceInfo. + * + * @param service The ResolveInfo returned from the package manager about this TV input service. + * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device. + * @param parentId The ID of this TV input's parent input. {@code null} if none exists. + * @param labelRes The label resource ID of this TvInputInfo. If it is {@code 0}, + * {@code service} label will be loaded. + * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is + * {@code null}, the application icon of {@code service} will be loaded. + * @hide + */ + @SystemApi + public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service, + HdmiDeviceInfo hdmiDeviceInfo, String parentId, int labelRes, Icon icon) + throws XmlPullParserException, IOException { + boolean isConnectedToHdmiSwitch = (hdmiDeviceInfo.getPhysicalAddress() & 0x0FFF) != 0; + TvInputInfo input = createTvInputInfo(context, service, generateInputIdForHdmiDevice( + new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name), + hdmiDeviceInfo), parentId, TYPE_HDMI, true, labelRes, null, icon, null, + isConnectedToHdmiSwitch); input.mHdmiDeviceInfo = hdmiDeviceInfo; return input; } @@ -190,11 +220,11 @@ public final class TvInputInfo implements Parcelable { * * @param service The ResolveInfo returned from the package manager about this TV input service. * @param hardwareInfo The TvInputHardwareInfo for a TV input hardware device. + * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service} + * label will be loaded. * @param iconUri The {@link android.net.Uri} to load the icon image. See * {@link android.content.ContentResolver#openInputStream}. If it is {@code null}, * the application icon of {@code service} will be loaded. - * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service} - * label will be loaded. * @hide */ @SystemApi @@ -204,12 +234,34 @@ public final class TvInputInfo implements Parcelable { int inputType = sHardwareTypeToTvInputType.get(hardwareInfo.getType(), TYPE_TUNER); return createTvInputInfo(context, service, generateInputIdForHardware( new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name), - hardwareInfo), null, inputType, true, label, iconUri, false); + hardwareInfo), null, inputType, true, 0, label, null, iconUri, false); + } + + /** + * Create a new instance of the TvInputInfo class, instantiating it from the given Context, + * ResolveInfo, and TvInputHardwareInfo. + * + * @param service The ResolveInfo returned from the package manager about this TV input service. + * @param hardwareInfo The TvInputHardwareInfo for a TV input hardware device. + * @param labelRes The label resource ID of this TvInputInfo. If it is {@code 0}, + * {@code service} label will be loaded. + * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is + * {@code null}, the application icon of {@code service} will be loaded. + * @hide + */ + @SystemApi + public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service, + TvInputHardwareInfo hardwareInfo, int labelRes, Icon icon) + throws XmlPullParserException, IOException { + int inputType = sHardwareTypeToTvInputType.get(hardwareInfo.getType(), TYPE_TUNER); + return createTvInputInfo(context, service, generateInputIdForHardware( + new ComponentName(service.serviceInfo.packageName, service.serviceInfo.name), + hardwareInfo), null, inputType, true, labelRes, null, icon, null, false); } - private static TvInputInfo createTvInputInfo(Context context, ResolveInfo service, - String id, String parentId, int inputType, boolean isHardwareInput, String label, - Uri iconUri, boolean isConnectedToHdmiSwitch) + private static TvInputInfo createTvInputInfo(Context context, ResolveInfo service, String id, + String parentId, int inputType, boolean isHardwareInput, int labelRes, String label, + Icon icon, Uri iconUri, boolean isConnectedToHdmiSwitch) throws XmlPullParserException, IOException { ServiceInfo si = service.serviceInfo; PackageManager pm = context.getPackageManager(); @@ -254,7 +306,9 @@ public final class TvInputInfo implements Parcelable { } sa.recycle(); + input.mLabelRes = labelRes; input.mLabel = label; + input.mIcon = icon; input.mIconUri = iconUri; input.mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch; return input; @@ -426,11 +480,13 @@ public final class TvInputInfo implements Parcelable { * a label, its name is returned. */ public CharSequence loadLabel(@NonNull Context context) { - if (TextUtils.isEmpty(mLabel)) { - return mService.loadLabel(context.getPackageManager()); - } else { + if (mLabelRes != 0) { + return context.getPackageManager().getText(mService.serviceInfo.packageName, mLabelRes, + null); + } else if (!TextUtils.isEmpty(mLabel)) { return mLabel; } + return mService.loadLabel(context.getPackageManager()); } /** @@ -454,19 +510,20 @@ public final class TvInputInfo implements Parcelable { * application's icon is returned. If it's unavailable too, {@code null} is returned. */ public Drawable loadIcon(@NonNull Context context) { - if (mIconUri == null) { - return loadServiceIcon(context); - } - try (InputStream is = context.getContentResolver().openInputStream(mIconUri)) { - Drawable drawable = Drawable.createFromStream(is, null); - if (drawable == null) { - return loadServiceIcon(context); + if (mIcon != null) { + return mIcon.loadDrawable(context); + } else if (mIconUri != null) { + try (InputStream is = context.getContentResolver().openInputStream(mIconUri)) { + Drawable drawable = Drawable.createFromStream(is, null); + if (drawable != null) { + return drawable; + } + } catch (IOException e) { + Log.w(TAG, "Loading the default icon due to a failure on loading " + mIconUri, e); + // Falls back. } - return drawable; - } catch (IOException e) { - Log.w(TAG, "Loading the default icon due to a failure on loading " + mIconUri, e); - return loadServiceIcon(context); } + return loadServiceIcon(context); } @Override @@ -516,7 +573,9 @@ public final class TvInputInfo implements Parcelable { dest.writeInt(mType); dest.writeByte(mIsHardwareInput ? (byte) 1 : 0); dest.writeParcelable(mHdmiDeviceInfo, flags); + dest.writeParcelable(mIcon, flags); dest.writeParcelable(mIconUri, flags); + dest.writeInt(mLabelRes); dest.writeString(mLabel); dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0); } @@ -591,7 +650,9 @@ public final class TvInputInfo implements Parcelable { mType = in.readInt(); mIsHardwareInput = in.readByte() == 1 ? true : false; mHdmiDeviceInfo = in.readParcelable(null); + mIcon = in.readParcelable(null); mIconUri = in.readParcelable(null); + mLabelRes = in.readInt(); mLabel = in.readString(); mIsConnectedToHdmiSwitch = in.readByte() == 1 ? true : false; } diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index 41156cb..1bb99ff 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -76,7 +76,7 @@ public abstract class MediaBrowserService extends Service { public static final String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService"; /** - * A key for passing the MediaItem to the ResultReceiver in getMediaItem. + * A key for passing the MediaItem to the ResultReceiver in getItem. * * @hide */ @@ -109,6 +109,7 @@ public abstract class MediaBrowserService extends Service { * be thrown. * * @see MediaBrowserService#onLoadChildren + * @see MediaBrowserService#onGetMediaItem */ public class Result<T> { private Object mDebug; @@ -279,20 +280,7 @@ public abstract class MediaBrowserService extends Service { mHandler.post(new Runnable() { @Override public void run() { - final Result<MediaBrowser.MediaItem> result - = new Result<MediaBrowser.MediaItem>(mediaId) { - @Override - void onResultSent(MediaBrowser.MediaItem item) { - Bundle bundle = new Bundle(); - bundle.putParcelable(KEY_MEDIA_ITEM, item); - receiver.send(0, bundle); - } - }; - try { - MediaBrowserService.this.getMediaItem(mediaId, result); - } catch (UnsupportedOperationException e) { - receiver.send(-1, null); - } + performLoadItem(mediaId, receiver); } }); } @@ -357,8 +345,7 @@ public abstract class MediaBrowserService extends Service { @NonNull Result<List<MediaBrowser.MediaItem>> result); /** - * Called to get a specific media item. The mediaId should be the same id - * that would be returned for this item when it is in a list of child items. + * Called to get information about a specific media item. * <p> * Implementations must call {@link Result#sendResult result.sendResult}. If * loading the item will be an expensive operation {@link Result#detach @@ -366,17 +353,15 @@ public abstract class MediaBrowserService extends Service { * then {@link Result#sendResult result.sendResult} called when the item has * been loaded. * <p> - * The default implementation throws an exception. + * The default implementation sends a null result. * - * @param mediaId The id for the specific + * @param itemId The id for the specific * {@link android.media.browse.MediaBrowser.MediaItem}. * @param result The Result to send the item to, or null if the id is * invalid. - * @throws UnsupportedOperationException */ - public void getMediaItem(String mediaId, Result<MediaBrowser.MediaItem> result) - throws UnsupportedOperationException { - throw new UnsupportedOperationException("getMediaItem is not supported."); + public void onLoadItem(String itemId, Result<MediaBrowser.MediaItem> result) { + result.sendResult(null); } /** @@ -515,6 +500,25 @@ public abstract class MediaBrowserService extends Service { } } + private void performLoadItem(String itemId, final ResultReceiver receiver) { + final Result<MediaBrowser.MediaItem> result = + new Result<MediaBrowser.MediaItem>(itemId) { + @Override + void onResultSent(MediaBrowser.MediaItem item) { + Bundle bundle = new Bundle(); + bundle.putParcelable(KEY_MEDIA_ITEM, item); + receiver.send(0, bundle); + } + }; + + MediaBrowserService.this.onLoadItem(itemId, result); + + if (!result.isDone()) { + throw new IllegalStateException("onLoadItem must call detach() or sendResult()" + + " before returning for id=" + itemId); + } + } + /** * Contains information that the browser service needs to send to the client * when first connected. diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp index 294cd84..634ba64 100644 --- a/media/jni/android_media_ImageWriter.cpp +++ b/media/jni/android_media_ImageWriter.cpp @@ -293,7 +293,8 @@ static jlong ImageWriter_init(JNIEnv* env, jobject thiz, jobject weakThiz, jobje res = native_window_set_usage(anw.get(), GRALLOC_USAGE_SW_WRITE_OFTEN); if (res != OK) { ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)", - __FUNCTION__, GRALLOC_USAGE_SW_WRITE_OFTEN, format, strerror(-res), res); + __FUNCTION__, static_cast<unsigned int>(GRALLOC_USAGE_SW_WRITE_OFTEN), + format, strerror(-res), res); jniThrowRuntimeException(env, "Failed to SW_WRITE_OFTEN configure usage"); return 0; } diff --git a/media/jni/soundpool/android_media_SoundPool.cpp b/media/jni/soundpool/android_media_SoundPool.cpp index fc4cf05..ab3e340 100644 --- a/media/jni/soundpool/android_media_SoundPool.cpp +++ b/media/jni/soundpool/android_media_SoundPool.cpp @@ -286,7 +286,7 @@ static JNINativeMethod gMethods[] = { "(Ljava/lang/Object;ILjava/lang/Object;)I", (void*)android_media_SoundPool_native_setup }, - { "release", + { "native_release", "()V", (void*)android_media_SoundPool_release } diff --git a/native/android/Android.mk b/native/android/Android.mk index 12fdf71..1742bee 100644 --- a/native/android/Android.mk +++ b/native/android/Android.mk @@ -16,6 +16,7 @@ LOCAL_SRC_FILES:= \ obb.cpp \ sensor.cpp \ storage_manager.cpp \ + trace.cpp \ LOCAL_SHARED_LIBRARIES := \ liblog \ diff --git a/native/android/trace.cpp b/native/android/trace.cpp new file mode 100644 index 0000000..db52220 --- /dev/null +++ b/native/android/trace.cpp @@ -0,0 +1,30 @@ +/* + * 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 <android/trace.h> +#include <cutils/trace.h> + +bool ATrace_isEnabled() { + return atrace_is_tag_enabled(ATRACE_TAG_APP); +} + +void ATrace_beginSection(const char* sectionName) { + atrace_begin(ATRACE_TAG_APP, sectionName); +} + +void ATrace_endSection() { + atrace_end(ATRACE_TAG_APP); +} diff --git a/packages/DocumentsUI/res/layout-sw720dp/activity.xml b/packages/DocumentsUI/res/layout-sw720dp/activity.xml index a9f1b3c..2a273f4 100644 --- a/packages/DocumentsUI/res/layout-sw720dp/activity.xml +++ b/packages/DocumentsUI/res/layout-sw720dp/activity.xml @@ -19,7 +19,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - <Toolbar + <com.android.documentsui.DocumentsToolBar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?android:attr/actionBarSize" @@ -34,7 +34,7 @@ android:layout_marginStart="4dp" android:overlapAnchor="true" /> - </Toolbar> + </com.android.documentsui.DocumentsToolBar> <LinearLayout android:layout_width="match_parent" diff --git a/packages/DocumentsUI/res/layout/activity.xml b/packages/DocumentsUI/res/layout/activity.xml index b549cd3..43fdaf2 100644 --- a/packages/DocumentsUI/res/layout/activity.xml +++ b/packages/DocumentsUI/res/layout/activity.xml @@ -24,7 +24,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - <Toolbar + <com.android.documentsui.DocumentsToolBar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?android:attr/actionBarSize" @@ -39,7 +39,7 @@ android:layout_marginStart="4dp" android:overlapAnchor="true" /> - </Toolbar> + </com.android.documentsui.DocumentsToolBar> <com.android.documentsui.DirectoryContainerView android:id="@+id/container_directory" diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml index 9794273..943104d 100644 --- a/packages/DocumentsUI/res/values/strings.xml +++ b/packages/DocumentsUI/res/values/strings.xml @@ -45,7 +45,7 @@ <!-- Menu item title that deletes the selected documents [CHAR LIMIT=24] --> <string name="menu_delete">Delete</string> <!-- Menu item title that selects all documents in the current directory [CHAR LIMIT=24] --> - <string name="menu_select_all">Select All</string> + <string name="menu_select_all">Select all</string> <!-- Menu item title that copies the selected documents [CHAR LIMIT=24] --> <string name="menu_copy">Copy to\u2026</string> diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index 8ea5816..bba33be 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -101,7 +101,7 @@ abstract class BaseActivity extends Activity { boolean showMenu = super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.activity, menu); - mSearchManager.install(menu.findItem(R.id.menu_search)); + mSearchManager.install((DocumentsToolBar) findViewById(R.id.toolbar)); return showMenu; } @@ -666,20 +666,24 @@ abstract class BaseActivity extends Activity { * Facade over the various search parts in the menu. */ final class SearchManager implements - SearchView.OnCloseListener, OnActionExpandListener, OnQueryTextListener { + SearchView.OnCloseListener, OnActionExpandListener, OnQueryTextListener, + DocumentsToolBar.OnActionViewCollapsedListener { private boolean mSearchExpanded; private boolean mIgnoreNextClose; private boolean mIgnoreNextCollapse; + private DocumentsToolBar mActionBar; private MenuItem mMenu; private SearchView mView; - public void install(MenuItem menu) { - assert(mMenu == null); - mMenu = menu; - mView = (SearchView) menu.getActionView(); + public void install(DocumentsToolBar actionBar) { + assert(mActionBar == null); + mActionBar = actionBar; + mMenu = actionBar.getSearchMenu(); + mView = (SearchView) mMenu.getActionView(); + mActionBar.setOnActionViewCollapsedListener(this); mMenu.setOnActionExpandListener(this); mView.setOnQueryTextListener(this); mView.setOnCloseListener(this); @@ -730,6 +734,19 @@ abstract class BaseActivity extends Activity { } } + /** + * Cancels current search operation. + * @return True if it cancels search. False if it does not operate + * search currently. + */ + boolean cancelSearch() { + if (mActionBar.hasExpandedActionView()) { + mActionBar.collapseActionView(); + return true; + } + return false; + } + boolean isSearching() { return getDisplayState().currentSearch != null; } @@ -765,7 +782,6 @@ abstract class BaseActivity extends Activity { mIgnoreNextCollapse = false; return true; } - getDisplayState().currentSearch = null; onCurrentDirectoryChanged(ANIM_NONE); return true; @@ -784,5 +800,10 @@ abstract class BaseActivity extends Activity { public boolean onQueryTextChange(String newText) { return false; } + + @Override + public void onActionViewCollapsed() { + updateActionBar(); + } } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index 69ae34e..90ccf91 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; @@ -508,6 +509,11 @@ public class DocumentsActivity extends BaseActivity { @Override public void onBackPressed() { + // While action bar is expanded, the state stack UI is hidden. + if (mSearchManager.cancelSearch()) { + return; + } + if (!mState.stackTouched) { super.onBackPressed(); return; diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java new file mode 100644 index 0000000..36b7646 --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsToolBar.java @@ -0,0 +1,72 @@ +/* + * 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.documentsui; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MenuItem; +import android.widget.Toolbar; + +/** + * ToolBar of Documents UI. + */ +public class DocumentsToolBar extends Toolbar { + interface OnActionViewCollapsedListener { + void onActionViewCollapsed(); + } + + private OnActionViewCollapsedListener mOnActionViewCollapsedListener; + + public DocumentsToolBar(Context context, AttributeSet attrs, + int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public DocumentsToolBar(Context context, AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public DocumentsToolBar(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public DocumentsToolBar(Context context) { + super(context); + } + + @Override + public void collapseActionView() { + super.collapseActionView(); + if (mOnActionViewCollapsedListener != null) { + mOnActionViewCollapsedListener.onActionViewCollapsed(); + } + } + + /** + * Adds a listener that is invoked after collapsing the action view. + * @param listener + */ + public void setOnActionViewCollapsedListener( + OnActionViewCollapsedListener listener) { + mOnActionViewCollapsedListener = listener; + } + + public MenuItem getSearchMenu() { + return getMenu().findItem(R.id.menu_search); + } +} diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml index 0f5431e..09c01de 100644 --- a/packages/Keyguard/res/layout/keyguard_pattern_view.xml +++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml @@ -31,8 +31,7 @@ android:clipToPadding="false" androidprv:layout_maxWidth="@dimen/keyguard_security_width" androidprv:layout_maxHeight="@dimen/keyguard_security_height" - android:gravity="center_horizontal" - android:contentDescription="@string/keyguard_accessibility_pattern_unlock"> + android:gravity="center_horizontal"> <FrameLayout android:layout_width="match_parent" diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml index 49ce427..748129c 100644 --- a/packages/Keyguard/res/values/strings.xml +++ b/packages/Keyguard/res/values/strings.xml @@ -299,6 +299,42 @@ <!-- Description of airplane mode --> <string name="airplane_mode">Airplane mode</string> + <!-- An explanation text that the pattern needs to be solved since the device has just been restarted. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_restart_pattern">Pattern required when you restart device.</string> + + <!-- An explanation text that the pin needs to be entered since the device has just been restarted. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_restart_pin">PIN required when you restart device.</string> + + <!-- An explanation text that the password needs to be entered since the device has just been restarted. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_restart_password">Password required when you restart device.</string> + + <!-- An explanation text that the pattern needs to be solved since profiles have just been switched. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_switch_profiles_pattern">Pattern required when you switch profiles.</string> + + <!-- An explanation text that the pin needs to be entered since profiles have just been switched. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_switch_profiles_pin">PIN required when you switch profiles.</string> + + <!-- An explanation text that the password needs to be entered since profiles have just been switched. [CHAR LIMIT=80] --> + <string name="kg_prompt_reason_switch_profiles_password">Password required when you switch profiles.</string> + + <!-- An explanation text that the pattern needs to be solved since it hasn't been solved in a while. [CHAR LIMIT=80]--> + <plurals name="kg_prompt_reason_time_pattern"> + <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hour. Confirm pattern.</item> + <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hours. Confirm pattern.</item> + </plurals> + + <!-- An explanation text that the pin needs to be entered since it hasn't been entered in a while. [CHAR LIMIT=80]--> + <plurals name="kg_prompt_reason_time_pin"> + <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hour. Confirm PIN.</item> + <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hours. Confirm PIN.</item> + </plurals> + + <!-- An explanation text that the password needs to be entered since it hasn't been entered in a while. [CHAR LIMIT=80]--> + <plurals name="kg_prompt_reason_time_password"> + <item quantity="one">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hour. Confirm password.</item> + <item quantity="other">Device hasn\'t been unlocked for <xliff:g id="number">%d</xliff:g> hours. Confirm password.</item> + </plurals> + <!-- Fingerprint hint message when finger was not recognized.--> <string name="fingerprint_not_recognized">Not recognized</string> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java index d0be855..ac9dc85 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java @@ -22,6 +22,9 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; +import com.android.settingslib.animation.AppearAnimationUtils; +import com.android.settingslib.animation.DisappearAnimationUtils; + /** * Displays a PIN pad for unlocking. */ @@ -115,7 +118,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { .setDuration(500) .setInterpolator(mAppearAnimationUtils.getInterpolator()) .translationY(0); - mAppearAnimationUtils.startAnimation(mViews, + mAppearAnimationUtils.startAnimation2d(mViews, new Runnable() { @Override public void run() { @@ -132,7 +135,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { .setDuration(280) .setInterpolator(mDisappearAnimationUtils.getInterpolator()) .translationY(mDisappearYTranslation); - mDisappearAnimationUtils.startAnimation(mViews, + mDisappearAnimationUtils.startAnimation2d(mViews, new Runnable() { @Override public void run() { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java index a9b2978..1bd0bb4 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java @@ -36,6 +36,9 @@ import android.widget.LinearLayout; import com.android.internal.widget.LockPatternChecker; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; +import com.android.settingslib.animation.AppearAnimationCreator; +import com.android.settingslib.animation.AppearAnimationUtils; +import com.android.settingslib.animation.DisappearAnimationUtils; import java.util.List; @@ -325,7 +328,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit .setDuration(500) .setInterpolator(mAppearAnimationUtils.getInterpolator()) .translationY(0); - mAppearAnimationUtils.startAnimation( + mAppearAnimationUtils.startAnimation2d( mLockPatternView.getCellStates(), new Runnable() { @Override @@ -353,7 +356,7 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit .setDuration(300) .setInterpolator(mDisappearAnimationUtils.getInterpolator()) .translationY(-mDisappearAnimationUtils.getStartTranslation()); - mDisappearAnimationUtils.startAnimation(mLockPatternView.getCellStates(), + mDisappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(), new Runnable() { @Override public void run() { diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java index ed0d4af..23834a3 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -150,13 +150,6 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView // Set selected property on so the view can send accessibility events. mPasswordEntry.setSelected(true); - // Poke the wakelock any time the text is selected or modified - mPasswordEntry.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - onUserInput(); - } - }); - mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() { @Override public void onUserActivity() { diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 4ba04e5..3c5dae3 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -679,6 +679,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (resolvedActivities.get(0).activityInfo.exported) { intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, mPrintJob); intent.putExtra(PrintService.EXTRA_PRINTER_INFO, printer); + intent.putExtra(PrintService.EXTRA_PRINT_JOB_INFO, + mPrintedDocument.getDocumentInfo().info); // This is external activity and may not be there. try { diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml new file mode 100644 index 0000000..1c4b05f --- /dev/null +++ b/packages/SettingsLib/res/values/dimens.xml @@ -0,0 +1,24 @@ +<?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> + + <!-- The y translation to apply at the start in appear animations. --> + <dimen name="appear_y_translation_start">32dp</dimen> + + <!-- The translation for disappearing security views after having solved them. --> + <dimen name="disappear_y_translation">-32dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/Keyguard/src/com/android/keyguard/AppearAnimationCreator.java b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationCreator.java index e4706b6..8a61e4e 100644 --- a/packages/Keyguard/src/com/android/keyguard/AppearAnimationCreator.java +++ b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationCreator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * 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. @@ -14,13 +14,13 @@ * limitations under the License */ -package com.android.keyguard; +package com.android.settingslib.animation; import android.view.animation.Interpolator; /** * An interface which can create animations when starting an appear animation with - * {@link com.android.keyguard.AppearAnimationUtils} + * {@link AppearAnimationUtils} */ public interface AppearAnimationCreator<T> { void createAnimation(T animatedObject, long delay, long duration, diff --git a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java index 9045fe3..441474d 100644 --- a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/animation/AppearAnimationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * 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. @@ -14,13 +14,15 @@ * limitations under the License */ -package com.android.keyguard; +package com.android.settingslib.animation; import android.content.Context; import android.view.View; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import com.android.settingslib.R; + /** * A class to make nice appear transitions for views in a tabular layout. */ @@ -33,7 +35,7 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { private final AppearAnimationProperties mProperties = new AppearAnimationProperties(); protected final float mDelayScale; private final long mDuration; - protected boolean mScaleTranslationWithRow; + protected RowTranslationScaler mRowTranslationScaler; protected boolean mAppearing; public AppearAnimationUtils(Context ctx) { @@ -49,19 +51,18 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { R.dimen.appear_y_translation_start) * translationScaleFactor; mDelayScale = delayScaleFactor; mDuration = duration; - mScaleTranslationWithRow = false; mAppearing = true; } - public void startAnimation(View[][] objects, final Runnable finishListener) { - startAnimation(objects, finishListener, this); + public void startAnimation2d(View[][] objects, final Runnable finishListener) { + startAnimation2d(objects, finishListener, this); } public void startAnimation(View[] objects, final Runnable finishListener) { startAnimation(objects, finishListener, this); } - public <T> void startAnimation(T[][] objects, final Runnable finishListener, + public <T> void startAnimation2d(T[][] objects, final Runnable finishListener, AppearAnimationCreator<T> creator) { AppearAnimationProperties properties = getDelays(objects); startAnimations(properties, objects, finishListener, creator); @@ -86,8 +87,13 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == 0) { endRunnable = finishListener; } + float translationScale = mRowTranslationScaler != null + ? mRowTranslationScaler.getRowTranslationScale(row, properties.delays.length) + : 1f; + float translation = translationScale * mStartTranslation; creator.createAnimation(objects[row], delay, mDuration, - mStartTranslation, true /* appearing */, mInterpolator, endRunnable); + mAppearing ? translation : -translation, + mAppearing, mInterpolator, endRunnable); } } @@ -99,10 +105,10 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { } for (int row = 0; row < properties.delays.length; row++) { long[] columns = properties.delays[row]; - float translation = mScaleTranslationWithRow - ? (float) (Math.pow((properties.delays.length - row), 2) - / properties.delays.length * mStartTranslation) - : mStartTranslation; + float translationScale = mRowTranslationScaler != null + ? mRowTranslationScaler.getRowTranslationScale(row, properties.delays.length) + : 1f; + float translation = translationScale * mStartTranslation; for (int col = 0; col < columns.length; col++) { long delay = columns[col]; Runnable endRunnable = null; @@ -193,4 +199,8 @@ public class AppearAnimationUtils implements AppearAnimationCreator<View> { public int maxDelayRowIndex; public int maxDelayColIndex; } + + public interface RowTranslationScaler { + float getRowTranslationScale(int row, int numRows); + } } diff --git a/packages/Keyguard/src/com/android/keyguard/DisappearAnimationUtils.java b/packages/SettingsLib/src/com/android/settingslib/animation/DisappearAnimationUtils.java index 517d96a..a444ff0 100644 --- a/packages/Keyguard/src/com/android/keyguard/DisappearAnimationUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/animation/DisappearAnimationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 The Android Open Source Project + * 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. @@ -14,7 +14,7 @@ * limitations under the License */ -package com.android.keyguard; +package com.android.settingslib.animation; import android.content.Context; import android.view.animation.AnimationUtils; @@ -28,17 +28,31 @@ public class DisappearAnimationUtils extends AppearAnimationUtils { public DisappearAnimationUtils(Context ctx) { this(ctx, DEFAULT_APPEAR_DURATION, 1.0f, 1.0f, - AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in)); + AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_linear_in)); } public DisappearAnimationUtils(Context ctx, long duration, float translationScaleFactor, float delayScaleFactor, Interpolator interpolator) { + this(ctx, duration, translationScaleFactor, delayScaleFactor, interpolator, + ROW_TRANSLATION_SCALER); + } + + public DisappearAnimationUtils(Context ctx, long duration, float translationScaleFactor, + float delayScaleFactor, Interpolator interpolator, RowTranslationScaler rowScaler) { super(ctx, duration, translationScaleFactor, delayScaleFactor, interpolator); - mScaleTranslationWithRow = true; + mRowTranslationScaler = rowScaler; mAppearing = false; } protected long calculateDelay(int row, int col) { return (long) ((row * 60 + col * (Math.pow(row, 0.4) + 0.4) * 10) * mDelayScale); } + + private static final RowTranslationScaler ROW_TRANSLATION_SCALER = new RowTranslationScaler() { + + @Override + public float getRowTranslationScale(int row, int numRows) { + return (float) (Math.pow((numRows - row), 2) / numRows); + } + }; } diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java index 3b59fd6..fe9b99a 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java @@ -90,7 +90,7 @@ public abstract class AbstractStatementRetriever { * Creates a new StatementRetriever that directly retrieves statements from the asset. * * <p> For web assets, {@link AbstractStatementRetriever} will try to retrieve the statement - * file from URL: {@code [webAsset.site]/.well-known/statements.json"} where {@code + * file from URL: {@code [webAsset.site]/.well-known/assetlinks.json"} where {@code * [webAsset.site]} is in the form {@code http{s}://[hostname]:[optional_port]}. The file * should contain one JSON array of statements. * diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java index 2ca85e9..e4feb90 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java @@ -38,7 +38,7 @@ import java.util.List; private static final int HTTP_CONNECTION_TIMEOUT_MILLIS = 5000; private static final long HTTP_CONTENT_SIZE_LIMIT_IN_BYTES = 1024 * 1024; private static final int MAX_INCLUDE_LEVEL = 1; - private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/statements.json"; + private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/assetlinks.json"; private final URLFetcher mUrlFetcher; private final AndroidPackageInfoFetcher mAndroidFetcher; diff --git a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java index da3c355..0f40a62 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java @@ -21,7 +21,7 @@ import android.annotation.NonNull; /** * An immutable value type representing a statement, consisting of a source, target, and relation. * This reflects an assertion that the relation holds for the source, target pair. For example, if a - * web site has the following in its statements.json file: + * web site has the following in its assetlinks.json file: * * <pre> * { diff --git a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java index 969aa88..225e26c 100644 --- a/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java +++ b/packages/StatementService/src/com/android/statementservice/retriever/URLFetcher.java @@ -60,33 +60,36 @@ public class URLFetcher { throw new IllegalArgumentException("The url protocol should be on http or https."); } - HttpURLConnection connection; - connection = (HttpURLConnection) url.openConnection(); - connection.setInstanceFollowRedirects(true); - connection.setConnectTimeout(connectionTimeoutMillis); - connection.setReadTimeout(connectionTimeoutMillis); - connection.setUseCaches(true); - connection.setInstanceFollowRedirects(false); - connection.addRequestProperty("Cache-Control", "max-stale=60"); - - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { - Log.e(TAG, "The responses code is not 200 but " + connection.getResponseCode()); - return new WebContent("", DO_NOT_CACHE_RESULT); - } + HttpURLConnection connection = null; + try { + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(true); + connection.setConnectTimeout(connectionTimeoutMillis); + connection.setReadTimeout(connectionTimeoutMillis); + connection.setUseCaches(true); + connection.setInstanceFollowRedirects(false); + connection.addRequestProperty("Cache-Control", "max-stale=60"); + + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + Log.e(TAG, "The responses code is not 200 but " + connection.getResponseCode()); + return new WebContent("", DO_NOT_CACHE_RESULT); + } - if (connection.getContentLength() > fileSizeLimit) { - Log.e(TAG, "The content size of the url is larger than " + fileSizeLimit); - return new WebContent("", DO_NOT_CACHE_RESULT); - } + if (connection.getContentLength() > fileSizeLimit) { + Log.e(TAG, "The content size of the url is larger than " + fileSizeLimit); + return new WebContent("", DO_NOT_CACHE_RESULT); + } - Long expireTimeMillis = getExpirationTimeMillisFromHTTPHeader(connection.getHeaderFields()); + Long expireTimeMillis = getExpirationTimeMillisFromHTTPHeader( + connection.getHeaderFields()); - try { return new WebContent(inputStreamToString( connection.getInputStream(), connection.getContentLength(), fileSizeLimit), expireTimeMillis); } finally { - connection.disconnect(); + if (connection != null) { + connection.disconnect(); + } } } diff --git a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml b/packages/SystemUI/res/drawable/managed_profile_toast_background.xml new file mode 100644 index 0000000..5c77b9a --- /dev/null +++ b/packages/SystemUI/res/drawable/managed_profile_toast_background.xml @@ -0,0 +1,21 @@ +<?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. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="2dp" /> + <solid android:color="@color/managed_profile_toast_background" /> +</shape> diff --git a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml index 3c4c646..2bfa39d 100644 --- a/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml +++ b/packages/SystemUI/res/drawable/stat_sys_managed_profile_status.xml @@ -20,10 +20,10 @@ Copyright (C) 2015 The Android Open Source Project android:viewportHeight="17.0"> <group android:translateX="2.0"> <path - android:fillColor="#FF000000" + android:fillColor="@android:color/white" android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/> <path - android:fillColor="#FF000000" + android:fillColor="@android:color/white" android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2 c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/> </group> </vector> diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 5d0367e..48af565 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -33,7 +33,8 @@ android:gravity="center_horizontal" android:textStyle="italic" android:textColor="#ffffff" - android:textAppearance="?android:attr/textAppearanceSmall" /> + android:textAppearance="?android:attr/textAppearanceSmall" + android:accessibilityLiveRegion="polite" /> <FrameLayout android:id="@+id/preview_container" diff --git a/packages/SystemUI/res/layout/managed_profile_toast.xml b/packages/SystemUI/res/layout/managed_profile_toast.xml new file mode 100644 index 0000000..5a01ca7 --- /dev/null +++ b/packages/SystemUI/res/layout/managed_profile_toast.xml @@ -0,0 +1,39 @@ +<?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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:paddingTop="16dp" + android:paddingBottom="16dp" + android:paddingLeft="32dp" + android:paddingRight="32dp" + android:background="@drawable/managed_profile_toast_background"> + <ImageView + android:layout_width="32dp" + android:layout_height="32dp" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="16dp" + android:src="@drawable/stat_sys_managed_profile_status"/> + <TextView android:text="@string/managed_profile_foreground_toast" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@android:color/white" + android:textSize="14sp" + android:layout_gravity="center_horizontal" /> +</LinearLayout> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 0dcbe88..9a96939 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -143,4 +143,6 @@ <color name="volume_icon_color">#ffffffff</color> <color name="volume_settings_icon_color">#7fffffff</color> <color name="volume_slider_inactive">#FFB0BEC5</color><!-- blue grey 200 --> + + <color name="managed_profile_toast_background">#E5000000</color><!-- 90% black --> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index de5639b..260d81b 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -135,8 +135,6 @@ <!-- The maximum number of items to be displayed in quick settings --> <integer name="quick_settings_detail_max_item_count">7</integer> - <integer name="blinds_pop_duration_ms">10</integer> - <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? --> <bool name="config_show4GForLTE">true</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 0e0584f..a0b70f0 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -772,6 +772,9 @@ <!-- Shows when people have clicked on the camera icon [CHAR LIMIT=60] --> <string name="camera_hint">Swipe from icon for camera</string> + <!-- Accessibility content description for Interruption level: None. [CHAR LIMIT=NONE] --> + <string name="interruption_level_none_with_warning">Total silence. This will also silence screen readers.</string> + <!-- Interruption level: None. [CHAR LIMIT=40] --> <string name="interruption_level_none">Total silence</string> @@ -847,7 +850,7 @@ <string name="guest_notification_title">Guest user</string> <!-- Text of the notification shown to a new guest user [CHAR LIMIT=60] --> - <string name="guest_notification_text">Remove guest to delete apps and data</string> + <string name="guest_notification_text">To delete apps and data, remove guest user</string> <!-- Remove action in the notification shown to a new guest user [CHAR LIMIT=30] --> <string name="guest_notification_remove_action">REMOVE GUEST</string> @@ -1009,7 +1012,7 @@ <string name="volumeui_notification_text">Touch to restore the original.</string> <!-- Toast shown when user unlocks screen and managed profile activity is in the foreground --> - <string name="managed_profile_foreground_toast">You are in the work profile</string> + <string name="managed_profile_foreground_toast">You\'re using your work profile</string> <string-array name="volume_stream_titles" translatable="false"> <item>Voice calls</item> <!-- STREAM_VOICE_CALL --> diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index fece07f..b0e2afa 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -25,6 +25,7 @@ import android.media.AudioAttributes; import android.os.Vibrator; import android.util.Log; import android.view.Gravity; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector.OnScaleGestureListener; @@ -64,15 +65,6 @@ public class ExpandHelper implements Gefingerpoken { // 2f: maximum brightness is stretching a 1U to 3U, or a 4U to 6U private static final float STRETCH_INTERVAL = 2f; - // level of glow for a touch, without overstretch - // overstretch fills the range (GLOW_BASE, 1.0] - private static final float GLOW_BASE = 0.5f; - - private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) - .build(); - @SuppressWarnings("unused") private Context mContext; @@ -94,13 +86,11 @@ public class ExpandHelper implements Gefingerpoken { private float mLastSpanY; private int mTouchSlop; private float mLastMotionY; - private int mPopDuration; private float mPullGestureMinXSpan; private Callback mCallback; private ScaleGestureDetector mSGD; private ViewScaler mScaler; private ObjectAnimator mScaleAnimation; - private Vibrator mVibrator; private boolean mEnabled = true; private ExpandableView mResizedView; private float mCurrentHeight; @@ -174,7 +164,6 @@ public class ExpandHelper implements Gefingerpoken { mScaler = new ViewScaler(); mGravity = Gravity.TOP; mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f); - mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min); final ViewConfiguration configuration = ViewConfiguration.get(mContext); @@ -452,7 +441,9 @@ public class ExpandHelper implements Gefingerpoken { } if (!mHasPopped) { - vibrate(mPopDuration); + if (mEventSource != null) { + mEventSource.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } mHasPopped = true; } @@ -600,16 +591,5 @@ public class ExpandHelper implements Gefingerpoken { public void onlyObserveMovements(boolean onlyMovements) { mOnlyMovements = onlyMovements; } - - /** - * Triggers haptic feedback. - */ - private synchronized void vibrate(long duration) { - if (mVibrator == null) { - mVibrator = (android.os.Vibrator) - mContext.getSystemService(Context.VIBRATOR_SERVICE); - } - mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); - } } diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java index 3e122da..1e7ee98 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java +++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java @@ -116,7 +116,6 @@ public class AssistManager { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); WindowManager.LayoutParams lp = getLayoutParams(); mWindowManager.addView(mView, lp); - mBar.getNavigationBarView().setDelegateView(mView); if (visible) { mView.show(true /* show */, false /* animate */); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 25e3d10..49eb9b2 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -360,7 +360,7 @@ public class QSPanel extends ViewGroup { } private void handleShowDetailTile(TileRecord r, boolean show) { - if ((mDetailRecord != null) == show) return; + if ((mDetailRecord != null) == show && mDetailRecord == r) return; if (show) { r.detailAdapter = r.tile.getDetailAdapter(); @@ -373,7 +373,8 @@ public class QSPanel extends ViewGroup { } private void handleShowDetailImpl(Record r, boolean show, int x, int y) { - if ((mDetailRecord != null) == show) return; // already in right state + boolean visibleDiff = (mDetailRecord != null) != show; + if (!visibleDiff && mDetailRecord == r) return; // already in right state DetailAdapter detailAdapter = null; AnimatorListener listener = null; if (show) { @@ -399,7 +400,7 @@ public class QSPanel extends ViewGroup { mContext.getString(detailAdapter.getTitle()))); setDetailRecord(r); listener = mHideGridContentWhenDone; - if (r instanceof TileRecord) { + if (r instanceof TileRecord && visibleDiff) { ((TileRecord) r).openingDetail = true; } } else { @@ -411,7 +412,9 @@ public class QSPanel extends ViewGroup { } sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); fireShowingDetail(show ? detailAdapter : null); - mClipper.animateCircularClip(x, y, show, listener); + if (visibleDiff) { + mClipper.animateCircularClip(x, y, show, listener); + } } private void setGridContentVisibility(boolean visible) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index c0b3a9b..7cde44c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -21,15 +21,8 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapShader; import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; import android.graphics.RectF; -import android.graphics.Shader; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -100,7 +93,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private boolean mDark; private int mBgTint = 0; - private final int mRoundedRectCornerRadius; /** * Flag to indicate that the notification has been touched once and the second touch will @@ -126,10 +118,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private NotificationBackgroundView mBackgroundDimmed; private ObjectAnimator mBackgroundAnimator; private RectF mAppearAnimationRect = new RectF(); - private PorterDuffColorFilter mAppearAnimationFilter; private float mAnimationTranslationY; private boolean mDrawingAppearAnimation; - private Paint mAppearPaint = new Paint(); private ValueAnimator mAppearAnimator; private float mAppearAnimationFraction = -1.0f; private float mAppearAnimationTranslation; @@ -151,9 +141,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mLinearInterpolator = new LinearInterpolator(); setClipChildren(false); setClipToPadding(false); - mAppearAnimationFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); - mRoundedRectCornerRadius = getResources().getDimensionPixelSize( - R.dimen.notification_material_rounded_rect_radius); mLegacyColor = context.getColor(R.color.notification_legacy_background_color); mNormalColor = context.getColor(R.color.notification_material_background_color); mLowPriorityColor = context.getColor( @@ -540,9 +527,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay, long duration, final Runnable onFinishedRunnable) { - if (mAppearAnimator != null) { - mAppearAnimator.cancel(); - } + cancelAppearAnimation(); mAnimationTranslationY = translationDirection * getActualHeight(); if (mAppearAnimationFraction == -1.0f) { // not initialized yet, we start anew @@ -613,6 +598,17 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mAppearAnimator.start(); } + private void cancelAppearAnimation() { + if (mAppearAnimator != null) { + mAppearAnimator.cancel(); + } + } + + public void cancelAppearDrawing() { + cancelAppearAnimation(); + enableAppearDrawing(false); + } + private void updateAppearRect() { float inverseFraction = (1.0f - mAppearAnimationFraction); float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction); @@ -652,20 +648,26 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } private void updateAppearAnimationAlpha() { - int backgroundColor = getBgColor(); - if (backgroundColor != -1) { - float contentAlphaProgress = mAppearAnimationFraction; - contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); - contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); - contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); - int sourceColor = Color.argb((int) (255 * (1.0f - contentAlphaProgress)), - Color.red(backgroundColor), Color.green(backgroundColor), - Color.blue(backgroundColor)); - mAppearAnimationFilter.setColor(sourceColor); - mAppearPaint.setColorFilter(mAppearAnimationFilter); + float contentAlphaProgress = mAppearAnimationFraction; + contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); + contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); + contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); + setContentAlpha(contentAlphaProgress); + } + + private void setContentAlpha(float contentAlpha) { + int layerType = contentAlpha == 0.0f || contentAlpha == 1.0f ? LAYER_TYPE_NONE + : LAYER_TYPE_HARDWARE; + View contentView = getContentView(); + int currentLayerType = contentView.getLayerType(); + if (currentLayerType != layerType) { + contentView.setLayerType(layerType, null); } + contentView.setAlpha(contentAlpha); } + protected abstract View getContentView(); + private int getBgColor() { if (mBgTint != 0) { return mBgTint; @@ -699,41 +701,24 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView */ private void enableAppearDrawing(boolean enable) { if (enable != mDrawingAppearAnimation) { - if (enable) { - if (getWidth() == 0 || getActualHeight() == 0) { - // TODO: This should not happen, but it can during expansion. Needs - // investigation - return; - } - Bitmap bitmap = Bitmap.createBitmap(getWidth(), getActualHeight(), - Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - draw(canvas); - mAppearPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, - Shader.TileMode.CLAMP)); - } else { - mAppearPaint.setShader(null); - } mDrawingAppearAnimation = enable; + if (!enable) { + setContentAlpha(1.0f); + } invalidate(); } } @Override protected void dispatchDraw(Canvas canvas) { - if (!mDrawingAppearAnimation) { - super.dispatchDraw(canvas); - } else { - drawAppearRect(canvas); + if (mDrawingAppearAnimation) { + canvas.save(); + canvas.translate(0, mAppearAnimationTranslation); + } + super.dispatchDraw(canvas); + if (mDrawingAppearAnimation) { + canvas.restore(); } - } - - private void drawAppearRect(Canvas canvas) { - canvas.save(); - canvas.translate(0, mAppearAnimationTranslation); - canvas.drawRoundRect(mAppearAnimationRect, mRoundedRectCornerRadius, - mRoundedRectCornerRadius, mAppearPaint); - canvas.restore(); } public void setOnActivatedListener(OnActivatedListener onActivatedListener) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 4cce1a4..85b4a64 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -65,6 +65,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.Display; +import android.view.Gravity; import android.view.IWindowManager; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -395,8 +396,14 @@ public abstract class BaseStatusBar extends SystemUI implements if (recentTask != null && recentTask.size() > 0) { UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId); if (user != null && user.isManagedProfile()) { - Toast.makeText(mContext, R.string.managed_profile_foreground_toast, - Toast.LENGTH_SHORT).show(); + LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + View layout = inflater.inflate(R.layout.managed_profile_toast, null); + Toast toast = new Toast(mContext); + toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); + toast.setDuration(Toast.LENGTH_SHORT); + toast.setView(layout); + toast.show(); } } } else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) { @@ -1848,11 +1855,8 @@ public abstract class BaseStatusBar extends SystemUI implements } } - if (onKeyguard && mKeyguardIconOverflowContainer.getIconsView().getChildCount() > 0) { - mKeyguardIconOverflowContainer.setVisibility(View.VISIBLE); - } else { - mKeyguardIconOverflowContainer.setVisibility(View.GONE); - } + mStackScroller.updateOverflowContainerVisibility(onKeyguard + && mKeyguardIconOverflowContainer.getIconsView().getChildCount() > 0); mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1); mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java deleted file mode 100644 index 2dc521e..0000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DelegateViewHelper.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.statusbar; - -import android.app.StatusBarManager; -import android.content.res.Resources; -import android.graphics.RectF; -import android.view.MotionEvent; -import android.view.View; -import com.android.systemui.R; -import com.android.systemui.statusbar.phone.PhoneStatusBar; - -public class DelegateViewHelper { - private View mDelegateView; - private View mSourceView; - private PhoneStatusBar mBar; - private int[] mTempPoint = new int[2]; - private float[] mDownPoint = new float[2]; - private float mTriggerThreshhold; - private boolean mPanelShowing; - - RectF mInitialTouch = new RectF(); - private boolean mStarted; - private boolean mSwapXY = false; - private boolean mDisabled; - - public DelegateViewHelper(View sourceView) { - setSourceView(sourceView); - } - - public void setDelegateView(View view) { - mDelegateView = view; - } - - public void setBar(PhoneStatusBar phoneStatusBar) { - mBar = phoneStatusBar; - } - - public boolean onInterceptTouchEvent(MotionEvent event) { - if (mSourceView == null || mDelegateView == null || mBar.shouldDisableNavbarGestures()) { - return false; - } - - mSourceView.getLocationOnScreen(mTempPoint); - final float sourceX = mTempPoint[0]; - final float sourceY = mTempPoint[1]; - - final int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE; - mDownPoint[0] = event.getX(); - mDownPoint[1] = event.getY(); - mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY); - break; - } - - if (!mStarted) { - return false; - } - - if (!mDisabled && !mPanelShowing && action == MotionEvent.ACTION_MOVE) { - final int historySize = event.getHistorySize(); - for (int k = 0; k < historySize + 1; k++) { - float x = k < historySize ? event.getHistoricalX(k) : event.getX(); - float y = k < historySize ? event.getHistoricalY(k) : event.getY(); - final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y); - if (distance > mTriggerThreshhold) { - mBar.invokeAssistGesture(false /* vibrate */); - mPanelShowing = true; - break; - } - } - } - - if (action == MotionEvent.ACTION_DOWN) { - mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, true); - } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false); - } - - mDelegateView.getLocationOnScreen(mTempPoint); - final float delegateX = mTempPoint[0]; - final float delegateY = mTempPoint[1]; - - float deltaX = sourceX - delegateX; - float deltaY = sourceY - delegateY; - event.offsetLocation(deltaX, deltaY); - mDelegateView.dispatchTouchEvent(event); - event.offsetLocation(-deltaX, -deltaY); - return mPanelShowing; - } - - public void abortCurrentGesture() { - if (mStarted) { - mStarted = false; - mBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, false); - } - } - - public void setSourceView(View view) { - mSourceView = view; - if (mSourceView != null) { - Resources r = mSourceView.getContext().getResources(); - mTriggerThreshhold = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance); - } - } - - /** - * Selects the initial touch region based on a list of views. This is meant to be called by - * a container widget on children over which the initial touch should be detected. Note this - * will compute a minimum bound that contains all specified views. - * - * @param views - */ - public void setInitialTouchRegion(View ... views) { - RectF bounds = new RectF(); - int p[] = new int[2]; - for (int i = 0; i < views.length; i++) { - View view = views[i]; - if (view == null) continue; - view.getLocationOnScreen(p); - if (i == 0) { - bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight()); - } else { - bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight()); - } - } - mInitialTouch.set(bounds); - } - - /** - * When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection - * @param swap - */ - public void setSwapXY(boolean swap) { - mSwapXY = swap; - } - - public void setDisabled(boolean disabled) { - mDisabled = disabled; - } -}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index d444ea8..b88e5ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -856,6 +856,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } @Override + protected View getContentView() { + return getShowingLayout(); + } + + @Override public void setActualHeight(int height, boolean notifyListeners) { super.setActualHeight(height, notifyListeners); int contentHeight = calculateContentHeightFromActualHeight(height); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java index a18fff2..d77e050 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java @@ -24,16 +24,21 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; +import com.android.systemui.R; + /** * Like {@link ExpandableView}, but setting an outline for the height and clipping. */ public abstract class ExpandableOutlineView extends ExpandableView { private final Rect mOutlineRect = new Rect(); + protected final int mRoundedRectCornerRadius; private boolean mCustomOutline; public ExpandableOutlineView(Context context, AttributeSet attrs) { super(context, attrs); + mRoundedRectCornerRadius = getResources().getDimensionPixelSize( + R.dimen.notification_material_rounded_rect_radius); setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { @@ -43,7 +48,7 @@ public abstract class ExpandableOutlineView extends ExpandableView { getWidth(), Math.max(getActualHeight(), mClipTopAmount)); } else { - outline.setRect(mOutlineRect); + outline.setRoundRect(mOutlineRect, mRoundedRectCornerRadius); } } }); @@ -66,12 +71,14 @@ public abstract class ExpandableOutlineView extends ExpandableView { setOutlineRect(rect.left, rect.top, rect.right, rect.bottom); } else { mCustomOutline = false; + setClipToOutline(false); invalidateOutline(); } } protected void setOutlineRect(float left, float top, float right, float bottom) { mCustomOutline = true; + setClipToOutline(true); mOutlineRect.set((int) left, (int) top, (int) right, (int) bottom); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index 3feec9e..03d0482 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -43,6 +43,7 @@ public abstract class ExpandableView extends FrameLayout { private ArrayList<View> mMatchParentViews = new ArrayList<View>(); private int mClipTopOptimization; private static Rect mClipRect = new Rect(); + private boolean mWillBeGone; public ExpandableView(Context context, AttributeSet attrs) { super(context, attrs); @@ -339,6 +340,12 @@ public abstract class ExpandableView extends FrameLayout { outRect.top += getTranslationY() + getClipTopAmount(); } + @Override + public void getBoundsOnScreen(Rect outRect, boolean clipToParent) { + super.getBoundsOnScreen(outRect, clipToParent); + outRect.bottom = (int) (outRect.top + getActualHeight()); + } + public int getContentHeight() { return mActualHeight - getBottomDecorHeight(); } @@ -374,6 +381,14 @@ public abstract class ExpandableView extends FrameLayout { updateClipping(); } + public boolean willBeGone() { + return mWillBeGone; + } + + public void setWillBeGone(boolean willBeGone) { + mWillBeGone = willBeGone; + } + /** * A listener notifying when {@link #getActualHeight} changes. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java index 5fa7070..9653b67 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationOverflowContainer.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.widget.TextView; import com.android.systemui.R; @@ -32,6 +33,7 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { private NotificationOverflowIconsView mIconsView; private ViewInvertHelper mViewInvertHelper; private boolean mDark; + private View mContent; public NotificationOverflowContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -43,7 +45,8 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view); mIconsView.setMoreText((TextView) findViewById(R.id.more_text)); mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow)); - mViewInvertHelper = new ViewInvertHelper(findViewById(R.id.content), + mContent = findViewById(R.id.content); + mViewInvertHelper = new ViewInvertHelper(mContent, NotificationPanelView.DOZE_ANIMATION_DURATION); } @@ -59,6 +62,11 @@ public class NotificationOverflowContainer extends ActivatableNotificationView { } } + @Override + protected View getContentView() { + return mContent; + } + public NotificationOverflowIconsView getIconsView() { return mIconsView; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java index 64d80cc..2f66c41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java @@ -32,7 +32,6 @@ public abstract class StackScrollerDecorView extends ExpandableView { protected View mContent; private boolean mIsVisible; private boolean mAnimating; - private boolean mWillBeGone; public StackScrollerDecorView(Context context, AttributeSet attrs) { super(context, attrs); @@ -134,13 +133,5 @@ public abstract class StackScrollerDecorView extends ExpandableView { mContent.animate().cancel(); } - public boolean willBeGone() { - return mWillBeGone; - } - - public void setWillBeGone(boolean willBeGone) { - mWillBeGone = willBeGone; - } - protected abstract View findContentView(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 636c511..f40f501 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -47,7 +47,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import com.android.systemui.R; -import com.android.systemui.statusbar.DelegateViewHelper; import com.android.systemui.statusbar.policy.DeadZone; import com.android.systemui.statusbar.policy.KeyButtonView; @@ -79,7 +78,6 @@ public class NavigationBarView extends LinearLayout { private Drawable mRecentLandIcon; private NavigationBarViewTaskSwitchHelper mTaskSwitchHelper; - private DelegateViewHelper mDelegateHelper; private DeadZone mDeadZone; private final NavigationBarTransitions mBarTransitions; @@ -92,7 +90,6 @@ public class NavigationBarView extends LinearLayout { private OnVerticalChangedListener mOnVerticalChangedListener; private boolean mIsLayoutRtl; - private boolean mDelegateIntercepted; private class NavTransitionListener implements TransitionListener { private boolean mBackTransitioning; @@ -180,7 +177,6 @@ public class NavigationBarView extends LinearLayout { mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size); mVertical = false; mShowMenu = false; - mDelegateHelper = new DelegateViewHelper(this); mTaskSwitchHelper = new NavigationBarViewTaskSwitchHelper(context); getIcons(res); @@ -192,13 +188,8 @@ public class NavigationBarView extends LinearLayout { return mBarTransitions; } - public void setDelegateView(View view) { - mDelegateHelper.setDelegateView(view); - } - public void setBar(PhoneStatusBar phoneStatusBar) { mTaskSwitchHelper.setBar(phoneStatusBar); - mDelegateHelper.setBar(phoneStatusBar); } public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) { @@ -208,44 +199,21 @@ public class NavigationBarView extends LinearLayout { @Override public boolean onTouchEvent(MotionEvent event) { - initDownStates(event); - if (!mDelegateIntercepted && mTaskSwitchHelper.onTouchEvent(event)) { + if (mTaskSwitchHelper.onTouchEvent(event)) { return true; } if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) { mDeadZone.poke(event); } - if (mDelegateHelper != null && mDelegateIntercepted) { - boolean ret = mDelegateHelper.onInterceptTouchEvent(event); - if (ret) return true; - } return super.onTouchEvent(event); } - private void initDownStates(MotionEvent ev) { - if (ev.getAction() == MotionEvent.ACTION_DOWN) { - mDelegateIntercepted = false; - } - } - @Override public boolean onInterceptTouchEvent(MotionEvent event) { - initDownStates(event); - boolean intercept = mTaskSwitchHelper.onInterceptTouchEvent(event); - if (!intercept) { - mDelegateIntercepted = mDelegateHelper.onInterceptTouchEvent(event); - intercept = mDelegateIntercepted; - } else { - MotionEvent cancelEvent = MotionEvent.obtain(event); - cancelEvent.setAction(MotionEvent.ACTION_CANCEL); - mDelegateHelper.onInterceptTouchEvent(cancelEvent); - cancelEvent.recycle(); - } - return intercept; + return mTaskSwitchHelper.onInterceptTouchEvent(event); } public void abortCurrentGesture() { - mDelegateHelper.abortCurrentGesture(); getHomeButton().abortCurrentGesture(); } @@ -461,10 +429,6 @@ public class NavigationBarView extends LinearLayout { Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation()); } - // swap to x coordinate if orientation is not in vertical - if (mDelegateHelper != null) { - mDelegateHelper.setSwapXY(mVertical); - } updateTaskSwitchHelper(); setNavigationIconHints(mNavigationIconHints, true); @@ -476,12 +440,6 @@ public class NavigationBarView extends LinearLayout { } @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); - mDelegateHelper.setInitialTouchRegion(getHomeButton(), getBackButton(), getRecentsButton()); - } - - @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (DEBUG) Log.d(TAG, String.format( "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh)); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 9e1af82..a750572 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -487,6 +487,7 @@ public class NotificationPanelView extends PanelView implements mStatusBar.dismissPopups(); mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */, true /* cancelAnimators */); + mNotificationStackScroller.resetScrollPosition(); } public void closeQs() { @@ -1716,12 +1717,16 @@ public class NotificationPanelView extends PanelView implements float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2); mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * mKeyguardStatusBarAnimateAlpha); + mKeyguardStatusBar.setVisibility(mKeyguardStatusBar.getAlpha() != 0f ? VISIBLE : INVISIBLE); setQsTranslation(mQsExpansionHeight); } private void updateKeyguardBottomAreaAlpha() { - mKeyguardBottomArea.setAlpha( - Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction())); + float alpha = Math.min(getKeyguardContentsAlpha(), 1 - getQsExpansionFraction()); + mKeyguardBottomArea.setAlpha(alpha); + mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f + ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : IMPORTANT_FOR_ACCESSIBILITY_AUTO); } private float getNotificationsTopY() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 54bd3e9..552a0b2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -81,10 +81,13 @@ public class PanelBar extends FrameLayout { } public void setBouncerShowing(boolean showing) { + int important = showing ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : IMPORTANT_FOR_ACCESSIBILITY_AUTO; + + setImportantForAccessibility(important); + if (mPanelHolder != null) { - mPanelHolder.setImportantForAccessibility( - showing ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS - : IMPORTANT_FOR_ACCESSIBILITY_AUTO); + mPanelHolder.setImportantForAccessibility(important); } } 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 a5b18f9..33e8e59 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -707,7 +707,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false); mKeyguardIconOverflowContainer.setOnActivatedListener(this); mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener); - mStackScroller.addView(mKeyguardIconOverflowContainer); + mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer); SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate( R.layout.status_bar_notification_speed_bump, mStackScroller, false); @@ -1861,6 +1861,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void setQsExpanded(boolean expanded) { mStatusBarWindowManager.setQsExpanded(expanded); + mKeyguardStatusView.setImportantForAccessibility(expanded + ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS + : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); } public boolean isGoingToNotificationShade() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java index 1460e5f..5cf6156 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java @@ -30,7 +30,7 @@ import android.view.ViewStub; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; -import com.android.keyguard.AppearAnimationUtils; +import com.android.settingslib.animation.AppearAnimationUtils; import com.android.systemui.R; import com.android.systemui.qs.tiles.UserDetailItemView; import com.android.systemui.statusbar.phone.KeyguardStatusBarView; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index d8f6bcd..1bf4547 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.NotificationOverflowContainer; import com.android.systemui.statusbar.SpeedBumpView; import com.android.systemui.statusbar.StackScrollerDecorView; import com.android.systemui.statusbar.StatusBarState; @@ -226,6 +227,7 @@ public class NotificationStackScrollLayout extends ViewGroup private boolean mTrackingHeadsUp; private ScrimController mScrimController; private boolean mForceNoOverlappingRendering; + private NotificationOverflowContainer mOverflowContainer; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -1368,17 +1370,11 @@ public class NotificationStackScrollLayout extends ViewGroup int childCount = getChildCount(); int count = 0; for (int i = 0; i < childCount; i++) { - View child = getChildAt(i); - if (child.getVisibility() != View.GONE) { + ExpandableView child = (ExpandableView) getChildAt(i); + if (child.getVisibility() != View.GONE && !child.willBeGone()) { count++; } } - if (mDismissView.willBeGone()) { - count--; - } - if (mEmptyShadeView.willBeGone()) { - count--; - } return count; } @@ -2234,6 +2230,11 @@ public class NotificationStackScrollLayout extends ViewGroup } } + public void resetScrollPosition() { + mScroller.abortAnimation(); + mOwnScrollY = 0; + } + private void setIsExpanded(boolean isExpanded) { boolean changed = isExpanded != mIsExpanded; mIsExpanded = isExpanded; @@ -2291,6 +2292,10 @@ public class NotificationStackScrollLayout extends ViewGroup public void onChildAnimationFinished() { requestChildrenUpdate(); + runAnimationFinishedRunnables(); + } + + private void runAnimationFinishedRunnables() { for (Runnable runnable : mAnimationFinishedRunnables) { runnable.run(); } @@ -2348,6 +2353,7 @@ public class NotificationStackScrollLayout extends ViewGroup if (mListener != null) { mListener.onChildLocationsChanged(this); } + runAnimationFinishedRunnables(); } public void setSpeedBumpView(SpeedBumpView speedBumpView) { @@ -2470,7 +2476,7 @@ public class NotificationStackScrollLayout extends ViewGroup mEmptyShadeView.setVisibility(newVisibility); mEmptyShadeView.setWillBeGone(false); updateContentHeight(); - notifyHeightChangeListener(mDismissView); + notifyHeightChangeListener(mEmptyShadeView); } else { Runnable onFinishedRunnable = new Runnable() { @Override @@ -2478,7 +2484,7 @@ public class NotificationStackScrollLayout extends ViewGroup mEmptyShadeView.setVisibility(GONE); mEmptyShadeView.setWillBeGone(false); updateContentHeight(); - notifyHeightChangeListener(mDismissView); + notifyHeightChangeListener(mEmptyShadeView); } }; if (mAnimationsEnabled) { @@ -2492,6 +2498,45 @@ public class NotificationStackScrollLayout extends ViewGroup } } + public void setOverflowContainer(NotificationOverflowContainer overFlowContainer) { + mOverflowContainer = overFlowContainer; + addView(mOverflowContainer); + } + + public void updateOverflowContainerVisibility(boolean visible) { + int oldVisibility = mOverflowContainer.willBeGone() ? GONE + : mOverflowContainer.getVisibility(); + final int newVisibility = visible ? VISIBLE : GONE; + if (oldVisibility != newVisibility) { + Runnable onFinishedRunnable = new Runnable() { + @Override + public void run() { + mOverflowContainer.setVisibility(newVisibility); + mOverflowContainer.setWillBeGone(false); + updateContentHeight(); + notifyHeightChangeListener(mOverflowContainer); + } + }; + if (!mAnimationsEnabled || !mIsExpanded) { + mOverflowContainer.cancelAppearDrawing(); + onFinishedRunnable.run(); + } else if (newVisibility != GONE) { + mOverflowContainer.performAddAnimation(0, + StackStateAnimator.ANIMATION_DURATION_STANDARD); + mOverflowContainer.setVisibility(newVisibility); + mOverflowContainer.setWillBeGone(false); + updateContentHeight(); + notifyHeightChangeListener(mOverflowContainer); + } else { + mOverflowContainer.performRemoveAnimation( + StackStateAnimator.ANIMATION_DURATION_STANDARD, + 0.0f, + onFinishedRunnable); + mOverflowContainer.setWillBeGone(true); + } + } + } + public void updateDismissView(boolean visible) { int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility(); int newVisibility = visible ? VISIBLE : GONE; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java index feae590..a70ad43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java @@ -210,7 +210,10 @@ public class StackScrollState { int oldVisibility = view.getVisibility(); int newVisibility = becomesInvisible ? View.INVISIBLE : View.VISIBLE; if (newVisibility != oldVisibility) { - view.setVisibility(newVisibility); + if (!(view instanceof ExpandableView) || !((ExpandableView) view).willBeGone()) { + // We don't want views to change visibility when they are animating to GONE + view.setVisibility(newVisibility); + } } // apply yTranslation diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java index c31244c..c995c8e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java @@ -285,6 +285,10 @@ public class StackStateAnimator { boolean scaleChanging = child.getScaleX() != viewState.scale; float childAlpha = child.getVisibility() == View.INVISIBLE ? 0.0f : child.getAlpha(); boolean alphaChanging = viewState.alpha != childAlpha; + if (child instanceof ExpandableView) { + // We don't want views to change visibility when they are animating to GONE + alphaChanging &= !((ExpandableView) child).willBeGone(); + } // start translationY animation if (yTranslationChanging) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index ced1a3c..a0eb61f 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -153,7 +153,7 @@ public class ZenModePanel extends LinearLayout { mZenButtons = (SegmentedButtons) findViewById(R.id.zen_buttons); mZenButtons.addButton(R.string.interruption_level_none_twoline, - R.string.interruption_level_none, + R.string.interruption_level_none_with_warning, Global.ZEN_MODE_NO_INTERRUPTIONS); mZenButtons.addButton(R.string.interruption_level_alarms_twoline, R.string.interruption_level_alarms, diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 7440b8c..b2ab797 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -346,6 +346,8 @@ public final class DisplayManagerService extends SystemService { synchronized (mTempDisplayStateWorkQueue) { try { // Update the display state within the lock. + // Note that we do not need to schedule traversals here although it + // may happen as a side-effect of displays changing state. synchronized (mSyncRoot) { if (mGlobalDisplayState == state && mGlobalDisplayBrightness == brightness) { @@ -357,8 +359,7 @@ public final class DisplayManagerService extends SystemService { + ", brightness=" + brightness + ")"); mGlobalDisplayState = state; mGlobalDisplayBrightness = brightness; - updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); - scheduleTraversalLocked(false); + applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); } // Setting the display power state can take hundreds of milliseconds @@ -715,6 +716,7 @@ public final class DisplayManagerService extends SystemService { handleDisplayDeviceRemovedLocked(device); } } + private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); if (!mDisplayDevices.remove(device)) { @@ -729,7 +731,7 @@ public final class DisplayManagerService extends SystemService { scheduleTraversalLocked(false); } - private void updateGlobalDisplayStateLocked(List<Runnable> workQueue) { + private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { DisplayDevice device = mDisplayDevices.get(i); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e2cc3f7..6c9fd3f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -92,6 +92,7 @@ import android.content.ServiceConnection; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.FeatureInfo; +import android.content.pm.IOnPermissionsChangeListener; import android.content.pm.IPackageDataObserver; import android.content.pm.IPackageDeleteObserver; import android.content.pm.IPackageDeleteObserver2; @@ -144,6 +145,7 @@ import android.os.Message; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Process; +import android.os.RemoteCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.SELinux; @@ -523,6 +525,8 @@ public class PackageManagerService extends IPackageManager.Stub { private AtomicInteger mNextMoveId = new AtomicInteger(); private final MoveCallbacks mMoveCallbacks; + private final OnPermissionChangeListeners mOnPermissionChangeListeners; + // Cache of users who need badging. SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); @@ -1731,6 +1735,9 @@ public class PackageManagerService extends IPackageManager.Stub { mPackageDexOptimizer = new PackageDexOptimizer(this); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); + mOnPermissionChangeListeners = new OnPermissionChangeListeners( + FgThread.get().getLooper()); + getDefaultDisplayMetrics(context, mMetrics); SystemConfig systemConfig = SystemConfig.getInstance(); @@ -3195,10 +3202,11 @@ public class PackageManagerService extends IPackageManager.Stub { case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { gidsChanged = true; - } - break; + } break; } + mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); + // Not critical if that is lost - app has to request again. mSettings.writeRuntimePermissionsForUserLPr(userId, false); } @@ -3255,6 +3263,8 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid); + // Critical, after this call app should never have the permission. mSettings.writeRuntimePermissionsForUserLPr(userId, true); } @@ -3397,6 +3407,24 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override + public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { + mContext.enforceCallingOrSelfPermission( + Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS, + "addOnPermissionsChangeListener"); + + synchronized (mPackages) { + mOnPermissionChangeListeners.addListenerLocked(listener); + } + } + + @Override + public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { + synchronized (mPackages) { + mOnPermissionChangeListeners.removeListenerLocked(listener); + } + } + + @Override public boolean isProtectedBroadcast(String actionName) { synchronized (mPackages) { return mProtectedBroadcasts.contains(actionName); @@ -6368,6 +6396,16 @@ public class PackageManagerService extends IPackageManager.Stub { if ((scanFlags & SCAN_NEW_INSTALL) == 0) { derivePackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); + + // Some system apps still use directory structure for native libraries + // in which case we might end up not detecting abi solely based on apk + // structure. Try to detect abi based on directory structure. + if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() && + pkg.applicationInfo.primaryCpuAbi == null) { + setBundledAppAbisAndRoots(pkg, pkgSetting); + setNativeLibraryPaths(pkg); + } + } else { if ((scanFlags & SCAN_MOVE) != 0) { // We haven't run dex-opt for this move (since we've moved the compiled output too) @@ -7273,6 +7311,33 @@ public class PackageManagerService extends IPackageManager.Stub { } /** + * Calculate the abis and roots for a bundled app. These can uniquely + * be determined from the contents of the system partition, i.e whether + * it contains 64 or 32 bit shared libraries etc. We do not validate any + * of this information, and instead assume that the system was built + * sensibly. + */ + private void setBundledAppAbisAndRoots(PackageParser.Package pkg, + PackageSetting pkgSetting) { + final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath()); + + // If "/system/lib64/apkname" exists, assume that is the per-package + // native library directory to use; otherwise use "/system/lib/apkname". + final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir); + setBundledAppAbi(pkg, apkRoot, apkName); + // pkgSetting might be null during rescan following uninstall of updates + // to a bundled app, so accommodate that possibility. The settings in + // that case will be established later from the parsed package. + // + // If the settings aren't null, sync them up with what we've just derived. + // note that apkRoot isn't stored in the package settings. + if (pkgSetting != null) { + pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; + pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; + } + } + + /** * Deduces the ABI of a bundled app and sets the relevant fields on the * parsed pkg object. * @@ -15260,4 +15325,57 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + private final class OnPermissionChangeListeners extends Handler { + private static final int MSG_ON_PERMISSIONS_CHANGED = 1; + + private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners = + new RemoteCallbackList<>(); + + public OnPermissionChangeListeners(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_ON_PERMISSIONS_CHANGED: { + final int uid = msg.arg1; + handleOnPermissionsChanged(uid); + } break; + } + } + + public void addListenerLocked(IOnPermissionsChangeListener listener) { + mPermissionListeners.register(listener); + + } + + public void removeListenerLocked(IOnPermissionsChangeListener listener) { + mPermissionListeners.unregister(listener); + } + + public void onPermissionsChanged(int uid) { + if (mPermissionListeners.getRegisteredCallbackCount() > 0) { + obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget(); + } + } + + private void handleOnPermissionsChanged(int uid) { + final int count = mPermissionListeners.beginBroadcast(); + try { + for (int i = 0; i < count; i++) { + IOnPermissionsChangeListener callback = mPermissionListeners + .getBroadcastItem(i); + try { + callback.onPermissionsChanged(uid); + } catch (RemoteException e) { + Log.e(TAG, "Permission listener is dead", e); + } + } + } finally { + mPermissionListeners.finishBroadcast(); + } + } + } } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 6e52358..25ca167 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -514,6 +514,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mDreamingLockscreen; boolean mDreamingSleepTokenNeeded; SleepToken mDreamingSleepToken; + SleepToken mScreenOffSleepToken; boolean mKeyguardSecure; boolean mKeyguardSecureIncludingHidden; volatile boolean mKeyguardOccluded; @@ -5385,6 +5386,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void screenTurnedOff() { if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off..."); + updateScreenOffSleepToken(true); synchronized (mLock) { mScreenOnEarly = false; mScreenOnFully = false; @@ -5399,6 +5401,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void screenTurningOn(final ScreenOnListener screenOnListener) { if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on..."); + updateScreenOffSleepToken(false); synchronized (mLock) { mScreenOnEarly = true; mScreenOnFully = false; @@ -6021,6 +6024,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else { if (mDreamingSleepToken != null) { mDreamingSleepToken.release(); + mDreamingSleepToken = null; + } + } + } + + private void updateScreenOffSleepToken(boolean acquire) { + if (acquire) { + if (mScreenOffSleepToken == null) { + mScreenOffSleepToken = mActivityManagerInternal.acquireSleepToken("ScreenOff"); + } + } else { + if (mScreenOffSleepToken != null) { + mScreenOffSleepToken.release(); + mScreenOffSleepToken = null; } } } diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index feb0285..ab1206b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3129,7 +3129,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public void uninstallCaCert(ComponentName admin, String alias) { + public void uninstallCaCerts(ComponentName admin, String[] aliases) { enforceCanManageCaCerts(admin); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); @@ -3137,7 +3137,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle); try { - keyChainConnection.getService().deleteCaCertificate(alias); + for (int i = 0 ; i < aliases.length; i++) { + keyChainConnection.getService().deleteCaCertificate(aliases[i]); + } } catch (RemoteException e) { Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java index 6684be4..bb0a36f 100644 --- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java @@ -48,6 +48,7 @@ import android.net.Network; import android.net.NetworkAgent; import android.net.NetworkCapabilities; import android.net.NetworkConfig; +import android.net.NetworkFactory; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; @@ -55,6 +56,7 @@ import android.net.NetworkRequest; import android.net.RouteInfo; import android.os.ConditionVariable; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.INetworkManagementService; import android.test.AndroidTestCase; @@ -68,6 +70,7 @@ import org.mockito.ArgumentCaptor; import java.net.InetAddress; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; /** * Tests for {@link ConnectivityService}. @@ -224,6 +227,31 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } + private static class MockNetworkFactory extends NetworkFactory { + final AtomicBoolean mNetworkStarted = new AtomicBoolean(false); + + public MockNetworkFactory(Looper looper, Context context, String logTag, + NetworkCapabilities filter) { + super(looper, context, logTag, filter); + } + + public int getMyRequestCount() { + return getRequestCount(); + } + + protected void startNetwork() { + mNetworkStarted.set(true); + } + + protected void stopNetwork() { + mNetworkStarted.set(false); + } + + public boolean getMyStartRequested() { + return mNetworkStarted.get(); + } + } + private class WrappedConnectivityService extends ConnectivityService { public WrappedConnectivityService(Context context, INetworkManagementService netManager, INetworkStatsService statsService, INetworkPolicyManager policyManager) { @@ -447,6 +475,71 @@ public class ConnectivityServiceTest extends AndroidTestCase { verifyNoNetwork(); } + @LargeTest + public void testNetworkFactoryRequests() throws Exception { + NetworkCapabilities filter = new NetworkCapabilities(); + filter.addCapability(NET_CAPABILITY_INTERNET); + final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests"); + handlerThread.start(); + MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(), + mServiceContext, "testFactory", filter); + testFactory.setScoreFilter(40); + testFactory.register(); + try { + Thread.sleep(500); + } catch (Exception e) {} + assertEquals(1, testFactory.getMyRequestCount()); + assertEquals(true, testFactory.getMyStartRequested()); + + // now bring in a higher scored network + MockNetworkAgent testAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + ConditionVariable cv = waitForConnectivityBroadcasts(1); + testAgent.connect(true); + cv.block(); + // part of the bringup makes another network request and then releases it + // wait for the release + try { Thread.sleep(500); } catch (Exception e) {} + assertEquals(1, testFactory.getMyRequestCount()); + assertEquals(false, testFactory.getMyStartRequested()); + + // bring in a bunch of requests.. + ConnectivityManager.NetworkCallback[] networkCallbacks = + new ConnectivityManager.NetworkCallback[10]; + for (int i = 0; i< networkCallbacks.length; i++) { + networkCallbacks[i] = new ConnectivityManager.NetworkCallback(); + NetworkRequest.Builder builder = new NetworkRequest.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + mCm.requestNetwork(builder.build(), networkCallbacks[i]); + } + + try { + Thread.sleep(1000); + } catch (Exception e) {} + assertEquals(11, testFactory.getMyRequestCount()); + assertEquals(false, testFactory.getMyStartRequested()); + + // remove the requests + for (int i = 0; i < networkCallbacks.length; i++) { + mCm.unregisterNetworkCallback(networkCallbacks[i]); + } + try { + Thread.sleep(500); + } catch (Exception e) {} + assertEquals(1, testFactory.getMyRequestCount()); + assertEquals(false, testFactory.getMyStartRequested()); + + // drop the higher scored network + cv = waitForConnectivityBroadcasts(1); + testAgent.disconnect(); + cv.block(); + assertEquals(1, testFactory.getMyRequestCount()); + assertEquals(true, testFactory.getMyStartRequested()); + + testFactory.unregister(); + handlerThread.quit(); + } + + // @Override // public void tearDown() throws Exception { // super.tearDown(); diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index d6a7dd1..588f8c6 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -91,6 +91,7 @@ public class UsbDeviceManager { private static final int MSG_SYSTEM_READY = 3; private static final int MSG_BOOT_COMPLETED = 4; private static final int MSG_USER_SWITCHED = 5; + private static final int MSG_SET_USB_DATA_UNLOCKED = 6; private static final int AUDIO_MODE_SOURCE = 1; @@ -314,6 +315,7 @@ public class UsbDeviceManager { // current USB state private boolean mConnected; private boolean mConfigured; + private boolean mUsbDataUnlocked; private String mCurrentFunctions; private UsbAccessory mCurrentAccessory; private int mUsbNotificationId; @@ -350,7 +352,7 @@ public class UsbDeviceManager { SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY, "adb"), UsbManager.USB_FUNCTION_ADB); - mCurrentFunctions = mAdbEnabled ? "adb" : "none"; + mCurrentFunctions = mAdbEnabled ? "adb" : UsbManager.USB_FUNCTION_MTP; String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); @@ -459,6 +461,15 @@ public class UsbDeviceManager { } } + /** + * Stop and start the USB driver. This is needed to close all outstanding + * USB connections. + */ + private void restartCurrentFunction() { + setUsbConfig("none"); + setUsbConfig(mCurrentFunctions); + } + private void setEnabledFunctions(String functions) { if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions); @@ -531,6 +542,7 @@ public class UsbDeviceManager { intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(UsbManager.USB_CONNECTED, mConnected); intent.putExtra(UsbManager.USB_CONFIGURED, mConfigured); + intent.putExtra(UsbManager.USB_DATA_UNLOCKED, mUsbDataUnlocked); if (mCurrentFunctions != null) { String[] functions = mCurrentFunctions.split(","); @@ -599,6 +611,10 @@ public class UsbDeviceManager { case MSG_UPDATE_STATE: mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); + if (!mConnected) { + // When a disconnect occurs, relock access to sensitive user data + mUsbDataUnlocked = false; + } updateUsbNotification(); updateAdbNotification(); if (containsFunction(mCurrentFunctions, @@ -621,6 +637,12 @@ public class UsbDeviceManager { String functions = (String)msg.obj; setEnabledFunctions(functions); break; + case MSG_SET_USB_DATA_UNLOCKED: + mUsbDataUnlocked = (msg.arg1 == 1); + updateUsbNotification(); + updateUsbState(); + restartCurrentFunction(); + break; case MSG_SYSTEM_READY: setUsbConfig(mCurrentFunctions); updatePersistentProperty(); @@ -676,7 +698,9 @@ public class UsbDeviceManager { int id = 0; Resources r = mContext.getResources(); if (mConnected) { - if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { + if (!mUsbDataUnlocked) { + id = com.android.internal.R.string.usb_charging_notification_title; + } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP)) { id = com.android.internal.R.string.usb_mtp_notification_title; } else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP)) { id = com.android.internal.R.string.usb_ptp_notification_title; @@ -771,7 +795,7 @@ public class UsbDeviceManager { } private String getDefaultFunctions() { - return "none"; + return UsbManager.USB_FUNCTION_MTP; } public void dump(FileDescriptor fd, PrintWriter pw) { @@ -817,6 +841,16 @@ public class UsbDeviceManager { mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions); } + public void setUsbDataUnlocked(boolean unlocked) { + if (DEBUG) Slog.d(TAG, "setUsbDataUnlocked(" + unlocked + ")"); + mHandler.sendMessage(MSG_SET_USB_DATA_UNLOCKED, unlocked); + } + + public boolean isUsbDataUnlocked() { + if (DEBUG) Slog.d(TAG, "isUsbDataUnlocked() -> " + mHandler.mUsbDataUnlocked); + return mHandler.mUsbDataUnlocked; + } + private void readOemUsbOverrideConfig() { String[] configList = mContext.getResources().getStringArray( com.android.internal.R.array.config_oemUsbModeOverride); diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java index 51281a2..7a3426c 100644 --- a/services/usb/java/com/android/server/usb/UsbService.java +++ b/services/usb/java/com/android/server/usb/UsbService.java @@ -271,6 +271,18 @@ public class UsbService extends IUsbManager.Stub { } @Override + public void setUsbDataUnlocked(boolean unlocked) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + mDeviceManager.setUsbDataUnlocked(unlocked); + } + + @Override + public boolean isUsbDataUnlocked() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); + return mDeviceManager.isUsbDataUnlocked(); + } + + @Override public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 0042414..9a63aa3 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -27,6 +27,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.view.Surface; @@ -442,8 +443,7 @@ public abstract class Connection extends Conferenceable { private static final int MSG_SET_PAUSE_IMAGE = 11; private static final int MSG_REMOVE_VIDEO_CALLBACK = 12; - private final VideoProvider.VideoProviderHandler - mMessageHandler = new VideoProvider.VideoProviderHandler(); + private VideoProvider.VideoProviderHandler mMessageHandler; private final VideoProvider.VideoProviderBinder mBinder; /** @@ -455,6 +455,14 @@ public abstract class Connection extends Conferenceable { * Default handler used to consolidate binder method calls onto a single thread. */ private final class VideoProviderHandler extends Handler { + public VideoProviderHandler() { + super(); + } + + public VideoProviderHandler(Looper looper) { + super(looper); + } + @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -586,6 +594,18 @@ public abstract class Connection extends Conferenceable { public VideoProvider() { mBinder = new VideoProvider.VideoProviderBinder(); + mMessageHandler = new VideoProvider.VideoProviderHandler(); + } + + /** + * Creates an instance of the {@link VideoProvider}, specifying the looper to use. + * + * @param looper The looper. + * @hide + */ + public VideoProvider(Looper looper) { + mBinder = new VideoProvider.VideoProviderBinder(); + mMessageHandler = new VideoProvider.VideoProviderHandler(looper); } /** diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b74b52d..6de438c 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -124,7 +124,7 @@ public class CarrierConfigManager { KEY_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG_BOOL = "allow_emergency_numbers_in_call_log_bool"; /** If true, removes the Voice Privacy option from Call Settings */ - public static final String KEY_VOICE_PRIVACY_DISABLE_BOOL = "voice_privacy_disable_bool"; + public static final String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool"; /** Control whether users can reach the carrier portions of Cellular Network Settings. */ public static final String @@ -302,7 +302,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_USE_HFA_FOR_PROVISIONING_BOOL, false); sDefaults.putBoolean(KEY_USE_OTASP_FOR_PROVISIONING_BOOL, false); sDefaults.putBoolean(KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL, false); - sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_BOOL, false); + sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_UI_BOOL, false); sDefaults.putBoolean(KEY_WORLD_PHONE_BOOL, false); sDefaults.putInt(KEY_VOLTE_REPLACEMENT_RAT_INT, 0); sDefaults.putString(KEY_VVM_DESTINATION_NUMBER_STRING, ""); diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index 7b58755..f02d109 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -469,7 +469,12 @@ public class SignalStrength implements Parcelable { } /** - * Get signal level as an int from 0..4 + * Retrieve an abstract level value for the overall signal strength. + * + * @return a single integer from 0 to 4 representing the general signal quality. + * This may take into account many different radio technology inputs. + * 0 represents very poor signal strength + * while 4 represents a very strong signal strength. */ public int getLevel() { int level; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 393888d..1cc275d 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3501,13 +3501,13 @@ public class TelephonyManager { /** * Values used to return status for hasCarrierPrivileges call. */ - /** @hide */ + /** @hide */ @SystemApi public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; - /** @hide */ + /** @hide */ @SystemApi public static final int CARRIER_PRIVILEGE_STATUS_NO_ACCESS = 0; - /** @hide */ + /** @hide */ @SystemApi public static final int CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED = -1; - /** @hide */ + /** @hide */ @SystemApi public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; /** diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 3b7aa9f..ac92dc0 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -224,6 +224,18 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public void addOnPermissionsChangeListener(OnPermissionsChangedListener listener) { + throw new UnsupportedOperationException(); + } + + /** @hide */ + @Override + public void removeOnPermissionsChangeListener(OnPermissionsChangedListener listener) { + throw new UnsupportedOperationException(); + } + @Override public int checkSignatures(String pkg1, String pkg2) { throw new UnsupportedOperationException(); |