diff options
57 files changed, 1825 insertions, 707 deletions
diff --git a/api/current.txt b/api/current.txt index e146dd159fa1..95d8f1ea8a1c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -23,7 +23,6 @@ package android { field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE"; field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; - field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN"; field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE"; field public static final java.lang.String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE"; @@ -32,6 +31,7 @@ package android { field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS"; + field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE"; field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE"; field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT"; field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION"; @@ -4781,6 +4781,8 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public java.lang.String getGroup(); + method public android.graphics.drawable.Icon getLargeIcon(); + method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); @@ -4925,6 +4927,7 @@ package android.app { ctor public Notification.BigPictureStyle(); ctor public Notification.BigPictureStyle(android.app.Notification.Builder); method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap); + method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap); method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence); method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence); @@ -4963,6 +4966,7 @@ package android.app { method public android.app.Notification.Builder setGroup(java.lang.String); method public android.app.Notification.Builder setGroupSummary(boolean); method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap); + method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); method public android.app.Notification.Builder setNumber(int); @@ -4974,6 +4978,7 @@ package android.app { method public android.app.Notification.Builder setShowWhen(boolean); method public android.app.Notification.Builder setSmallIcon(int); method public android.app.Notification.Builder setSmallIcon(int, int); + method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setSortKey(java.lang.String); method public android.app.Notification.Builder setSound(android.net.Uri); method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int); @@ -14694,6 +14699,7 @@ package android.media { public final class AudioDeviceInfo { method public int[] getChannelCounts(); + method public int[] getChannelIndexMasks(); method public int[] getChannelMasks(); method public int[] getFormats(); method public int getId(); @@ -29940,23 +29946,6 @@ package android.system { package android.telecom { - public final class AudioState implements android.os.Parcelable { - ctor public AudioState(boolean, int, int); - ctor public AudioState(android.telecom.AudioState); - method public static java.lang.String audioRouteToString(int); - method public int describeContents(); - method public int getRoute(); - method public int getSupportedRouteMask(); - method public boolean isMuted(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.telecom.AudioState> CREATOR; - field public static final int ROUTE_BLUETOOTH = 2; // 0x2 - field public static final int ROUTE_EARPIECE = 1; // 0x1 - field public static final int ROUTE_SPEAKER = 8; // 0x8 - field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4 - field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5 - } - public final class Call { method public void answer(int); method public void conference(android.telecom.Call); @@ -30050,11 +30039,27 @@ package android.telecom { field public static final int PROPERTY_WIFI = 8; // 0x8 } + public final class CallAudioState implements android.os.Parcelable { + ctor public CallAudioState(boolean, int, int); + method public static java.lang.String audioRouteToString(int); + method public int describeContents(); + method public int getRoute(); + method public int getSupportedRouteMask(); + method public boolean isMuted(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR; + field public static final int ROUTE_BLUETOOTH = 2; // 0x2 + field public static final int ROUTE_EARPIECE = 1; // 0x1 + field public static final int ROUTE_SPEAKER = 8; // 0x8 + field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4 + field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5 + } + public abstract class Conference implements android.telecom.Conferenceable { ctor public Conference(android.telecom.PhoneAccountHandle); method public final boolean addConnection(android.telecom.Connection); method public final void destroy(); - method public final android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.util.List<android.telecom.Connection> getConferenceableConnections(); method public final int getConnectionCapabilities(); method public final long getConnectionTime(); @@ -30065,7 +30070,7 @@ package android.telecom { method public final android.telecom.StatusHints getStatusHints(); method public android.telecom.Connection.VideoProvider getVideoProvider(); method public int getVideoState(); - method public void onAudioStateChanged(android.telecom.AudioState); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onConnectionAdded(android.telecom.Connection); method public void onDisconnect(); method public void onHold(); @@ -30101,7 +30106,7 @@ package android.telecom { method public final android.net.Uri getAddress(); method public final int getAddressPresentation(); method public final boolean getAudioModeIsVoip(); - method public final android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.lang.String getCallerDisplayName(); method public final int getCallerDisplayNamePresentation(); method public final android.telecom.Conference getConference(); @@ -30115,7 +30120,7 @@ package android.telecom { method public void onAbort(); method public void onAnswer(int); method public void onAnswer(); - method public void onAudioStateChanged(android.telecom.AudioState); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onDisconnect(); method public void onHold(); method public void onPlayDtmfTone(char); @@ -30273,12 +30278,12 @@ package android.telecom { public abstract class InCallService extends android.app.Service { ctor public InCallService(); method public final boolean canAddCall(); - method public final android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.util.List<android.telecom.Call> getCalls(); - method public void onAudioStateChanged(android.telecom.AudioState); method public android.os.IBinder onBind(android.content.Intent); method public void onBringToForeground(boolean); method public void onCallAdded(android.telecom.Call); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onCallRemoved(android.telecom.Call); method public void onCanAddCallChanged(boolean); method public final void setAudioRoute(int); @@ -30316,16 +30321,12 @@ package android.telecom { public final class PhoneAccount implements android.os.Parcelable { method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence); - method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context); method public int describeContents(); method public android.telecom.PhoneAccountHandle getAccountHandle(); method public android.net.Uri getAddress(); method public int getCapabilities(); method public int getHighlightColor(); - method public android.graphics.Bitmap getIconBitmap(); - method public java.lang.String getIconPackageName(); - method public int getIconResId(); - method public int getIconTint(); + method public android.graphics.drawable.Icon getIcon(); method public java.lang.CharSequence getLabel(); method public java.lang.CharSequence getShortDescription(); method public android.net.Uri getSubscriptionAddress(); @@ -30341,7 +30342,6 @@ package android.telecom { field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8 field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR; field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0 - field public static final int NO_ICON_TINT = 0; // 0x0 field public static final int NO_RESOURCE_ID = -1; // 0xffffffff field public static final java.lang.String SCHEME_SIP = "sip"; field public static final java.lang.String SCHEME_TEL = "tel"; @@ -30356,11 +30356,7 @@ package android.telecom { method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri); method public android.telecom.PhoneAccount.Builder setCapabilities(int); method public android.telecom.PhoneAccount.Builder setHighlightColor(int); - method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int); - method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int); - method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int); - method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int); - method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap); + method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon); method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence); method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri); method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>); @@ -30390,7 +30386,7 @@ package android.telecom { method public final void registerCallback(android.telecom.RemoteConference.Callback); method public final void registerCallback(android.telecom.RemoteConference.Callback, android.os.Handler); method public void separate(android.telecom.RemoteConnection); - method public void setAudioState(android.telecom.AudioState); + method public void setCallAudioState(android.telecom.CallAudioState); method public void stopDtmfTone(); method public void swap(); method public void unhold(); @@ -30430,7 +30426,7 @@ package android.telecom { method public void registerCallback(android.telecom.RemoteConnection.Callback); method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler); method public void reject(); - method public void setAudioState(android.telecom.AudioState); + method public void setCallAudioState(android.telecom.CallAudioState); method public void stopDtmfTone(); method public void unhold(); method public void unregisterCallback(android.telecom.RemoteConnection.Callback); @@ -38812,8 +38808,7 @@ package android.webkit { } public abstract class WebResourceError { - ctor public WebResourceError(); - method public abstract java.lang.String getDescription(); + method public abstract java.lang.CharSequence getDescription(); method public abstract int getErrorCode(); } @@ -38843,12 +38838,6 @@ package android.webkit { public abstract class WebResourceResponseBase { ctor public WebResourceResponseBase(); - method public abstract java.io.InputStream getData(); - method public abstract java.lang.String getEncoding(); - method public abstract java.lang.String getMimeType(); - method public abstract java.lang.String getReasonPhrase(); - method public abstract java.util.Map<java.lang.String, java.lang.String> getResponseHeaders(); - method public abstract int getStatusCode(); } public abstract class WebSettings { @@ -39180,6 +39169,7 @@ package android.webkit { method public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError); method public void onReceivedHttpAuthRequest(android.webkit.WebView, android.webkit.HttpAuthHandler, java.lang.String, java.lang.String); method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponseBase); + method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponse); method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String); method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError); method public void onScaleChanged(android.webkit.WebView, float, float); @@ -40282,6 +40272,7 @@ package android.widget { method public void setImageAlpha(int); method public void setImageBitmap(android.graphics.Bitmap); method public void setImageDrawable(android.graphics.drawable.Drawable); + method public void setImageIcon(android.graphics.drawable.Icon); method public void setImageLevel(int); method public void setImageMatrix(android.graphics.Matrix); method public void setImageResource(int); @@ -40862,7 +40853,9 @@ package android.widget { method public void setDouble(int, java.lang.String, double); method public void setEmptyView(int, int); method public void setFloat(int, java.lang.String, float); + method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon); method public void setImageViewBitmap(int, android.graphics.Bitmap); + method public void setImageViewIcon(int, android.graphics.drawable.Icon); method public void setImageViewResource(int, int); method public void setImageViewUri(int, android.net.Uri); method public void setInt(int, java.lang.String, int); diff --git a/api/system-current.txt b/api/system-current.txt index f6843eaf0374..5d11b25842b9 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -32,7 +32,7 @@ package android { field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE"; field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE"; field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE"; - field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; + field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN"; field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH"; field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE"; @@ -43,6 +43,7 @@ package android { field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"; field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE"; field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS"; + field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE"; field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE"; field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT"; field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT"; @@ -4874,6 +4875,8 @@ package android.app { method public android.app.Notification clone(); method public int describeContents(); method public java.lang.String getGroup(); + method public android.graphics.drawable.Icon getLargeIcon(); + method public android.graphics.drawable.Icon getSmallIcon(); method public java.lang.String getSortKey(); method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent); method public void writeToParcel(android.os.Parcel, int); @@ -5018,6 +5021,7 @@ package android.app { ctor public Notification.BigPictureStyle(); ctor public Notification.BigPictureStyle(android.app.Notification.Builder); method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap); + method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap); method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence); method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence); @@ -5056,6 +5060,7 @@ package android.app { method public android.app.Notification.Builder setGroup(java.lang.String); method public android.app.Notification.Builder setGroupSummary(boolean); method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap); + method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); method public android.app.Notification.Builder setNumber(int); @@ -5067,6 +5072,7 @@ package android.app { method public android.app.Notification.Builder setShowWhen(boolean); method public android.app.Notification.Builder setSmallIcon(int); method public android.app.Notification.Builder setSmallIcon(int, int); + method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setSortKey(java.lang.String); method public android.app.Notification.Builder setSound(android.net.Uri); method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int); @@ -9671,6 +9677,7 @@ package android.content.pm { field public static final int INSTALL_FAILED_NO_SHARED_USER = -6; // 0xfffffffa field public static final int INSTALL_FAILED_OLDER_SDK = -12; // 0xfffffff4 field public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23; // 0xffffffe9 + field public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26; // 0xffffffe6 field public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; // 0xfffffff6 field public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; // 0xfffffff8 field public static final int INSTALL_FAILED_TEST_ONLY = -15; // 0xfffffff1 @@ -15905,6 +15912,7 @@ package android.media { public final class AudioDeviceInfo { method public int[] getChannelCounts(); + method public int[] getChannelIndexMasks(); method public int[] getChannelMasks(); method public int[] getFormats(); method public int getId(); @@ -32066,9 +32074,10 @@ package android.system { package android.telecom { - public final class AudioState implements android.os.Parcelable { + public deprecated class AudioState implements android.os.Parcelable { ctor public AudioState(boolean, int, int); ctor public AudioState(android.telecom.AudioState); + ctor public AudioState(android.telecom.CallAudioState); method public static java.lang.String audioRouteToString(int); method public int describeContents(); method public int getRoute(); @@ -32183,11 +32192,28 @@ package android.telecom { ctor public Call.Listener(); } + public final class CallAudioState implements android.os.Parcelable { + ctor public CallAudioState(boolean, int, int); + method public static java.lang.String audioRouteToString(int); + method public int describeContents(); + method public int getRoute(); + method public int getSupportedRouteMask(); + method public boolean isMuted(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR; + field public static final int ROUTE_BLUETOOTH = 2; // 0x2 + field public static final int ROUTE_EARPIECE = 1; // 0x1 + field public static final int ROUTE_SPEAKER = 8; // 0x8 + field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4 + field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5 + } + public abstract class Conference implements android.telecom.Conferenceable { ctor public Conference(android.telecom.PhoneAccountHandle); method public final boolean addConnection(android.telecom.Connection); method public final void destroy(); - method public final android.telecom.AudioState getAudioState(); + method public final deprecated android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.util.List<android.telecom.Connection> getConferenceableConnections(); method public final deprecated long getConnectTimeMillis(); method public final int getConnectionCapabilities(); @@ -32200,7 +32226,8 @@ package android.telecom { method public final android.telecom.StatusHints getStatusHints(); method public android.telecom.Connection.VideoProvider getVideoProvider(); method public int getVideoState(); - method public void onAudioStateChanged(android.telecom.AudioState); + method public deprecated void onAudioStateChanged(android.telecom.AudioState); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onConnectionAdded(android.telecom.Connection); method public void onDisconnect(); method public void onHold(); @@ -32237,7 +32264,8 @@ package android.telecom { method public final android.net.Uri getAddress(); method public final int getAddressPresentation(); method public final boolean getAudioModeIsVoip(); - method public final android.telecom.AudioState getAudioState(); + method public final deprecated android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.lang.String getCallerDisplayName(); method public final int getCallerDisplayNamePresentation(); method public final android.telecom.Conference getConference(); @@ -32251,7 +32279,8 @@ package android.telecom { method public void onAbort(); method public void onAnswer(int); method public void onAnswer(); - method public void onAudioStateChanged(android.telecom.AudioState); + method public deprecated void onAudioStateChanged(android.telecom.AudioState); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onDisconnect(); method public void onHold(); method public void onPlayDtmfTone(char); @@ -32409,13 +32438,13 @@ package android.telecom { public abstract class InCallService extends android.app.Service { ctor public InCallService(); method public final boolean canAddCall(); - method public final android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.util.List<android.telecom.Call> getCalls(); method public deprecated android.telecom.Phone getPhone(); - method public void onAudioStateChanged(android.telecom.AudioState); method public android.os.IBinder onBind(android.content.Intent); method public void onBringToForeground(boolean); method public void onCallAdded(android.telecom.Call); + method public void onCallAudioStateChanged(android.telecom.CallAudioState); method public void onCallRemoved(android.telecom.Call); method public void onCanAddCallChanged(boolean); method public deprecated void onPhoneCreated(android.telecom.Phone); @@ -32456,7 +32485,8 @@ package android.telecom { public final deprecated class Phone { method public final void addListener(android.telecom.Phone.Listener); method public final boolean canAddCall(); - method public final android.telecom.AudioState getAudioState(); + method public final deprecated android.telecom.AudioState getAudioState(); + method public final android.telecom.CallAudioState getCallAudioState(); method public final java.util.List<android.telecom.Call> getCalls(); method public final void removeListener(android.telecom.Phone.Listener); method public final void setAudioRoute(int); @@ -32465,25 +32495,22 @@ package android.telecom { public static abstract class Phone.Listener { ctor public Phone.Listener(); - method public void onAudioStateChanged(android.telecom.Phone, android.telecom.AudioState); + method public deprecated void onAudioStateChanged(android.telecom.Phone, android.telecom.AudioState); method public void onBringToForeground(android.telecom.Phone, boolean); method public void onCallAdded(android.telecom.Phone, android.telecom.Call); + method public void onCallAudioStateChanged(android.telecom.Phone, android.telecom.CallAudioState); method public void onCallRemoved(android.telecom.Phone, android.telecom.Call); method public void onCanAddCallChanged(android.telecom.Phone, boolean); } public final class PhoneAccount implements android.os.Parcelable { method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence); - method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context); method public int describeContents(); method public android.telecom.PhoneAccountHandle getAccountHandle(); method public android.net.Uri getAddress(); method public int getCapabilities(); method public int getHighlightColor(); - method public android.graphics.Bitmap getIconBitmap(); - method public java.lang.String getIconPackageName(); - method public int getIconResId(); - method public int getIconTint(); + method public android.graphics.drawable.Icon getIcon(); method public java.lang.CharSequence getLabel(); method public java.lang.CharSequence getShortDescription(); method public android.net.Uri getSubscriptionAddress(); @@ -32500,7 +32527,6 @@ package android.telecom { field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8 field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR; field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0 - field public static final int NO_ICON_TINT = 0; // 0x0 field public static final int NO_RESOURCE_ID = -1; // 0xffffffff field public static final java.lang.String SCHEME_SIP = "sip"; field public static final java.lang.String SCHEME_TEL = "tel"; @@ -32515,11 +32541,7 @@ package android.telecom { method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri); method public android.telecom.PhoneAccount.Builder setCapabilities(int); method public android.telecom.PhoneAccount.Builder setHighlightColor(int); - method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int); - method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int); - method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int); - method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int); - method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap); + method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon); method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence); method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri); method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>); @@ -32549,7 +32571,8 @@ package android.telecom { method public final void registerCallback(android.telecom.RemoteConference.Callback); method public final void registerCallback(android.telecom.RemoteConference.Callback, android.os.Handler); method public void separate(android.telecom.RemoteConnection); - method public void setAudioState(android.telecom.AudioState); + method public deprecated void setAudioState(android.telecom.AudioState); + method public void setCallAudioState(android.telecom.CallAudioState); method public void stopDtmfTone(); method public void swap(); method public void unhold(); @@ -32589,7 +32612,8 @@ package android.telecom { method public void registerCallback(android.telecom.RemoteConnection.Callback); method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler); method public void reject(); - method public void setAudioState(android.telecom.AudioState); + method public deprecated void setAudioState(android.telecom.AudioState); + method public void setCallAudioState(android.telecom.CallAudioState); method public void stopDtmfTone(); method public void unhold(); method public void unregisterCallback(android.telecom.RemoteConnection.Callback); @@ -41108,7 +41132,7 @@ package android.webkit { public abstract class WebResourceError { ctor public WebResourceError(); - method public abstract java.lang.String getDescription(); + method public abstract java.lang.CharSequence getDescription(); method public abstract int getErrorCode(); } @@ -41123,6 +41147,7 @@ package android.webkit { public class WebResourceResponse extends android.webkit.WebResourceResponseBase { ctor public WebResourceResponse(java.lang.String, java.lang.String, java.io.InputStream); ctor public WebResourceResponse(java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.io.InputStream); + ctor public WebResourceResponse(boolean, java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.io.InputStream); method public java.io.InputStream getData(); method public java.lang.String getEncoding(); method public java.lang.String getMimeType(); @@ -41138,12 +41163,6 @@ package android.webkit { public abstract class WebResourceResponseBase { ctor public WebResourceResponseBase(); - method public abstract java.io.InputStream getData(); - method public abstract java.lang.String getEncoding(); - method public abstract java.lang.String getMimeType(); - method public abstract java.lang.String getReasonPhrase(); - method public abstract java.util.Map<java.lang.String, java.lang.String> getResponseHeaders(); - method public abstract int getStatusCode(); } public abstract class WebSettings { @@ -41520,6 +41539,7 @@ package android.webkit { method public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError); method public void onReceivedHttpAuthRequest(android.webkit.WebView, android.webkit.HttpAuthHandler, java.lang.String, java.lang.String); method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponseBase); + method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponse); method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String); method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError); method public void onScaleChanged(android.webkit.WebView, float, float); @@ -42827,6 +42847,7 @@ package android.widget { method public void setImageAlpha(int); method public void setImageBitmap(android.graphics.Bitmap); method public void setImageDrawable(android.graphics.drawable.Drawable); + method public void setImageIcon(android.graphics.drawable.Icon); method public void setImageLevel(int); method public void setImageMatrix(android.graphics.Matrix); method public void setImageResource(int); @@ -43407,7 +43428,9 @@ package android.widget { method public void setDouble(int, java.lang.String, double); method public void setEmptyView(int, int); method public void setFloat(int, java.lang.String, float); + method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon); method public void setImageViewBitmap(int, android.graphics.Bitmap); + method public void setImageViewIcon(int, android.graphics.drawable.Icon); method public void setImageViewResource(int, int); method public void setImageViewUri(int, android.net.Uri); method public void setInt(int, java.lang.String, int); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 49b254936295..3ffeea7e3bd5 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -30,6 +30,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.session.MediaSession; @@ -885,6 +886,9 @@ public class Notification implements Parcelable */ public static final int HEADS_UP_REQUESTED = 2; + private Icon mSmallIcon; + private Icon mLargeIcon; + /** * Structure to encapsulate a named action that can be shown as part of this notification. * It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is @@ -1362,7 +1366,7 @@ public class Notification implements Parcelable int version = parcel.readInt(); when = parcel.readLong(); - icon = parcel.readInt(); + mSmallIcon = Icon.CREATOR.createFromParcel(parcel); number = parcel.readInt(); if (parcel.readInt() != 0) { contentIntent = PendingIntent.CREATOR.createFromParcel(parcel); @@ -1380,7 +1384,7 @@ public class Notification implements Parcelable contentView = RemoteViews.CREATOR.createFromParcel(parcel); } if (parcel.readInt() != 0) { - largeIcon = Bitmap.CREATOR.createFromParcel(parcel); + mLargeIcon = Icon.CREATOR.createFromParcel(parcel); } defaults = parcel.readInt(); flags = parcel.readInt(); @@ -1445,7 +1449,7 @@ public class Notification implements Parcelable */ public void cloneInto(Notification that, boolean heavy) { that.when = this.when; - that.icon = this.icon; + that.mSmallIcon = this.mSmallIcon; that.number = this.number; // PendingIntents are global, so there's no reason (or way) to clone them. @@ -1462,8 +1466,8 @@ public class Notification implements Parcelable if (heavy && this.contentView != null) { that.contentView = this.contentView.clone(); } - if (heavy && this.largeIcon != null) { - that.largeIcon = Bitmap.createBitmap(this.largeIcon); + if (heavy && this.mLargeIcon != null) { + that.mLargeIcon = this.mLargeIcon; } that.iconLevel = this.iconLevel; that.sound = this.sound; // android.net.Uri is immutable @@ -1544,7 +1548,7 @@ public class Notification implements Parcelable contentView = null; bigContentView = null; headsUpContentView = null; - largeIcon = null; + mLargeIcon = null; if (extras != null) { extras.remove(Notification.EXTRA_LARGE_ICON); extras.remove(Notification.EXTRA_LARGE_ICON_BIG); @@ -1586,7 +1590,7 @@ public class Notification implements Parcelable parcel.writeInt(1); parcel.writeLong(when); - parcel.writeInt(icon); + mSmallIcon.writeToParcel(parcel, 0); parcel.writeInt(number); if (contentIntent != null) { parcel.writeInt(1); @@ -1618,9 +1622,9 @@ public class Notification implements Parcelable } else { parcel.writeInt(0); } - if (largeIcon != null) { + if (mLargeIcon != null) { parcel.writeInt(1); - largeIcon.writeToParcel(parcel, 0); + mLargeIcon.writeToParcel(parcel, 0); } else { parcel.writeInt(0); } @@ -1865,6 +1869,27 @@ public class Notification implements Parcelable } /** + * The small icon representing this notification in the status bar and content view. + * + * @return the small icon representing this notification. + * + * @see Builder#getSmallIcon() + * @see Builder#setSmallIcon(Icon) + */ + public Icon getSmallIcon() { + return mSmallIcon; + } + + /** + * The large icon shown in this notification's content view. + * @see Builder#getLargeIcon() + * @see Builder#setLargeIcon(Icon) + */ + public Icon getLargeIcon() { + return mLargeIcon; + } + + /** * @hide */ public boolean isValid() { @@ -1966,7 +1991,7 @@ public class Notification implements Parcelable private Context mContext; private long mWhen; - private int mSmallIcon; + private Icon mSmallIcon, mLargeIcon; private int mSmallIconLevel; private int mNumber; private CharSequence mContentTitle; @@ -1979,7 +2004,6 @@ public class Notification implements Parcelable private PendingIntent mFullScreenIntent; private CharSequence mTickerText; private RemoteViews mTickerView; - private Bitmap mLargeIcon; private Uri mSound; private int mAudioStreamType; private AudioAttributes mAudioAttributes; @@ -2160,8 +2184,7 @@ public class Notification implements Parcelable * @see Notification#icon */ public Builder setSmallIcon(@DrawableRes int icon) { - mSmallIcon = icon; - return this; + return setSmallIcon(Icon.createWithResource(mContext.getResources(), icon)); } /** @@ -2176,8 +2199,20 @@ public class Notification implements Parcelable * @see Notification#iconLevel */ public Builder setSmallIcon(@DrawableRes int icon, int level) { - mSmallIcon = icon; mSmallIconLevel = level; + return setSmallIcon(icon); + } + + /** + * Set the small icon, which will be used to represent the notification in the + * status bar and content view (unless overriden there by a + * {@link #setLargeIcon(Bitmap) large icon}). + * + * @param icon An Icon object to use. + * @see Notification#icon + */ + public Builder setSmallIcon(Icon icon) { + mSmallIcon = icon; return this; } @@ -2324,14 +2359,24 @@ public class Notification implements Parcelable } /** - * Add a large icon to the notification (and the ticker on some devices). + * Add a large icon to the notification content view. * * In the platform template, this image will be shown on the left of the notification view - * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side). + * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small + * badge atop the large icon). + */ + public Builder setLargeIcon(Bitmap b) { + return setLargeIcon(b != null ? Icon.createWithBitmap(b) : null); + } + + /** + * Add a large icon to the notification content view. * - * @see Notification#largeIcon + * In the platform template, this image will be shown on the left of the notification view + * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small + * badge atop the large icon). */ - public Builder setLargeIcon(Bitmap icon) { + public Builder setLargeIcon(Icon icon) { mLargeIcon = icon; return this; } @@ -2840,13 +2885,13 @@ public class Notification implements Parcelable boolean contentTextInLine2 = false; if (mLargeIcon != null) { - contentView.setImageViewBitmap(R.id.icon, mLargeIcon); + contentView.setImageViewIcon(R.id.icon, mLargeIcon); processLargeLegacyIcon(mLargeIcon, contentView); - contentView.setImageViewResource(R.id.right_icon, mSmallIcon); + contentView.setImageViewIcon(R.id.right_icon, mSmallIcon); contentView.setViewVisibility(R.id.right_icon, View.VISIBLE); processSmallRightIcon(mSmallIcon, contentView); } else { // small icon at left - contentView.setImageViewResource(R.id.icon, mSmallIcon); + contentView.setImageViewIcon(R.id.icon, mSmallIcon); contentView.setViewVisibility(R.id.icon, View.VISIBLE); processSmallIconAsLarge(mSmallIcon, contentView); } @@ -3086,14 +3131,16 @@ public class Notification implements Parcelable /** * Apply any necessary background to smallIcons being used in the largeIcon spot. */ - private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) { + private void processSmallIconAsLarge(Icon largeIcon, RemoteViews contentView) { if (!isLegacy()) { contentView.setDrawableParameters(R.id.icon, false, -1, 0xFFFFFFFF, PorterDuff.Mode.SRC_ATOP, -1); - } - if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) { applyLargeIconBackground(contentView); + } else { + if (mColorUtil.isGrayscaleIcon(mContext, largeIcon)) { + applyLargeIconBackground(contentView); + } } } @@ -3102,8 +3149,9 @@ public class Notification implements Parcelable * if it's grayscale). */ // TODO: also check bounds, transparency, that sort of thing. - private void processLargeLegacyIcon(Bitmap largeIcon, RemoteViews contentView) { - if (isLegacy() && mColorUtil.isGrayscaleIcon(largeIcon)) { + private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) { + if (largeIcon != null && isLegacy() + && mColorUtil.isGrayscaleIcon(mContext, largeIcon)) { applyLargeIconBackground(contentView); } else { removeLargeIconBackground(contentView); @@ -3137,14 +3185,15 @@ public class Notification implements Parcelable /** * Recolor small icons when used in the R.id.right_icon slot. */ - private void processSmallRightIcon(int smallIconDrawableId, - RemoteViews contentView) { + private void processSmallRightIcon(Icon smallIcon, RemoteViews contentView) { if (!isLegacy()) { contentView.setDrawableParameters(R.id.right_icon, false, -1, 0xFFFFFFFF, PorterDuff.Mode.SRC_ATOP, -1); } - if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) { + final boolean gray = (smallIcon.getType() == Icon.TYPE_RESOURCE + && mColorUtil.isGrayscaleIcon(mContext, smallIcon.getResId())); + if (!isLegacy() || gray) { contentView.setInt(R.id.right_icon, "setBackgroundResource", R.drawable.notification_icon_legacy_bg); @@ -3180,7 +3229,10 @@ public class Notification implements Parcelable public Notification buildUnstyled() { Notification n = new Notification(); n.when = mWhen; - n.icon = mSmallIcon; + n.mSmallIcon = mSmallIcon; + if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) { + n.icon = mSmallIcon.getResId(); + } n.iconLevel = mSmallIconLevel; n.number = mNumber; @@ -3192,7 +3244,10 @@ public class Notification implements Parcelable n.fullScreenIntent = mFullScreenIntent; n.tickerText = mTickerText; n.tickerView = makeTickerView(); - n.largeIcon = mLargeIcon; + n.mLargeIcon = mLargeIcon; + if (mLargeIcon != null && mLargeIcon.getType() == Icon.TYPE_BITMAP) { + n.largeIcon = mLargeIcon.getBitmap(); + } n.sound = mSound; n.audioStreamType = mAudioStreamType; n.audioAttributes = mAudioAttributes; @@ -3242,7 +3297,7 @@ public class Notification implements Parcelable extras.putCharSequence(EXTRA_TEXT, mContentText); extras.putCharSequence(EXTRA_SUB_TEXT, mSubText); extras.putCharSequence(EXTRA_INFO_TEXT, mContentInfo); - extras.putInt(EXTRA_SMALL_ICON, mSmallIcon); + extras.putParcelable(EXTRA_SMALL_ICON, mSmallIcon); extras.putInt(EXTRA_PROGRESS, mProgress); extras.putInt(EXTRA_PROGRESS_MAX, mProgressMax); extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate); @@ -3430,7 +3485,7 @@ public class Notification implements Parcelable // Notification fields. mWhen = n.when; - mSmallIcon = n.icon; + mSmallIcon = n.mSmallIcon; mSmallIconLevel = n.iconLevel; mNumber = n.number; @@ -3441,7 +3496,7 @@ public class Notification implements Parcelable mFullScreenIntent = n.fullScreenIntent; mTickerText = n.tickerText; mTickerView = n.tickerView; - mLargeIcon = n.largeIcon; + mLargeIcon = n.mLargeIcon; mSound = n.sound; mAudioStreamType = n.audioStreamType; mAudioAttributes = n.audioAttributes; @@ -3472,7 +3527,7 @@ public class Notification implements Parcelable mContentText = extras.getCharSequence(EXTRA_TEXT); mSubText = extras.getCharSequence(EXTRA_SUB_TEXT); mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT); - mSmallIcon = extras.getInt(EXTRA_SMALL_ICON); + mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON); mProgress = extras.getInt(EXTRA_PROGRESS); mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX); mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE); @@ -3764,7 +3819,7 @@ public class Notification implements Parcelable */ public static class BigPictureStyle extends Style { private Bitmap mPicture; - private Bitmap mBigLargeIcon; + private Icon mBigLargeIcon; private boolean mBigLargeIconSet = false; public BigPictureStyle() { @@ -3803,8 +3858,15 @@ public class Notification implements Parcelable * Override the large icon when the big notification is shown. */ public BigPictureStyle bigLargeIcon(Bitmap b) { + return bigLargeIcon(b != null ? Icon.createWithBitmap(b) : null); + } + + /** + * Override the large icon when the big notification is shown. + */ + public BigPictureStyle bigLargeIcon(Icon icon) { mBigLargeIconSet = true; - mBigLargeIcon = b; + mBigLargeIcon = icon; return this; } @@ -3815,7 +3877,7 @@ public class Notification implements Parcelable // 1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides // mLargeIcon // 2. !mBigLargeIconSet -> mLargeIcon applies - Bitmap oldLargeIcon = null; + Icon oldLargeIcon = null; if (mBigLargeIconSet) { oldLargeIcon = mBuilder.mLargeIcon; mBuilder.mLargeIcon = mBigLargeIcon; diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java index c74bbddaaadf..34699d8012c2 100644 --- a/core/java/android/app/usage/UsageStatsManager.java +++ b/core/java/android/app/usage/UsageStatsManager.java @@ -234,4 +234,15 @@ public final class UsageStatsManager { } return false; } + + /** + * @hide + */ + public void setAppInactive(String packageName, boolean inactive) { + try { + mService.setAppInactive(packageName, inactive, UserHandle.myUserId()); + } catch (RemoteException e) { + // fall through + } + } } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 202a8a7ae231..2ca030635ef5 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -653,6 +653,16 @@ public abstract class PackageManager { public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25; /** + * Installation return code: this is passed to the {@link IPackageInstallObserver} by + * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if + * the old package has target SDK high enough to support runtime permission and + * the new package has target SDK low enough to not support runtime permissions. + * @hide + */ + @SystemApi + public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26; + + /** * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} * if the parser was given a path that is not a file, or does not end with the expected @@ -4512,6 +4522,7 @@ public abstract class PackageManager { case INSTALL_FAILED_PACKAGE_CHANGED: return PackageInstaller.STATUS_FAILURE_INVALID; case INSTALL_FAILED_UID_CHANGED: return PackageInstaller.STATUS_FAILURE_INVALID; case INSTALL_FAILED_VERSION_DOWNGRADE: return PackageInstaller.STATUS_FAILURE_INVALID; + case INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE: return PackageInstaller.STATUS_FAILURE_INVALID; case INSTALL_PARSE_FAILED_NOT_APK: return PackageInstaller.STATUS_FAILURE_INVALID; case INSTALL_PARSE_FAILED_BAD_MANIFEST: return PackageInstaller.STATUS_FAILURE_INVALID; case INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: return PackageInstaller.STATUS_FAILURE_INVALID; diff --git a/core/java/android/webkit/WebResourceError.java b/core/java/android/webkit/WebResourceError.java index 080d1740562b..11f1b6f17566 100644 --- a/core/java/android/webkit/WebResourceError.java +++ b/core/java/android/webkit/WebResourceError.java @@ -16,6 +16,8 @@ package android.webkit; +import android.annotation.SystemApi; + /** * Encapsulates information about errors occured during loading of web resources. See * {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError) WebViewClient.onReceivedError(WebView, WebResourceRequest, WebResourceError)} @@ -35,5 +37,12 @@ public abstract class WebResourceError { * * @return The description of the error */ - public abstract String getDescription(); + public abstract CharSequence getDescription(); + + /** + * This class can not be subclassed by applications. + * @hide + */ + @SystemApi + public WebResourceError() {} } diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java index a42aaa78deb8..3a925c8dc826 100644 --- a/core/java/android/webkit/WebResourceResponse.java +++ b/core/java/android/webkit/WebResourceResponse.java @@ -20,12 +20,15 @@ import java.io.InputStream; import java.io.StringBufferInputStream; import java.util.Map; +import android.annotation.SystemApi; + /** * Encapsulates a resource response. Applications can return an instance of this * class from {@link WebViewClient#shouldInterceptRequest} to provide a custom * response when the WebView requests a particular resource. */ public class WebResourceResponse extends WebResourceResponseBase { + private boolean mImmutable; private String mMimeType; private String mEncoding; private int mStatusCode; @@ -80,13 +83,15 @@ public class WebResourceResponse extends WebResourceResponseBase { * @param mimeType The resource response's MIME type */ public void setMimeType(String mimeType) { + checkImmutable(); mMimeType = mimeType; } /** - * {@inheritDoc} + * Gets the resource response's MIME type. + * + * @return The resource response's MIME type */ - @Override public String getMimeType() { return mMimeType; } @@ -98,13 +103,15 @@ public class WebResourceResponse extends WebResourceResponseBase { * @param encoding The resource response's encoding */ public void setEncoding(String encoding) { + checkImmutable(); mEncoding = encoding; } /** - * {@inheritDoc} + * Gets the resource response's encoding. + * + * @return The resource response's encoding */ - @Override public String getEncoding() { return mEncoding; } @@ -118,6 +125,7 @@ public class WebResourceResponse extends WebResourceResponseBase { * and not empty. */ public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase) { + checkImmutable(); if (statusCode < 100) throw new IllegalArgumentException("statusCode can't be less than 100."); if (statusCode > 599) @@ -140,17 +148,19 @@ public class WebResourceResponse extends WebResourceResponseBase { } /** - * {@inheritDoc} + * Gets the resource response's status code. + * + * @return The resource response's status code. */ - @Override public int getStatusCode() { return mStatusCode; } /** - * {@inheritDoc} + * Gets the description of the resource response's status code. + * + * @return The description of the resource response's status code. */ - @Override public String getReasonPhrase() { return mReasonPhrase; } @@ -161,13 +171,15 @@ public class WebResourceResponse extends WebResourceResponseBase { * @param headers Mapping of header name -> header value. */ public void setResponseHeaders(Map<String, String> headers) { + checkImmutable(); mResponseHeaders = headers; } /** - * {@inheritDoc} + * Gets the headers for the resource response. + * + * @return The headers for the resource response. */ - @Override public Map<String, String> getResponseHeaders() { return mResponseHeaders; } @@ -180,6 +192,7 @@ public class WebResourceResponse extends WebResourceResponseBase { * StringBufferInputStream. */ public void setData(InputStream data) { + checkImmutable(); // If data is (or is a subclass of) StringBufferInputStream if (data != null && StringBufferInputStream.class.isAssignableFrom(data.getClass())) { throw new IllegalArgumentException("StringBufferInputStream is deprecated and must " + @@ -189,10 +202,32 @@ public class WebResourceResponse extends WebResourceResponseBase { } /** - * {@inheritDoc} + * Gets the input stream that provides the resource response's data. + * + * @return The input stream that provides the resource response's data */ - @Override public InputStream getData() { return mInputStream; } + + /** + * The internal version of the constructor that doesn't perform arguments checks. + * @hide + */ + @SystemApi + public WebResourceResponse(boolean immutable, String mimeType, String encoding, int statusCode, + String reasonPhrase, Map<String, String> responseHeaders, InputStream data) { + mImmutable = immutable; + mMimeType = mimeType; + mEncoding = encoding; + mStatusCode = statusCode; + mReasonPhrase = reasonPhrase; + mResponseHeaders = responseHeaders; + mInputStream = data; + } + + private void checkImmutable() { + if (mImmutable) + throw new IllegalStateException("This WebResourceResponse instance is immutable"); + } } diff --git a/core/java/android/webkit/WebResourceResponseBase.java b/core/java/android/webkit/WebResourceResponseBase.java index cffde82c673d..69eb3974699b 100644 --- a/core/java/android/webkit/WebResourceResponseBase.java +++ b/core/java/android/webkit/WebResourceResponseBase.java @@ -16,53 +16,9 @@ package android.webkit; -import java.io.InputStream; -import java.util.Map; - /** - * Encapsulates a resource response received from the server. - * This is an abstract class used by WebView callbacks. + * This class will be deleted after updated WebView.apk will be submitted + * into the Android tree. */ public abstract class WebResourceResponseBase { - /** - * Gets the resource response's MIME type. - * - * @return The resource response's MIME type - */ - public abstract String getMimeType(); - - /** - * Gets the resource response's encoding. - * - * @return The resource response's encoding - */ - public abstract String getEncoding(); - - /** - * Gets the resource response's status code. - * - * @return The resource response's status code. - */ - public abstract int getStatusCode(); - - /** - * Gets the description of the resource response's status code. - * - * @return The description of the resource response's status code. - */ - public abstract String getReasonPhrase(); - - /** - * Gets the headers for the resource response. - * - * @return The headers for the resource response. - */ - public abstract Map<String, String> getResponseHeaders(); - - /** - * Gets the input stream that provides the resource response's data. - * - * @return The input stream that provides the resource response's data - */ - public abstract InputStream getData(); } diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java index 3a40de6312d3..feed2b8f22bf 100644 --- a/core/java/android/webkit/WebViewClient.java +++ b/core/java/android/webkit/WebViewClient.java @@ -233,11 +233,20 @@ public class WebViewClient { public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { if (request.isForMainFrame()) { onReceivedError(view, - error.getErrorCode(), error.getDescription(), request.getUrl().toString()); + error.getErrorCode(), error.getDescription().toString(), + request.getUrl().toString()); } } /** + * This method will be deleted after updated WebView.apk will be submitted + * into the Android tree. + */ + public void onReceivedHttpError( + WebView view, WebResourceRequest request, WebResourceResponseBase errorResponse) { + } + + /** * Notify the host application that an HTTP error has been received from the server while * loading a resource. HTTP errors have status codes >= 400. This callback will be called * for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to @@ -248,7 +257,7 @@ public class WebViewClient { * @param errorResponse Information about the error occured. */ public void onReceivedHttpError( - WebView view, WebResourceRequest request, WebResourceResponseBase errorResponse) { + WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { } /** diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 814882a4242c..30f373a35e77 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -3855,8 +3855,8 @@ public class Editor { private class SelectionStartHandleView extends HandleView { // Indicates whether the cursor is making adjustments within a word. private boolean mInWord = false; - // Offset to track difference between touch and word boundary. - protected int mTouchWordOffset; + // Difference between touch position and word boundary position. + private float mTouchWordDelta; public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); @@ -3908,18 +3908,36 @@ public class Editor { offset = mPreviousOffset; } } - mTouchWordOffset = Math.max(trueOffset - offset, 0); - positionCursor = true; - } else if (offset - mTouchWordOffset > mPreviousOffset || currLine > mPrevLine) { - // User is shrinking the selection. - if (currLine > mPrevLine) { - // We're on a different line, so we'll snap to word boundaries. - offset = start; - mTouchWordOffset = Math.max(trueOffset - offset, 0); + final Layout layout = mTextView.getLayout(); + if (layout != null && offset < trueOffset) { + final float adjustedX = layout.getPrimaryHorizontal(offset); + mTouchWordDelta = + mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX; } else { - offset -= mTouchWordOffset; + mTouchWordDelta = 0.0f; } positionCursor = true; + } else { + final int adjustedOffset = + mTextView.getOffsetAtCoordinate(currLine, x - mTouchWordDelta); + if (adjustedOffset > mPreviousOffset || currLine > mPrevLine) { + // User is shrinking the selection. + if (currLine > mPrevLine) { + // We're on a different line, so we'll snap to word boundaries. + offset = start; + final Layout layout = mTextView.getLayout(); + if (layout != null && offset < trueOffset) { + final float adjustedX = layout.getPrimaryHorizontal(offset); + mTouchWordDelta = + mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX; + } else { + mTouchWordDelta = 0.0f; + } + } else { + offset = adjustedOffset; + } + positionCursor = true; + } } // Handles can not cross and selection is at least one character. @@ -3934,7 +3952,7 @@ public class Editor { } else { offset = alteredOffset; } - mTouchWordOffset = 0; + mTouchWordDelta = 0.0f; } mInWord = !getWordIteratorWithText().isBoundary(offset); positionAtCursorOffset(offset, false); @@ -3946,7 +3964,7 @@ public class Editor { boolean superResult = super.onTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP) { // Reset the touch word offset when the user has lifted their finger. - mTouchWordOffset = 0; + mTouchWordDelta = 0.0f; } return superResult; } @@ -3955,8 +3973,8 @@ public class Editor { private class SelectionEndHandleView extends HandleView { // Indicates whether the cursor is making adjustments within a word. private boolean mInWord = false; - // Offset to track difference between touch and word boundary. - protected int mTouchWordOffset; + // Difference between touch position and word boundary position. + private float mTouchWordDelta; public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) { super(drawableLtr, drawableRtl); @@ -4008,18 +4026,36 @@ public class Editor { offset = mPreviousOffset; } } - mTouchWordOffset = Math.max(offset - trueOffset, 0); - positionCursor = true; - } else if (offset + mTouchWordOffset < mPreviousOffset || currLine < mPrevLine) { - // User is shrinking the selection. - if (currLine < mPrevLine) { - // We're on a different line, so we'll snap to word boundaries. - offset = end; - mTouchWordOffset = Math.max(offset - trueOffset, 0); + final Layout layout = mTextView.getLayout(); + if (layout != null && offset > trueOffset) { + final float adjustedX = layout.getPrimaryHorizontal(offset); + mTouchWordDelta = + adjustedX - mTextView.convertToLocalHorizontalCoordinate(x); } else { - offset += mTouchWordOffset; + mTouchWordDelta = 0.0f; } positionCursor = true; + } else { + final int adjustedOffset = + mTextView.getOffsetAtCoordinate(currLine, x + mTouchWordDelta); + if (adjustedOffset < mPreviousOffset || currLine < mPrevLine) { + // User is shrinking the selection. + if (currLine < mPrevLine) { + // We're on a different line, so we'll snap to word boundaries. + offset = end; + final Layout layout = mTextView.getLayout(); + if (layout != null && offset > trueOffset) { + final float adjustedX = layout.getPrimaryHorizontal(offset); + mTouchWordDelta = + adjustedX - mTextView.convertToLocalHorizontalCoordinate(x); + } else { + mTouchWordDelta = 0.0f; + } + } else { + offset = adjustedOffset; + } + positionCursor = true; + } } if (positionCursor) { @@ -4034,7 +4070,7 @@ public class Editor { } else { offset = Math.min(alteredOffset, length); } - mTouchWordOffset = 0; + mTouchWordDelta = 0.0f; } mInWord = !getWordIteratorWithText().isBoundary(offset); positionAtCursorOffset(offset, false); @@ -4046,7 +4082,7 @@ public class Editor { boolean superResult = super.onTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP) { // Reset the touch word offset when the user has lifted their finger. - mTouchWordOffset = 0; + mTouchWordDelta = 0.0f; } return superResult; } diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 05059bca81d8..94cda889c4f1 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -36,8 +36,10 @@ import android.graphics.RectF; import android.graphics.Xfermode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Build; +import android.os.Handler; import android.text.TextUtils; import android.util.AttributeSet; import android.util.Log; @@ -462,6 +464,21 @@ public class ImageView extends View { } /** + * Sets the content of this ImageView to the specified Icon. + * + * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding + * on the UI thread, which can cause UI jank. If that's a concern, consider using + * {@link Icon#loadDrawableAsync(Context, Handler, Icon.OnDrawableLoadedListener)} + * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p> + * + * @param icon an Icon holding the desired image + */ + @android.view.RemotableViewMethod + public void setImageIcon(Icon icon) { + setImageDrawable(icon.loadDrawable(mContext)); + } + + /** * Applies a tint to the image drawable. Does not modify the current tint * mode, which is {@link PorterDuff.Mode#SRC_IN} by default. * <p> diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index a10be119da45..dc75fd04227a 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -35,6 +35,7 @@ import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -1072,6 +1073,7 @@ public class RemoteViews implements Parcelable, Filter { static final int BUNDLE = 13; static final int INTENT = 14; static final int COLOR_STATE_LIST = 15; + static final int ICON = 16; String methodName; int type; @@ -1150,6 +1152,10 @@ public class RemoteViews implements Parcelable, Filter { this.value = ColorStateList.CREATOR.createFromParcel(in); } break; + case ICON: + if (in.readInt() != 0) { + this.value = Icon.CREATOR.createFromParcel(in); + } default: break; } @@ -1225,6 +1231,13 @@ public class RemoteViews implements Parcelable, Filter { if (this.value != null) { ((ColorStateList)this.value).writeToParcel(out, flags); } + break; + case ICON: + out.writeInt(this.value != null ? 1 : 0); + if (this.value != null) { + ((Icon)this.value).writeToParcel(out, flags); + } + break; default: break; } @@ -1262,6 +1275,8 @@ public class RemoteViews implements Parcelable, Filter { return Intent.class; case COLOR_STATE_LIST: return ColorStateList.class; + case ICON: + return Icon.class; default: return null; } @@ -2082,6 +2097,16 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Equivalent to calling ImageView.setImageIcon + * + * @param viewId The id of the view whose bitmap should change + * @param icon The new Icon for the ImageView + */ + public void setImageViewIcon(int viewId, Icon icon) { + setIcon(viewId, "setImageIcon", icon); + } + + /** * Equivalent to calling AdapterView.setEmptyView * * @param viewId The id of the view on which to set the empty view @@ -2519,6 +2544,17 @@ public class RemoteViews implements Parcelable, Filter { } /** + * Call a method taking one Icon on a view in the layout for this RemoteViews. + * + * @param viewId The id of the view on which to call the method. + * @param methodName The name of the method to call. + * @param value The {@link android.graphics.drawable.Icon} to pass the method. + */ + public void setIcon(int viewId, String methodName, Icon value) { + addAction(new ReflectionAction(viewId, methodName, ReflectionAction.ICON, value)); + } + + /** * Equivalent to calling View.setContentDescription(CharSequence). * * @param viewId The id of the view whose content description should change. diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index e0792cb37646..4693d4b7c840 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -16,40 +16,46 @@ package com.android.internal.statusbar; +import android.graphics.drawable.Icon; import android.os.Parcel; import android.os.Parcelable; import android.os.UserHandle; public class StatusBarIcon implements Parcelable { - public String iconPackage; public UserHandle user; - public int iconId; + public Icon icon; public int iconLevel; public boolean visible = true; public int number; public CharSequence contentDescription; - public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, + public StatusBarIcon(UserHandle user, Icon icon, int iconLevel, int number, CharSequence contentDescription) { - this.iconPackage = iconPackage; this.user = user; - this.iconId = iconId; + this.icon = icon; this.iconLevel = iconLevel; this.number = number; this.contentDescription = contentDescription; } + public StatusBarIcon(String iconPackage, UserHandle user, + int iconId, int iconLevel, int number, + CharSequence contentDescription) { + this(user, Icon.createWithResource(iconPackage, iconId), + iconLevel, number, contentDescription); + } + @Override public String toString() { - return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier() - + " id=0x" + Integer.toHexString(this.iconId) + return "StatusBarIcon(icon=" + this.icon + + " user=" + user.getIdentifier() + " level=" + this.iconLevel + " visible=" + visible + " num=" + this.number + " )"; } @Override public StatusBarIcon clone() { - StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId, + StatusBarIcon that = new StatusBarIcon(this.user, this.icon, this.iconLevel, this.number, this.contentDescription); that.visible = this.visible; return that; @@ -63,9 +69,8 @@ public class StatusBarIcon implements Parcelable { } public void readFromParcel(Parcel in) { - this.iconPackage = in.readString(); + this.icon = (Icon) in.readParcelable(null); this.user = (UserHandle) in.readParcelable(null); - this.iconId = in.readInt(); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; this.number = in.readInt(); @@ -73,9 +78,8 @@ public class StatusBarIcon implements Parcelable { } public void writeToParcel(Parcel out, int flags) { - out.writeString(this.iconPackage); + out.writeParcelable(this.icon, 0); out.writeParcelable(this.user, 0); - out.writeInt(this.iconId); out.writeInt(this.iconLevel); out.writeInt(this.visible ? 1 : 0); out.writeInt(this.number); diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index 3249ea3a5250..607697340ca0 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -24,6 +24,7 @@ import android.graphics.Color; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.graphics.drawable.VectorDrawable; import android.text.SpannableStringBuilder; import android.text.Spanned; @@ -129,6 +130,20 @@ public class NotificationColorUtil { } } + public boolean isGrayscaleIcon(Context context, Icon icon) { + if (icon == null) { + return false; + } + switch (icon.getType()) { + case Icon.TYPE_BITMAP: + return isGrayscaleIcon(icon.getBitmap()); + case Icon.TYPE_RESOURCE: + return isGrayscaleIcon(context, icon.getResId()); + default: + return false; + } + } + /** * Checks whether a drawable with a resoure id is a small grayscale icon. * Grayscale here means "very close to a perfect gray"; icon means "no larger than 64dp". diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index edff537a5141..4c034b3169bd 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1107,6 +1107,11 @@ <permission android:name="android.permission.CAPTURE_TV_INPUT" android:protectionLevel="signatureOrSystem" /> + <!-- @hide Allows TvInputService to access DVB device. + <p>Not for use by third-party applications. --> + <permission android:name="android.permission.DVB_DEVICE" + android:protectionLevel="signatureOrSystem" /> + <!-- @hide Allows enabling/disabling OEM unlock <p>Not for use by third-party applications. --> <permission android:name="android.permission.OEM_UNLOCK_STATE" @@ -1184,10 +1189,20 @@ android:protectionLevel="system|signature" /> <!-- Must be required by a {@link android.telecom.ConnectionService}, - to ensure that only the system can bind to it. --> + to ensure that only the system can bind to it. + @deprecated {@link android.telecom.ConnectionService}s should require + android.permission.BIND_TELECOM_CONNECTION_SERVICE instead. + @SystemApi + @hide --> <permission android:name="android.permission.BIND_CONNECTION_SERVICE" android:protectionLevel="system|signature" /> + <!-- Must be required by a {@link android.telecom.ConnectionService}, + to ensure that only the system can bind to it. --> + <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE" + android:protectionLevel="system|signature" /> + + <!-- @SystemApi Allows an application to control the in-call experience. @hide --> <permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index b2c3ab7efff3..37fb703d77f7 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -18,9 +18,9 @@ package android.graphics.drawable; import android.annotation.DrawableRes; import android.content.ContentResolver; +import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; @@ -29,15 +29,16 @@ import android.os.Handler; import android.os.Message; import android.os.Parcel; import android.os.Parcelable; -import android.os.UserHandle; import android.util.Log; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; -import java.lang.IllegalArgumentException; -import java.lang.Override; +import java.io.OutputStream; /** * An umbrella container for several serializable graphics representations, including Bitmaps, @@ -52,10 +53,16 @@ import java.lang.Override; public final class Icon implements Parcelable { private static final String TAG = "Icon"; - private static final int TYPE_BITMAP = 1; - private static final int TYPE_RESOURCE = 2; - private static final int TYPE_DATA = 3; - private static final int TYPE_URI = 4; + /** @hide */ + public static final int TYPE_BITMAP = 1; + /** @hide */ + public static final int TYPE_RESOURCE = 2; + /** @hide */ + public static final int TYPE_DATA = 3; + /** @hide */ + public static final int TYPE_URI = 4; + + private static final int VERSION_STREAM_SERIALIZER = 1; private final int mType; @@ -78,15 +85,34 @@ public final class Icon implements Parcelable { // TYPE_DATA: data offset private int mInt2; - // Internal accessors for different mType variants - private Bitmap getBitmap() { + /** + * @return The type of image data held in this Icon. One of + * {@link #TYPE_BITMAP}, + * {@link #TYPE_RESOURCE}, + * {@link #TYPE_DATA}, or + * {@link #TYPE_URI}. + * @hide + */ + public int getType() { + return mType; + } + + /** + * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon. + * @hide + */ + public Bitmap getBitmap() { if (mType != TYPE_BITMAP) { throw new IllegalStateException("called getBitmap() on " + this); } return (Bitmap) mObj1; } - private int getDataLength() { + /** + * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon. + * @hide + */ + public int getDataLength() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataLength() on " + this); } @@ -95,7 +121,12 @@ public final class Icon implements Parcelable { } } - private int getDataOffset() { + /** + * @return The offset into the byte array held by this {@link #TYPE_DATA} Icon at which + * valid compressed bitmap data is found. + * @hide + */ + public int getDataOffset() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataOffset() on " + this); } @@ -104,7 +135,12 @@ public final class Icon implements Parcelable { } } - private byte[] getDataBytes() { + /** + * @return The byte array held by this {@link #TYPE_DATA} Icon ctonaining compressed + * bitmap data. + * @hide + */ + public byte[] getDataBytes() { if (mType != TYPE_DATA) { throw new IllegalStateException("called getDataBytes() on " + this); } @@ -113,39 +149,58 @@ public final class Icon implements Parcelable { } } - private Resources getResources() { + /** + * @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon. + * @hide + */ + public Resources getResources() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResources() on " + this); } return (Resources) mObj1; } - private String getResPackage() { + /** + * @return The package containing resources for this {@link #TYPE_RESOURCE} Icon. + * @hide + */ + public String getResPackage() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResPackage() on " + this); } return mString1; } - private int getResId() { + /** + * @return The resource ID for this {@link #TYPE_RESOURCE} Icon. + * @hide + */ + public int getResId() { if (mType != TYPE_RESOURCE) { throw new IllegalStateException("called getResId() on " + this); } return mInt1; } - private String getUriString() { + /** + * @return The URI (as a String) for this {@link #TYPE_URI} Icon. + * @hide + */ + public String getUriString() { if (mType != TYPE_URI) { throw new IllegalStateException("called getUriString() on " + this); } return mString1; } - private Uri getUri() { + /** + * @return The {@link android.net.Uri} for this {@link #TYPE_URI} Icon. + * @hide + */ + public Uri getUri() { return Uri.parse(getUriString()); } - // Convert a int32 into a four-char string private static final String typeToString(int x) { switch (x) { case TYPE_BITMAP: return "BITMAP"; @@ -281,16 +336,81 @@ public final class Icon implements Parcelable { return loadDrawable(context); } + /** + * Writes a serialized version of an Icon to the specified stream. + * + * @param stream The stream on which to serialize the Icon. + * @hide + */ + public void writeToStream(OutputStream stream) throws IOException { + DataOutputStream dataStream = new DataOutputStream(stream); + + dataStream.writeInt(VERSION_STREAM_SERIALIZER); + dataStream.writeByte(mType); + + switch (mType) { + case TYPE_BITMAP: + getBitmap().compress(Bitmap.CompressFormat.PNG, 100, dataStream); + break; + case TYPE_DATA: + dataStream.writeInt(getDataLength()); + dataStream.write(getDataBytes(), getDataOffset(), getDataLength()); + break; + case TYPE_RESOURCE: + dataStream.writeUTF(getResPackage()); + dataStream.writeInt(getResId()); + break; + case TYPE_URI: + dataStream.writeUTF(getUriString()); + break; + } + } + private Icon(int mType) { this.mType = mType; } /** + * Create an Icon from the specified stream. + * + * @param stream The input stream from which to reconstruct the Icon. + * @hide + */ + public static Icon createFromStream(InputStream stream) throws IOException { + DataInputStream inputStream = new DataInputStream(stream); + + final int version = inputStream.readInt(); + if (version >= VERSION_STREAM_SERIALIZER) { + final int type = inputStream.readByte(); + switch (type) { + case TYPE_BITMAP: + return createWithBitmap(BitmapFactory.decodeStream(inputStream)); + case TYPE_DATA: + final int length = inputStream.readInt(); + final byte[] data = new byte[length]; + inputStream.read(data, 0 /* offset */, length); + return createWithData(data, 0 /* offset */, length); + case TYPE_RESOURCE: + final String packageName = inputStream.readUTF(); + final int resId = inputStream.readInt(); + return createWithResource(packageName, resId); + case TYPE_URI: + final String uriOrPath = inputStream.readUTF(); + return createWithContentUri(uriOrPath); + } + } + return null; + } + + /** * Create an Icon pointing to a drawable resource. * @param res Resources for a package containing the resource in question * @param resId ID of the drawable resource */ public static Icon createWithResource(Resources res, @DrawableRes int resId) { + if (res == null) { + throw new IllegalArgumentException("Resource must not be null."); + } final Icon rep = new Icon(TYPE_RESOURCE); rep.mObj1 = res; rep.mInt1 = resId; @@ -304,6 +424,9 @@ public final class Icon implements Parcelable { * @param resId ID of the drawable resource */ public static Icon createWithResource(String resPackage, @DrawableRes int resId) { + if (resPackage == null) { + throw new IllegalArgumentException("Resource package name must not be null."); + } final Icon rep = new Icon(TYPE_RESOURCE); rep.mInt1 = resId; rep.mString1 = resPackage; @@ -315,6 +438,9 @@ public final class Icon implements Parcelable { * @param bits A valid {@link android.graphics.Bitmap} object */ public static Icon createWithBitmap(Bitmap bits) { + if (bits == null) { + throw new IllegalArgumentException("Bitmap must not be null."); + } final Icon rep = new Icon(TYPE_BITMAP); rep.mObj1 = bits; return rep; @@ -329,6 +455,9 @@ public final class Icon implements Parcelable { * @param length Length of the bitmap data */ public static Icon createWithData(byte[] data, int offset, int length) { + if (data == null) { + throw new IllegalArgumentException("Data must not be null."); + } final Icon rep = new Icon(TYPE_DATA); rep.mObj1 = data; rep.mInt1 = length; @@ -342,6 +471,9 @@ public final class Icon implements Parcelable { * @param uri A uri referring to local content:// or file:// image data. */ public static Icon createWithContentUri(String uri) { + if (uri == null) { + throw new IllegalArgumentException("Uri must not be null."); + } final Icon rep = new Icon(TYPE_URI); rep.mString1 = uri; return rep; @@ -353,6 +485,9 @@ public final class Icon implements Parcelable { * @param uri A uri referring to local content:// or file:// image data. */ public static Icon createWithContentUri(Uri uri) { + if (uri == null) { + throw new IllegalArgumentException("Uri must not be null."); + } final Icon rep = new Icon(TYPE_URI); rep.mString1 = uri.toString(); return rep; @@ -365,6 +500,9 @@ public final class Icon implements Parcelable { * a type that {@link android.graphics.BitmapFactory} can decode. */ public static Icon createWithFilePath(String path) { + if (path == null) { + throw new IllegalArgumentException("Path must not be null."); + } final Icon rep = new Icon(TYPE_URI); rep.mString1 = path; return rep; diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java index 566f8dc4ee50..4ecb930eeec8 100644 --- a/media/java/android/media/AudioDeviceInfo.java +++ b/media/java/android/media/AudioDeviceInfo.java @@ -16,6 +16,7 @@ package android.media; +import android.annotation.NonNull; import android.util.SparseIntArray; /** @@ -151,27 +152,38 @@ public final class AudioDeviceInfo { /** * @return An array of sample rates supported by the audio device. */ - public int[] getSampleRates() { + public @NonNull int[] getSampleRates() { return mPort.samplingRates(); } /** - * @return An array of channel masks ({@link AudioFormat#CHANNEL_IN_STEREO}, - * {@link AudioFormat#CHANNEL_OUT_7POINT1) for which this audio device can be configured. + * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO}, + * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured. * * @see AudioFormat */ - public int[] getChannelMasks() { + public @NonNull int[] getChannelMasks() { return mPort.channelMasks(); } /** - * @return An array of channel counts (1, 2, 4....) for which this audio device + * @return An array of channel index masks for which this audio device can be configured. + * + * @see AudioFormat + */ + public @NonNull int[] getChannelIndexMasks() { + // TODO: implement + return new int[0]; + } + + /** + * @return An array of channel counts (1, 2, 4, ...) for which this audio device * can be configured. */ - public int[] getChannelCounts() { + public @NonNull int[] getChannelCounts() { int[] masks = getChannelMasks(); int[] counts = new int[masks.length]; + // TODO: consider channel index masks for (int mask_index = 0; mask_index < masks.length; mask_index++) { counts[mask_index] = isSink() ? AudioFormat.channelCountFromOutChannelMask(masks[mask_index]) @@ -181,12 +193,16 @@ public final class AudioDeviceInfo { } /** - * @return An array of audio format IDs (@link AudioFormat#ENCODING_PCM_16BIT, - * {@link AudioFormat#ENCODING_PCM_FLOAT}...) supported by the audio device. + * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT}, + * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device. + * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more + * than 16 bits of integer precision. Specifying <code>ENCODING_PCM_FLOAT</code> + * with {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of + * integer precision to that device. * * @see AudioFormat */ - public int[] getFormats() { + public @NonNull int[] getFormats() { return mPort.formats(); } diff --git a/media/java/android/media/tv/DvbDeviceInfo.aidl b/media/java/android/media/tv/DvbDeviceInfo.aidl new file mode 100644 index 000000000000..48510503339b --- /dev/null +++ b/media/java/android/media/tv/DvbDeviceInfo.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 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.media.tv; + +parcelable DvbDeviceInfo;
\ No newline at end of file diff --git a/media/java/android/media/tv/DvbDeviceInfo.java b/media/java/android/media/tv/DvbDeviceInfo.java new file mode 100644 index 000000000000..1885a3453c60 --- /dev/null +++ b/media/java/android/media/tv/DvbDeviceInfo.java @@ -0,0 +1,97 @@ +/* + * 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.media.tv; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.media.tv.TvInputManager; +import android.util.Log; + +import java.lang.IllegalArgumentException; + +/** + * Simple container for information about DVB device. + * Not for third-party developers. + * + * @hide + */ +public final class DvbDeviceInfo implements Parcelable { + static final String TAG = "DvbDeviceInfo"; + + public static final Parcelable.Creator<DvbDeviceInfo> CREATOR = + new Parcelable.Creator<DvbDeviceInfo>() { + @Override + public DvbDeviceInfo createFromParcel(Parcel source) { + try { + return new DvbDeviceInfo(source); + } catch (Exception e) { + Log.e(TAG, "Exception creating DvbDeviceInfo from parcel", e); + return null; + } + } + + @Override + public DvbDeviceInfo[] newArray(int size) { + return new DvbDeviceInfo[size]; + } + }; + + private final int mAdapterId; + private final int mDeviceId; + + private DvbDeviceInfo(Parcel source) { + mAdapterId = source.readInt(); + mDeviceId = source.readInt(); + } + + /** + * Constructs a new {@link DvbDeviceInfo} with the given adapter ID and device ID. + */ + public DvbDeviceInfo(int adapterId, int deviceId) { + mAdapterId = adapterId; + mDeviceId = deviceId; + } + + /** + * Returns the adapter ID of DVB device, in terms of enumerating the DVB device adapters + * installed in the system. The adapter ID counts from zero. + */ + public int getAdapterId() { + return mAdapterId; + } + + /** + * Returns the device ID of DVB device, in terms of enumerating the DVB devices attached to + * the same device adapter. The device ID counts from zero. + */ + public int getDeviceId() { + return mDeviceId; + } + + // Parcelable + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mAdapterId); + dest.writeInt(mDeviceId); + } +} diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl index 078fb2fa946c..6fe5dbbc8a13 100644 --- a/media/java/android/media/tv/ITvInputManager.aidl +++ b/media/java/android/media/tv/ITvInputManager.aidl @@ -18,6 +18,7 @@ package android.media.tv; import android.content.ComponentName; import android.graphics.Rect; +import android.media.tv.DvbDeviceInfo; import android.media.tv.ITvInputClient; import android.media.tv.ITvInputHardware; import android.media.tv.ITvInputHardwareCallback; @@ -29,6 +30,7 @@ import android.media.tv.TvStreamConfig; import android.media.tv.TvTrackInfo; import android.net.Uri; import android.os.Bundle; +import android.os.ParcelFileDescriptor; import android.view.Surface; /** @@ -91,4 +93,8 @@ interface ITvInputManager { boolean captureFrame(in String inputId, in Surface surface, in TvStreamConfig config, int userId); boolean isSingleSessionActive(int userId); + + // For DVB device binding + List<DvbDeviceInfo> getDvbDeviceList(); + ParcelFileDescriptor openDvbDevice(in DvbDeviceInfo info, int device); } diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 705aa3d646bd..e74860ee9285 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -21,12 +21,14 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.graphics.Rect; import android.media.MediaPlayer; +import android.media.tv.DvbDeviceInfo; 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.ParcelFileDescriptor; import android.os.RemoteException; import android.util.ArrayMap; import android.util.Log; @@ -42,6 +44,7 @@ import android.view.View; import com.android.internal.util.Preconditions; +import java.lang.IllegalArgumentException; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; @@ -55,6 +58,25 @@ import java.util.Map; public final class TvInputManager { private static final String TAG = "TvInputManager"; + static final int DVB_DEVICE_START = 0; + static final int DVB_DEVICE_END = 2; + + /** + * A demux device of DVB API for controlling the filters of DVB hardware/software. + * @hide + */ + public static final int DVB_DEVICE_DEMUX = DVB_DEVICE_START; + /** + * A DVR device of DVB API for reading transport streams. + * @hide + */ + public static final int DVB_DEVICE_DVR = 1; + /** + * A frontend device of DVB API for controlling the tuner and DVB demodulator hardware. + * @hide + */ + public static final int DVB_DEVICE_FRONTEND = DVB_DEVICE_END; + static final int VIDEO_UNAVAILABLE_REASON_START = 0; static final int VIDEO_UNAVAILABLE_REASON_END = 4; @@ -1258,6 +1280,43 @@ public final class TvInputManager { } /** + * Returns the list of currently available DVB devices on the system. + * + * @return the list of {@link DvbDeviceInfo} objects representing available DVB devices. + * @hide + */ + public List<DvbDeviceInfo> getDvbDeviceList() { + try { + return mService.getDvbDeviceList(); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns a {@link ParcelFileDescriptor} of a specified DVB device for a given + * {@link DvbDeviceInfo} + * + * @param info A {@link DvbDeviceInfo} to open a DVB device. + * @param device A DVB device. The DVB device can be {@link DVB_DEVICE_DEMUX}, + * {@link DVB_DEVICE_DVR} or {@link DVB_DEVICE_FRONTEND}. + * @return a {@link ParcelFileDescriptor} of a specified DVB device for a given + * {@link DvbDeviceInfo}, or {@code null} if the given {@link DvbDeviceInfo} was + * invalid or the specified DVB device was busy with a previous request. + * @hide + */ + public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device) { + try { + if (DVB_DEVICE_START > device || DVB_DEVICE_END < device) { + throw new IllegalArgumentException("Invalid DVB device: " + device); + } + return mService.openDvbDevice(info, device); + } catch (RemoteException e) { + throw new RuntimeException(e); + } + } + + /** * The Session provides the per-session functionality of TV inputs. * @hide */ diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp index 84ae3b4fa8d5..6c1bd972ccc6 100644 --- a/media/jni/soundpool/SoundPool.cpp +++ b/media/jni/soundpool/SoundPool.cpp @@ -738,12 +738,16 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV // do not create a new audio track if current track is compatible with sample parameters #ifdef USE_SHARED_MEM_BUFFER newTrack = new AudioTrack(streamType, sampleRate, sample->format(), - channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); + channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData, + 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE, + AudioTrack::TRANSFER_DEFAULT, + NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); #else uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; newTrack = new AudioTrack(streamType, sampleRate, sample->format(), channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, - bufferFrames); + bufferFrames, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT, + NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); #endif oldTrack = mAudioTrack; status = newTrack->initCheck(); diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index b702e3508d0b..377a9a4b8e76 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -48,6 +48,8 @@ <string name="wifi_security_psk_generic">@string/wifi_security_wpa_wpa2</string> <!-- Do not translate. Concise terminology for wifi with 802.1x EAP security --> <string name="wifi_security_eap">802.1x EAP</string> + <!-- Do not translate. Concise terminology for Passpoint network --> + <string name="wifi_security_passpoint">Passpoint</string> <!-- Summary for the remembered network. --> <string name="wifi_remembered">Saved</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java index 1ad7a51ba921..7049d6ab6668 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java @@ -248,6 +248,9 @@ public class AccessPoint implements Comparable<AccessPoint> { public String getSecurityString(boolean concise) { Context context = mContext; + if (mConfig != null && mConfig.isPasspoint()) { + return context.getString(R.string.wifi_security_passpoint); + } switch(security) { case SECURITY_EAP: return concise ? context.getString(R.string.wifi_security_short_eap) : diff --git a/packages/SettingsProvider/res/values-gu-rIN/defaults.xml b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml new file mode 100644 index 000000000000..22443a5673ea --- /dev/null +++ b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright (c) 2009, 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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string> + <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string> +</resources> diff --git a/packages/SettingsProvider/res/values-gu-rIN/strings.xml b/packages/SettingsProvider/res/values-gu-rIN/strings.xml new file mode 100644 index 000000000000..72419749c36a --- /dev/null +++ b/packages/SettingsProvider/res/values-gu-rIN/strings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright (c) 2007, 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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4567566098528588863">"સેટિંગ્સ સંગ્રહ"</string> +</resources> diff --git a/packages/SettingsProvider/res/values-sq-rAL/strings.xml b/packages/SettingsProvider/res/values-sq-rAL/strings.xml new file mode 100644 index 000000000000..a8e66d5dae80 --- /dev/null +++ b/packages/SettingsProvider/res/values-sq-rAL/strings.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright (c) 2007, 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 xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4567566098528588863">"Hapësira ruajtëse e \"Cilësimeve\""</string> +</resources> diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml index a2541922bf28..6a5358b7616c 100644 --- a/packages/Shell/res/values-hy-rAM/strings.xml +++ b/packages/Shell/res/values-hy-rAM/strings.xml @@ -17,7 +17,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_label" msgid="3701846017049540910">"Խեցի"</string> - <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց ստացվեց"</string> + <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց է ստացվել"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string> <string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string> diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 715f4e443d21..be33085f68eb 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -194,7 +194,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi // we compose the final post-save notification below. mNotificationBuilder.setLargeIcon(croppedIcon); // But we still don't set it for the expanded view, allowing the smallIcon to show here. - mNotificationStyle.bigLargeIcon(null); + mNotificationStyle.bigLargeIcon((Bitmap) null); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 2913c7df1f78..1e488f39ee57 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -1390,9 +1390,9 @@ public abstract class BaseStatusBar extends SystemUI implements final ImageView profileBadge = (ImageView) publicViewLocal.findViewById( R.id.profile_badge_line3); - final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( entry.notification.getUser(), - entry.notification.getNotification().icon, + entry.notification.getNotification().getSmallIcon(), entry.notification.getNotification().iconLevel, entry.notification.getNotification().number, entry.notification.getNotification().tickerText); @@ -1770,9 +1770,9 @@ public abstract class BaseStatusBar extends SystemUI implements sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n); iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); - final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( sbn.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); @@ -1916,9 +1916,9 @@ public abstract class BaseStatusBar extends SystemUI implements try { if (entry.icon != null) { // Update the icon - final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); @@ -1938,9 +1938,9 @@ public abstract class BaseStatusBar extends SystemUI implements } if (!updateSuccessful) { if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key); - final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(), + final StatusBarIcon ic = new StatusBarIcon( notification.getUser(), - n.icon, + n.getSmallIcon(), n.iconLevel, n.number, n.tickerText); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index e6847d8ce5e2..3294e15ab3a5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -24,6 +24,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; @@ -100,13 +101,23 @@ public class StatusBarIconView extends AnimatedImageView { return a.equals(b); } + public boolean equalIcons(Icon a, Icon b) { + if (a == b) return true; + if (a.getType() != b.getType()) return false; + switch (a.getType()) { + case Icon.TYPE_RESOURCE: + return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId(); + case Icon.TYPE_URI: + return a.getUriString().equals(b.getUriString()); + default: + return false; + } + } /** * Returns whether the set succeeded. */ public boolean set(StatusBarIcon icon) { - final boolean iconEquals = mIcon != null - && streq(mIcon.iconPackage, icon.iconPackage) - && mIcon.iconId == icon.iconId; + final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon); final boolean levelEquals = iconEquals && mIcon.iconLevel == icon.iconLevel; final boolean visibilityEquals = mIcon != null @@ -167,45 +178,18 @@ public class StatusBarIconView extends AnimatedImageView { } /** - * Returns the right icon to use for this item, respecting the iconId and - * iconPackage (if set) + * Returns the right icon to use for this item * - * @param context Context to use to get resources if iconPackage is not set + * @param context Context to use to get resources * @return Drawable for this item, or null if the package or item could not * be found */ public static Drawable getIcon(Context context, StatusBarIcon icon) { - Resources r = null; - - if (icon.iconPackage != null) { - try { - int userId = icon.user.getIdentifier(); - if (userId == UserHandle.USER_ALL) { - userId = UserHandle.USER_OWNER; - } - r = context.getPackageManager() - .getResourcesForApplicationAsUser(icon.iconPackage, userId); - } catch (PackageManager.NameNotFoundException ex) { - Log.e(TAG, "Icon package not found: " + icon.iconPackage); - return null; - } - } else { - r = context.getResources(); + int userId = icon.user.getIdentifier(); + if (userId == UserHandle.USER_ALL) { + userId = UserHandle.USER_OWNER; } - - if (icon.iconId == 0) { - return null; - } - - try { - return r.getDrawable(icon.iconId); - } catch (RuntimeException e) { - Log.w(TAG, "Icon not found in " - + (icon.iconPackage != null ? icon.iconId : "<system>") - + ": " + Integer.toHexString(icon.iconId)); - } - - return null; + return icon.icon.loadDrawableAsUser(context, userId); } public StatusBarIcon getStatusBarIcon() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 44168bc71383..26d1c867ab08 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.phone; +import android.graphics.drawable.Icon; import android.os.Bundle; import android.os.UserHandle; import android.view.Gravity; @@ -132,8 +133,7 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { break; } else { StatusBarIcon icon = v.getStatusBarIcon(); - icon.iconPackage = iconPkg; - icon.iconId = iconId; + icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId); v.set(icon); v.updateDrawable(); return; @@ -152,4 +152,4 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode { v.set(icon); addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize)); } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java index 080665aaadc1..0462035041ef 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java @@ -34,6 +34,8 @@ import android.view.SurfaceControl; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,6 +49,21 @@ import java.util.regex.Pattern; * service as usual. The UI handler is only used by the {@link OverlayDisplayWindow}. * </p><p> * Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock. + * </p><p> + * This adapter is configured via the + * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be + * formatted as follows: + * <pre> + * [mode1]|[mode2]|...,[flag1],[flag2],... + * </pre> + * with each mode specified as: + * <pre> + * [width]x[height]/[densityDpi] + * </pre> + * Supported flags: + * <ul> + * <li><pre>secure</pre>: creates a secure display</li> + * </ul> * </p> */ final class OverlayDisplayAdapter extends DisplayAdapter { @@ -58,8 +75,10 @@ final class OverlayDisplayAdapter extends DisplayAdapter { private static final int MAX_WIDTH = 4096; private static final int MAX_HEIGHT = 4096; - private static final Pattern SETTING_PATTERN = - Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*"); + private static final Pattern DISPLAY_PATTERN = + Pattern.compile("([^,]+)(,[a-z]+)*"); + private static final Pattern MODE_PATTERN = + Pattern.compile("(\\d+)x(\\d+)/(\\d+)"); // Unique id prefix for overlay displays. private static final String UNIQUE_ID_PREFIX = "overlay:"; @@ -136,40 +155,49 @@ final class OverlayDisplayAdapter extends DisplayAdapter { int count = 0; for (String part : value.split(";")) { - Matcher matcher = SETTING_PATTERN.matcher(part); - if (matcher.matches()) { + Matcher displayMatcher = DISPLAY_PATTERN.matcher(part); + if (displayMatcher.matches()) { if (count >= 4) { Slog.w(TAG, "Too many overlay display devices specified: " + value); break; } - try { - int width = Integer.parseInt(matcher.group(1), 10); - int height = Integer.parseInt(matcher.group(2), 10); - int densityDpi = Integer.parseInt(matcher.group(3), 10); - String flagString = matcher.group(4); - if (width >= MIN_WIDTH && width <= MAX_WIDTH - && height >= MIN_HEIGHT && height <= MAX_HEIGHT - && densityDpi >= DisplayMetrics.DENSITY_LOW - && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) { - int number = ++count; - String name = getContext().getResources().getString( - com.android.internal.R.string.display_manager_overlay_display_name, - number); - int gravity = chooseOverlayGravity(number); - boolean secure = flagString != null && flagString.contains(",secure"); - - Slog.i(TAG, "Showing overlay display device #" + number - + ": name=" + name + ", width=" + width + ", height=" + height - + ", densityDpi=" + densityDpi + ", secure=" + secure); - - mOverlays.add(new OverlayDisplayHandle(name, - width, height, densityDpi, gravity, secure, number)); + String modeString = displayMatcher.group(1); + String flagString = displayMatcher.group(2); + ArrayList<OverlayMode> modes = new ArrayList<>(); + for (String mode : modeString.split("\\|")) { + Matcher modeMatcher = MODE_PATTERN.matcher(mode); + if (modeMatcher.matches()) { + try { + int width = Integer.parseInt(modeMatcher.group(1), 10); + int height = Integer.parseInt(modeMatcher.group(2), 10); + int densityDpi = Integer.parseInt(modeMatcher.group(3), 10); + if (width >= MIN_WIDTH && width <= MAX_WIDTH + && height >= MIN_HEIGHT && height <= MAX_HEIGHT + && densityDpi >= DisplayMetrics.DENSITY_LOW + && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) { + modes.add(new OverlayMode(width, height, densityDpi)); + continue; + } + } catch (NumberFormatException ex) { + } + } else if (mode.isEmpty()) { continue; } - } catch (NumberFormatException ex) { } - } else if (part.isEmpty()) { - continue; + if (!modes.isEmpty()) { + int number = ++count; + String name = getContext().getResources().getString( + com.android.internal.R.string.display_manager_overlay_display_name, + number); + int gravity = chooseOverlayGravity(number); + boolean secure = flagString != null && flagString.contains(",secure"); + + Slog.i(TAG, "Showing overlay display device #" + number + + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray())); + + mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number)); + continue; + } } Slog.w(TAG, "Malformed overlay display devices setting: " + value); } @@ -189,36 +217,41 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } } - private final class OverlayDisplayDevice extends DisplayDevice { + private abstract class OverlayDisplayDevice extends DisplayDevice { private final String mName; - private final int mWidth; - private final int mHeight; private final float mRefreshRate; private final long mDisplayPresentationDeadlineNanos; - private final int mDensityDpi; private final boolean mSecure; - private final Display.Mode mMode; + private final List<OverlayMode> mRawModes; + private final Display.Mode[] mModes; + private final int mDefaultMode; private int mState; private SurfaceTexture mSurfaceTexture; private Surface mSurface; private DisplayDeviceInfo mInfo; + private int mActiveMode; public OverlayDisplayDevice(IBinder displayToken, String name, - int width, int height, float refreshRate, long presentationDeadlineNanos, - int densityDpi, boolean secure, int state, + List<OverlayMode> modes, int activeMode, int defaultMode, + float refreshRate, long presentationDeadlineNanos, + boolean secure, int state, SurfaceTexture surfaceTexture, int number) { super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number); mName = name; - mWidth = width; - mHeight = height; mRefreshRate = refreshRate; mDisplayPresentationDeadlineNanos = presentationDeadlineNanos; - mDensityDpi = densityDpi; mSecure = secure; mState = state; mSurfaceTexture = surfaceTexture; - mMode = createMode(width, height, refreshRate); + mRawModes = modes; + mModes = new Display.Mode[modes.size()]; + for (int i = 0; i < modes.size(); i++) { + OverlayMode mode = modes.get(i); + mModes[i] = createMode(mode.mWidth, mode.mHeight, refreshRate); + } + mActiveMode = activeMode; + mDefaultMode = defaultMode; } public void destroyLocked() { @@ -248,17 +281,19 @@ final class OverlayDisplayAdapter extends DisplayAdapter { @Override public DisplayDeviceInfo getDisplayDeviceInfoLocked() { if (mInfo == null) { + Display.Mode mode = mModes[mActiveMode]; + OverlayMode rawMode = mRawModes.get(mActiveMode); mInfo = new DisplayDeviceInfo(); mInfo.name = mName; mInfo.uniqueId = getUniqueId(); - mInfo.width = mWidth; - mInfo.height = mHeight; - mInfo.modeId = mMode.getModeId(); - mInfo.defaultModeId = mMode.getModeId(); - mInfo.supportedModes = new Display.Mode[] { mMode }; - mInfo.densityDpi = mDensityDpi; - mInfo.xDpi = mDensityDpi; - mInfo.yDpi = mDensityDpi; + mInfo.width = mode.getPhysicalWidth(); + mInfo.height = mode.getPhysicalHeight(); + mInfo.modeId = mode.getModeId(); + mInfo.defaultModeId = mModes[0].getModeId(); + mInfo.supportedModes = mModes; + mInfo.densityDpi = rawMode.mDensityDpi; + mInfo.xDpi = rawMode.mDensityDpi; + mInfo.yDpi = rawMode.mDensityDpi; mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos + 1000000000L / (int) mRefreshRate; // display's deadline + 1 frame mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION; @@ -271,6 +306,40 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } return mInfo; } + + @Override + public void requestModeInTransactionLocked(int id) { + int index = -1; + if (id == 0) { + // Use the default. + index = 0; + } else { + for (int i = 0; i < mModes.length; i++) { + if (mModes[i].getModeId() == id) { + index = i; + break; + } + } + } + if (index == -1) { + Slog.w(TAG, "Unable to locate mode " + id + ", reverting to default."); + index = mDefaultMode; + } + if (mActiveMode == index) { + return; + } + mActiveMode = index; + mInfo = null; + sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED); + onModeChangedLocked(index); + } + + /** + * Called when the device switched to a new mode. + * + * @param index index of the mode in the list of modes + */ + public abstract void onModeChangedLocked(int index); } /** @@ -280,27 +349,32 @@ final class OverlayDisplayAdapter extends DisplayAdapter { * Guarded by the {@link DisplayManagerService.SyncRoot} lock. */ private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener { + private static final int DEFAULT_MODE_INDEX = 0; + private final String mName; - private final int mWidth; - private final int mHeight; - private final int mDensityDpi; + private final List<OverlayMode> mModes; private final int mGravity; private final boolean mSecure; private final int mNumber; private OverlayDisplayWindow mWindow; private OverlayDisplayDevice mDevice; + private int mActiveMode; - public OverlayDisplayHandle(String name, int width, - int height, int densityDpi, int gravity, boolean secure, int number) { + public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity, + boolean secure, int number) { mName = name; - mWidth = width; - mHeight = height; - mDensityDpi = densityDpi; + mModes = modes; mGravity = gravity; mSecure = secure; mNumber = number; + mActiveMode = 0; + + showLocked(); + } + + private void showLocked() { mUiHandler.post(mShowRunnable); } @@ -309,15 +383,28 @@ final class OverlayDisplayAdapter extends DisplayAdapter { mUiHandler.post(mDismissRunnable); } + private void onActiveModeChangedLocked(int index) { + mUiHandler.removeCallbacks(mResizeRunnable); + mActiveMode = index; + if (mWindow != null) { + mUiHandler.post(mResizeRunnable); + } + } + // Called on the UI thread. @Override public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate, long presentationDeadlineNanos, int state) { synchronized (getSyncRoot()) { IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure); - mDevice = new OverlayDisplayDevice(displayToken, mName, - mWidth, mHeight, refreshRate, presentationDeadlineNanos, - mDensityDpi, mSecure, state, surfaceTexture, mNumber); + mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode, + DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos, + mSecure, state, surfaceTexture, mNumber) { + @Override + public void onModeChangedLocked(int index) { + onActiveModeChangedLocked(index); + } + }; sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED); } @@ -347,9 +434,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter { public void dumpLocked(PrintWriter pw) { pw.println(" " + mName + ":"); - pw.println(" mWidth=" + mWidth); - pw.println(" mHeight=" + mHeight); - pw.println(" mDensityDpi=" + mDensityDpi); + pw.println(" mModes=" + Arrays.toString(mModes.toArray())); + pw.println(" mActiveMode=" + mActiveMode); pw.println(" mGravity=" + mGravity); pw.println(" mSecure=" + mSecure); pw.println(" mNumber=" + mNumber); @@ -366,8 +452,9 @@ final class OverlayDisplayAdapter extends DisplayAdapter { private final Runnable mShowRunnable = new Runnable() { @Override public void run() { + OverlayMode mode = mModes.get(mActiveMode); OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(), - mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure, + mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure, OverlayDisplayHandle.this); window.show(); @@ -392,5 +479,47 @@ final class OverlayDisplayAdapter extends DisplayAdapter { } } }; + + // Runs on the UI thread. + private final Runnable mResizeRunnable = new Runnable() { + @Override + public void run() { + OverlayMode mode; + OverlayDisplayWindow window; + synchronized (getSyncRoot()) { + if (mWindow == null) { + return; + } + mode = mModes.get(mActiveMode); + window = mWindow; + } + window.resize(mode.mWidth, mode.mHeight, mode.mDensityDpi); + } + }; + } + + /** + * A display mode for an overlay display. + */ + private static final class OverlayMode { + final int mWidth; + final int mHeight; + final int mDensityDpi; + + OverlayMode(int width, int height, int densityDpi) { + mWidth = width; + mHeight = height; + mDensityDpi = densityDpi; + } + + @Override + public String toString() { + return new StringBuilder("{") + .append("width=").append(mWidth) + .append(", height=").append(mHeight) + .append(", densityDpi=").append(mDensityDpi) + .append("}") + .toString(); + } } } diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java index 786889ae5b0b..f23caf2e7a76 100644 --- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java +++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java @@ -60,9 +60,9 @@ final class OverlayDisplayWindow implements DumpUtils.Dump { private final Context mContext; private final String mName; - private final int mWidth; - private final int mHeight; - private final int mDensityDpi; + private int mWidth; + private int mHeight; + private int mDensityDpi; private final int mGravity; private final boolean mSecure; private final Listener mListener; @@ -97,19 +97,9 @@ final class OverlayDisplayWindow implements DumpUtils.Dump { Listener listener) { mContext = context; mName = name; - mWidth = width; - mHeight = height; - mDensityDpi = densityDpi; mGravity = gravity; mSecure = secure; mListener = listener; - mTitle = context.getResources().getString( - com.android.internal.R.string.display_manager_overlay_display_title, - mName, mWidth, mHeight, mDensityDpi); - if (secure) { - mTitle += context.getResources().getString( - com.android.internal.R.string.display_manager_overlay_display_secure_suffix); - } mDisplayManager = (DisplayManager)context.getSystemService( Context.DISPLAY_SERVICE); @@ -119,6 +109,8 @@ final class OverlayDisplayWindow implements DumpUtils.Dump { mDefaultDisplay = mWindowManager.getDefaultDisplay(); updateDefaultDisplayInfo(); + resize(width, height, densityDpi, false /* doLayout */); + createWindow(); } @@ -145,6 +137,26 @@ final class OverlayDisplayWindow implements DumpUtils.Dump { } } + public void resize(int width, int height, int densityDpi) { + resize(width, height, densityDpi, true /* doLayout */); + } + + private void resize(int width, int height, int densityDpi, boolean doLayout) { + mWidth = width; + mHeight = height; + mDensityDpi = densityDpi; + mTitle = mContext.getResources().getString( + com.android.internal.R.string.display_manager_overlay_display_title, + mName, mWidth, mHeight, mDensityDpi); + if (mSecure) { + mTitle += mContext.getResources().getString( + com.android.internal.R.string.display_manager_overlay_display_secure_suffix); + } + if (doLayout) { + relayout(); + } + } + public void relayout() { if (mWindowVisible) { updateWindowParams(); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 290fb6579efd..de74a044d3fd 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -2017,7 +2017,7 @@ public class NotificationManagerService extends SystemService { throw new IllegalArgumentException("null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification); } - if (notification.icon != 0) { + if (notification.getSmallIcon() != null) { if (!notification.isValid()) { throw new IllegalArgumentException("Invalid notification (): pkg=" + pkg + " id=" + id + " notification=" + notification); @@ -2138,11 +2138,11 @@ public class NotificationManagerService extends SystemService { applyZenModeLocked(r); mRankingHelper.sort(mNotificationList); - if (notification.icon != 0) { + if (notification.getSmallIcon() != null) { StatusBarNotification oldSbn = (old != null) ? old.sbn : null; mListeners.notifyPostedLocked(n, oldSbn); } else { - Slog.e(TAG, "Not posting notification with icon==0: " + notification); + Slog.e(TAG, "Not posting notification without small icon: " + notification); if (old != null && !old.isCanceled) { mListeners.notifyRemovedLocked(n); } @@ -2715,7 +2715,7 @@ public class NotificationManagerService extends SystemService { } // status bar - if (r.getNotification().icon != 0) { + if (r.getNotification().getSmallIcon() != null) { r.isCanceled = true; mListeners.notifyRemovedLocked(r.sbn); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 19210c9f8c54..145786f1ef72 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4137,7 +4137,9 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { final int count = candidates.size(); - // First, try to use the domain prefered App + // First, try to use the domain prefered App. Partition the candidates into four lists: + // one for the final results, one for the "do not use ever", one for "undefined status" + // and finally one for "Browser App type". for (int n=0; n<count; n++) { ResolveInfo info = candidates.get(n); String packageName = info.activityInfo.packageName; @@ -4159,19 +4161,19 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + // Add all undefined Apps as we want them to appear in the Disambiguation dialog. + result.addAll(undefinedList); // If there is nothing selected, add all candidates and remove the ones that the User // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and - // also remove any undefined ones and Browser Apps ones. - // If there is still none after this pass, add all undefined one and Browser Apps and + // also remove Browser Apps ones. + // If there is still none after this pass, add all Browser Apps and // let the User decide with the Disambiguation dialog if there are several ones. if (result.size() == 0) { result.addAll(candidates); } result.removeAll(neverList); result.removeAll(matchAllList); - result.removeAll(undefinedList); if (result.size() == 0) { - result.addAll(undefinedList); if ((flags & MATCH_ALL) != 0) { result.addAll(matchAllList); } else { @@ -11459,6 +11461,21 @@ public class PackageManagerService extends IPackageManager.Stub { replace = true; if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName); } + + // Prevent apps opting out from runtime permissions + if (replace) { + PackageParser.Package oldPackage = mPackages.get(pkgName); + final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion; + final int newTargetSdk = pkg.applicationInfo.targetSdkVersion; + if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1 + && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) { + res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE, + "Package " + pkg.packageName + " new target SDK " + newTargetSdk + + " doesn't support runtime permissions but the old" + + " target SDK " + oldTargetSdk + " does."); + return; + } + } } PackageSetting ps = mSettings.mPackages.get(pkgName); diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java index e649e4847281..a869c206bc4e 100644 --- a/services/core/java/com/android/server/tv/TvInputManagerService.java +++ b/services/core/java/com/android/server/tv/TvInputManagerService.java @@ -39,6 +39,7 @@ import android.content.pm.ServiceInfo; import android.graphics.Rect; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiDeviceInfo; +import android.media.tv.DvbDeviceInfo; import android.media.tv.ITvInputClient; import android.media.tv.ITvInputHardware; import android.media.tv.ITvInputHardwareCallback; @@ -64,6 +65,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; @@ -80,23 +82,34 @@ import com.android.server.SystemService; import org.xmlpull.v1.XmlPullParserException; +import java.io.File; import java.io.FileDescriptor; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; +import java.lang.IllegalArgumentException; +import java.lang.Integer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** This class provides a system service that manages television inputs. */ public final class TvInputManagerService extends SystemService { private static final boolean DEBUG = false; private static final String TAG = "TvInputManagerService"; + // Pattern for selecting the DVB frontend devices from the list of files in the /dev directory. + private static final Pattern sFrontEndDevicePattern = + Pattern.compile("^dvb([0-9]+)\\.frontend([0-9]+)$"); + private final Context mContext; private final TvInputHardwareManager mTvInputHardwareManager; @@ -1507,6 +1520,74 @@ public final class TvInputManagerService extends SystemService { } @Override + public List<DvbDeviceInfo> getDvbDeviceList() throws RemoteException { + if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires DVB_DEVICE permission"); + } + + final long identity = Binder.clearCallingIdentity(); + try { + ArrayList<DvbDeviceInfo> deviceInfos = new ArrayList<>(); + File devDirectory = new File("/dev"); + for (String fileName : devDirectory.list()) { + Matcher matcher = sFrontEndDevicePattern.matcher(fileName); + if (matcher.find()) { + int adapterId = Integer.parseInt(matcher.group(1)); + int deviceId = Integer.parseInt(matcher.group(2)); + deviceInfos.add(new DvbDeviceInfo(adapterId, deviceId)); + } + } + return Collections.unmodifiableList(deviceInfos); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override + public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device) + throws RemoteException { + if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires DVB_DEVICE permission"); + } + + final long identity = Binder.clearCallingIdentity(); + try { + String deviceFileName; + switch (device) { + case TvInputManager.DVB_DEVICE_DEMUX: + deviceFileName = String.format("/dev/dvb%d.demux%d", info.getAdapterId(), + info.getDeviceId()); + break; + case TvInputManager.DVB_DEVICE_DVR: + deviceFileName = String.format("/dev/dvb%d.dvr%d", info.getAdapterId(), + info.getDeviceId()); + break; + case TvInputManager.DVB_DEVICE_FRONTEND: + deviceFileName = String.format("/dev/dvb%d.frontend%d", info.getAdapterId(), + info.getDeviceId()); + break; + default: + throw new IllegalArgumentException("Invalid DVB device: " + device); + } + try { + // The DVB frontend device only needs to be opened in read/write mode, which + // allows performing tuning operations. The DVB demux and DVR device are enough + // to be opened in read only mode. + return ParcelFileDescriptor.open(new File(deviceFileName), + TvInputManager.DVB_DEVICE_FRONTEND == device + ? ParcelFileDescriptor.MODE_READ_WRITE + : ParcelFileDescriptor.MODE_READ_ONLY); + } catch (FileNotFoundException e) { + return null; + } + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int userId) throws RemoteException { if (mContext.checkCallingPermission( diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 9033c9cd26ec..0357de270d87 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -289,11 +289,13 @@ public class AppTransition implements Dump { return mNextAppTransitionStartY; } - void prepare() { + boolean prepare() { if (!isRunning()) { mAppTransitionState = APP_STATE_IDLE; notifyAppTransitionPendingLocked(); + return true; } + return false; } void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) { @@ -953,8 +955,8 @@ public class AppTransition implements Dump { : com.android.internal.R.anim.voice_activity_open_exit); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation voice:" - + " anim=" + a + " transit=" + transit + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); + + " anim=" + a + " transit=" + appTransitionToString(transit) + + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE || transit == TRANSIT_TASK_CLOSE || transit == TRANSIT_TASK_TO_BACK)) { @@ -963,22 +965,23 @@ public class AppTransition implements Dump { : com.android.internal.R.anim.voice_activity_close_exit); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation voice:" - + " anim=" + a + " transit=" + transit + " isEntrance=" + enter - + " Callers=" + Debug.getCallers(3)); + + " anim=" + a + " transit=" + appTransitionToString(transit) + + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { a = loadAnimationRes(mNextAppTransitionPackage, enter ? mNextAppTransitionEnter : mNextAppTransitionExit); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=ANIM_CUSTOM" - + " transit=" + transit + " isEntrance=" + enter + + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) { a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" - + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE" - + " transit=" + transit + " Callers=" + Debug.getCallers(3)); + + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE" + + " transit=" + appTransitionToString(transit) + + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) { a = createClipRevealAnimationLocked(transit, enter, appFrame); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, @@ -990,7 +993,7 @@ public class AppTransition implements Dump { if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP" - + " transit=" + transit + " isEntrance=" + enter + + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP || mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) { @@ -1003,7 +1006,7 @@ public class AppTransition implements Dump { "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN"; Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=" + animName - + " transit=" + transit + " isEntrance=" + enter + + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP || @@ -1018,7 +1021,7 @@ public class AppTransition implements Dump { "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN"; Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=" + animName - + " transit=" + transit + " isEntrance=" + enter + + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } } else { @@ -1084,7 +1087,7 @@ public class AppTransition implements Dump { "applyAnimation:" + " anim=" + a + " animAttr=0x" + Integer.toHexString(animAttr) - + " transit=" + transit + " isEntrance=" + enter + + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3)); } return a; @@ -1188,7 +1191,7 @@ public class AppTransition implements Dump { @Override public String toString() { - return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition); + return "mNextAppTransition=" + appTransitionToString(mNextAppTransition); } /** diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java index 21011e894bdf..3feec8209ed0 100644 --- a/services/core/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java @@ -16,6 +16,11 @@ package com.android.server.wm; +import static com.android.server.wm.WindowManagerService.DEBUG_ANIM; +import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS; +import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS; +import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET; + import android.graphics.Matrix; import android.util.Slog; import android.util.TimeUtils; @@ -78,7 +83,11 @@ public class AppWindowAnimator { boolean deferFinalFrameCleanup; /** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */ - ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>(); + ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>(); + + /** True if the current animation was transferred from another AppWindowAnimator. + * See {@link #transferCurrentAnimation}*/ + boolean usingTransferredAnimation = false; static final Animation sDummyAnimation = new DummyAnimation(); @@ -102,9 +111,9 @@ public class AppWindowAnimator { int zorder = anim.getZAdjustment(); int adj = 0; if (zorder == Animation.ZORDER_TOP) { - adj = WindowManagerService.TYPE_LAYER_OFFSET; + adj = TYPE_LAYER_OFFSET; } else if (zorder == Animation.ZORDER_BOTTOM) { - adj = -WindowManagerService.TYPE_LAYER_OFFSET; + adj = -TYPE_LAYER_OFFSET; } if (animLayerAdjustment != adj) { @@ -140,6 +149,7 @@ public class AppWindowAnimator { mAppToken.allDrawn = false; mAppToken.deferClearAllDrawn = false; } + usingTransferredAnimation = false; } public boolean isAnimating() { @@ -154,19 +164,38 @@ public class AppWindowAnimator { deferThumbnailDestruction = false; } + void transferCurrentAnimation( + AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) { + + if (animation != null) { + toAppAnimator.animation = animation; + animation = null; + toAppAnimator.animating = animating; + toAppAnimator.animLayerAdjustment = animLayerAdjustment; + animLayerAdjustment = 0; + toAppAnimator.updateLayers(); + updateLayers(); + toAppAnimator.usingTransferredAnimation = true; + } + if (transferWinAnimator != null) { + mAllAppWinAnimators.remove(transferWinAnimator); + toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator); + transferWinAnimator.mAppAnimator = toAppAnimator; + } + } + void updateLayers() { - final int N = mAppToken.allAppWindows.size(); + final int windowCount = mAppToken.allAppWindows.size(); final int adj = animLayerAdjustment; thumbnailLayer = -1; - for (int i=0; i<N; i++) { + for (int i = 0; i < windowCount; i++) { final WindowState w = mAppToken.allAppWindows.get(i); final WindowStateAnimator winAnimator = w.mWinAnimator; winAnimator.mAnimLayer = w.mLayer + adj; if (winAnimator.mAnimLayer > thumbnailLayer) { thumbnailLayer = winAnimator.mAnimLayer; } - if (WindowManagerService.DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " - + winAnimator.mAnimLayer); + if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer); if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) { mService.setInputMethodAnimLayerAdjustment(adj); } @@ -191,11 +220,11 @@ public class AppWindowAnimator { // cache often used attributes locally final float tmpFloats[] = mService.mTmpFloats; thumbnailTransformation.getMatrix().getValues(tmpFloats); - if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail, + if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail, "thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X] + ", " + tmpFloats[Matrix.MTRANS_Y], null); thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]); - if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail, + if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail, "thumbnail", "alpha=" + thumbnailTransformation.getAlpha() + " layer=" + thumbnailLayer + " matrix=[" + tmpFloats[Matrix.MSCALE_X] @@ -228,14 +257,14 @@ public class AppWindowAnimator { deferFinalFrameCleanup = true; hasMoreFrames = true; } else { - if (false && WindowManagerService.DEBUG_ANIM) Slog.v( - TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames + - ", xform=" + transformation); + if (false && DEBUG_ANIM) Slog.v(TAG, + "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames + + ", xform=" + transformation); deferFinalFrameCleanup = false; animation = null; clearThumbnail(); - if (WindowManagerService.DEBUG_ANIM) Slog.v( - TAG, "Finished animation in " + mAppToken + " @ " + currentTime); + if (DEBUG_ANIM) Slog.v(TAG, + "Finished animation in " + mAppToken + " @ " + currentTime); } } hasTransformation = hasMoreFrames; @@ -258,8 +287,8 @@ public class AppWindowAnimator { if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed) && animation != null) { if (!animating) { - if (WindowManagerService.DEBUG_ANIM) Slog.v( - TAG, "Starting animation in " + mAppToken + + if (DEBUG_ANIM) Slog.v(TAG, + "Starting animation in " + mAppToken + " @ " + currentTime + " scale=" + mService.getTransitionAnimationScaleLocked() + " allDrawn=" + mAppToken.allDrawn + " animating=" + animating); @@ -306,8 +335,8 @@ public class AppWindowAnimator { mService.moveInputMethodWindowsIfNeededLocked(true); } - if (WindowManagerService.DEBUG_ANIM) Slog.v( - TAG, "Animation done in " + mAppToken + if (DEBUG_ANIM) Slog.v(TAG, + "Animation done in " + mAppToken + ": reportedVisible=" + mAppToken.reportedVisible); transformation.clear(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 77694b6985d6..4972ce4d84cc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -495,7 +495,7 @@ public class WindowManagerService extends IWindowManager.Stub String mLastANRState; /** All DisplayContents in the world, kept here */ - SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2); + SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2); int mRotation = 0; int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -511,7 +511,7 @@ public class WindowManagerService extends IWindowManager.Stub deathRecipient = d; } } - ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>(); + ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>(); int mDeferredRotationPauseCount; int mSystemDecorLayer = 0; @@ -552,11 +552,10 @@ public class WindowManagerService extends IWindowManager.Stub private final PowerManager.WakeLock mScreenFrozenLock; final AppTransition mAppTransition; - boolean mStartingIconInTransition = false; boolean mSkipAppTransitionAnimation = false; - final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<AppWindowToken>(); - final ArraySet<AppWindowToken> mClosingApps = new ArraySet<AppWindowToken>(); + final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>(); + final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>(); boolean mIsTouchDevice; @@ -581,7 +580,7 @@ public class WindowManagerService extends IWindowManager.Stub int mInputMethodAnimLayerAdjustment; WindowState mInputMethodWindow = null; - final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>(); + final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>(); /** Temporary list for comparison. Always clear this after use so we don't end up with * orphaned windows references */ @@ -4146,8 +4145,8 @@ public class WindowManagerService extends IWindowManager.Stub } synchronized(mWindowMap) { - if (DEBUG_APP_TRANSITIONS) Slog.v( - TAG, "Prepare app transition: transit=" + transit + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:" + + " transit=" + AppTransition.appTransitionToString(transit) + " " + mAppTransition + " alwaysKeepCurrent=" + alwaysKeepCurrent + " Callers=" + Debug.getCallers(3)); @@ -4166,9 +4165,7 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.setAppTransition(transit); } } - if (okToDisplay()) { - mAppTransition.prepare(); - mStartingIconInTransition = false; + if (okToDisplay() && mAppTransition.prepare()) { mSkipAppTransitionAnimation = false; } if (mAppTransition.isTransitionSet()) { @@ -4295,19 +4292,16 @@ public class WindowManagerService extends IWindowManager.Stub if (ttoken != null) { WindowState startingWindow = ttoken.startingWindow; if (startingWindow != null) { - if (mStartingIconInTransition) { - // In this case, the starting icon has already - // been displayed, so start letting windows get - // shown immediately without any more transitions. - mSkipAppTransitionAnimation = true; - } + // In this case, the starting icon has already been displayed, so start + // letting windows get shown immediately without any more transitions. + mSkipAppTransitionAnimation = true; + if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Moving existing starting " + startingWindow + " from " + ttoken + " to " + wtoken); final long origId = Binder.clearCallingIdentity(); - // Transfer the starting window over to the new - // token. + // Transfer the starting window over to the new token. wtoken.startingData = ttoken.startingData; wtoken.startingView = ttoken.startingView; wtoken.startingDisplayed = ttoken.startingDisplayed; @@ -4321,7 +4315,6 @@ public class WindowManagerService extends IWindowManager.Stub startingWindow.mToken = wtoken; startingWindow.mRootToken = wtoken; startingWindow.mAppToken = wtoken; - startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator; if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) { Slog.v(TAG, "Removing starting window: " + startingWindow); @@ -4355,17 +4348,8 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.clientHidden = ttoken.clientHidden; wtoken.sendAppVisibilityToClients(); } - final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator; - final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator; - if (tAppAnimator.animation != null) { - wAppAnimator.animation = tAppAnimator.animation; - wAppAnimator.animating = tAppAnimator.animating; - wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment; - tAppAnimator.animation = null; - tAppAnimator.animLayerAdjustment = 0; - wAppAnimator.updateLayers(); - tAppAnimator.updateLayers(); - } + ttoken.mAppAnimator.transferCurrentAnimation( + wtoken.mAppAnimator, startingWindow.mWinAnimator); updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/); @@ -4465,7 +4449,6 @@ public class WindowManagerService extends IWindowManager.Stub } if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData"); - mStartingIconInTransition = true; wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags); Message m = mH.obtainMessage(H.ADD_STARTING, wtoken); @@ -4566,8 +4549,8 @@ public class WindowManagerService extends IWindowManager.Stub changed = true; } - final int N = wtoken.allAppWindows.size(); - for (int i=0; i<N; i++) { + final int windowsCount = wtoken.allAppWindows.size(); + for (int i = 0; i < windowsCount; i++) { WindowState win = wtoken.allAppWindows.get(i); if (win == wtoken.startingWindow) { continue; @@ -4696,7 +4679,7 @@ public class WindowManagerService extends IWindowManager.Stub // If we are preparing an app transition, then delay changing // the visibility of this token until we execute that transition. if (okToDisplay() && mAppTransition.isTransitionSet()) { - if (!wtoken.startingDisplayed) { + if (!wtoken.startingDisplayed || mSkipAppTransitionAnimation) { if (DEBUG_APP_TRANSITIONS) Slog.v( TAG, "Setting dummy animation on: " + wtoken); wtoken.mAppAnimator.setDummyAnimation(); @@ -9178,14 +9161,14 @@ public class WindowManagerService extends IWindowManager.Stub public int handleAppTransitionReadyLocked(WindowList windows) { int changes = 0; int i; - int NN = mOpeningApps.size(); + int appsCount = mOpeningApps.size(); boolean goodToGo = true; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "Checking " + NN + " opening apps (frozen=" + "Checking " + appsCount + " opening apps (frozen=" + mDisplayFrozen + " timeout=" + mAppTransition.isTimeout() + ")..."); if (!mAppTransition.isTimeout()) { - for (i=0; i<NN && goodToGo; i++) { + for (i = 0; i < appsCount && goodToGo; i++) { AppWindowToken wtoken = mOpeningApps.valueAt(i); if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Check opening app=" + wtoken + ": allDrawn=" @@ -9238,7 +9221,6 @@ public class WindowManagerService extends IWindowManager.Stub if (mSkipAppTransitionAnimation) { transit = AppTransition.TRANSIT_UNSET; } - mStartingIconInTransition = false; mSkipAppTransitionAnimation = false; mH.removeMessages(H.APP_TRANSITION_TIMEOUT); @@ -9287,17 +9269,17 @@ public class WindowManagerService extends IWindowManager.Stub // (2) Find the layout params of the top-most // application window in the tokens, which is // what will control the animation theme. - final int NC = mClosingApps.size(); - NN = NC + mOpeningApps.size(); - for (i=0; i<NN; i++) { + final int closingAppsCount = mClosingApps.size(); + appsCount = closingAppsCount + mOpeningApps.size(); + for (i = 0; i < appsCount; i++) { final AppWindowToken wtoken; - if (i < NC) { + if (i < closingAppsCount) { wtoken = mClosingApps.valueAt(i); if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) { closingAppHasWallpaper = true; } } else { - wtoken = mOpeningApps.valueAt(i - NC); + wtoken = mOpeningApps.valueAt(i - closingAppsCount); if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) { openingAppHasWallpaper = true; } @@ -9338,20 +9320,23 @@ public class WindowManagerService extends IWindowManager.Stub transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE; break; } - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit); + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, + "New transit: " + AppTransition.appTransitionToString(transit)); } else if ((oldWallpaper != null) && !mOpeningApps.isEmpty() && !mOpeningApps.contains(oldWallpaper.mAppToken)) { // We are transitioning from an activity with // a wallpaper to one without. transit = AppTransition.TRANSIT_WALLPAPER_CLOSE; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "New transit away from wallpaper: " + transit); + "New transit away from wallpaper: " + + AppTransition.appTransitionToString(transit)); } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) { // We are transitioning from an activity without // a wallpaper to now showing the wallpaper transit = AppTransition.TRANSIT_WALLPAPER_OPEN; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, - "New transit into wallpaper: " + transit); + "New transit into wallpaper: " + + AppTransition.appTransitionToString(transit)); } else { mAnimateWallpaperWithTarget = true; } @@ -9395,21 +9380,24 @@ public class WindowManagerService extends IWindowManager.Stub } } - NN = mOpeningApps.size(); - for (i=0; i<NN; i++) { + appsCount = mOpeningApps.size(); + for (i = 0; i < appsCount; i++) { AppWindowToken wtoken = mOpeningApps.valueAt(i); final AppWindowAnimator appAnimator = wtoken.mAppAnimator; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken); - appAnimator.clearThumbnail(); - appAnimator.animation = null; + + if (!appAnimator.usingTransferredAnimation) { + appAnimator.clearThumbnail(); + appAnimator.animation = null; + } wtoken.inPendingTransaction = false; setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction); wtoken.updateReportedVisibilityLocked(); wtoken.waitingToShow = false; appAnimator.mAllAppWinAnimators.clear(); - final int N = wtoken.allAppWindows.size(); - for (int j = 0; j < N; j++) { + final int windowsCount = wtoken.allAppWindows.size(); + for (int j = 0; j < windowsCount; j++) { appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator); } mAnimator.mAnimating |= appAnimator.showAllWindowsLocked(); @@ -9417,7 +9405,7 @@ public class WindowManagerService extends IWindowManager.Stub if (animLp != null) { int layer = -1; - for (int j=0; j<wtoken.windows.size(); j++) { + for (int j = 0; j < wtoken.windows.size(); j++) { WindowState win = wtoken.windows.get(j); if (win.mWinAnimator.mAnimLayer > layer) { layer = win.mWinAnimator.mAnimLayer; @@ -9429,8 +9417,8 @@ public class WindowManagerService extends IWindowManager.Stub } } } - NN = mClosingApps.size(); - for (i=0; i<NN; i++) { + appsCount = mClosingApps.size(); + for (i = 0; i < appsCount; i++) { AppWindowToken wtoken = mClosingApps.valueAt(i); final AppWindowAnimator appAnimator = wtoken.mAppAnimator; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken); @@ -9454,7 +9442,7 @@ public class WindowManagerService extends IWindowManager.Stub if (animLp != null) { int layer = -1; - for (int j=0; j<wtoken.windows.size(); j++) { + for (int j = 0; j < wtoken.windows.size(); j++) { WindowState win = wtoken.windows.get(j); if (win.mWinAnimator.mAnimLayer > layer) { layer = win.mWinAnimator.mAnimLayer; @@ -11407,8 +11395,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting); pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting); pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled); - pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition); - pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation); + pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation); pw.println(" mLayoutToAnim:"); mAppTransition.dump(pw, " "); } diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index bfd6cc0fafb1..f7bcf2ad0e7f 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -100,7 +100,7 @@ public class UsageStatsService extends SystemService implements static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = DEBUG ? ONE_MINUTE * 4 : 1L * 24 * 60 * ONE_MINUTE; // 1 day - static final long DEFAULT_CHECK_IDLE_INTERVAL = DEBUG ? ONE_MINUTE / 4 + static final long DEFAULT_CHECK_IDLE_INTERVAL = DEBUG ? ONE_MINUTE : 8 * 60 * ONE_MINUTE; // 8 hours static final long DEFAULT_PAROLE_INTERVAL = DEBUG ? ONE_MINUTE * 10 : 24 * 60 * ONE_MINUTE; // 24 hours between paroles @@ -336,6 +336,7 @@ public class UsageStatsService extends SystemService implements /** Check all running users' apps to see if they enter an idle state. */ void checkIdleStates() { + if (DEBUG) Slog.d(TAG, "Checking idle state"); final int[] runningUsers; try { runningUsers = ActivityManagerNative.getDefault().getRunningUserIds(); diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java index 465c5f41a297..33013ac07a3c 100644 --- a/telecomm/java/android/telecom/AudioState.java +++ b/telecomm/java/android/telecom/AudioState.java @@ -16,6 +16,7 @@ package android.telecom; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -24,8 +25,12 @@ import java.util.Locale; /** * Encapsulates the telecom audio state, including the current audio routing, supported audio * routing and mute. + * @deprecated - use {@link CallAudioState} instead. + * @hide */ -public final class AudioState implements Parcelable { +@Deprecated +@SystemApi +public class AudioState implements Parcelable { /** Direct the audio stream through the device's earpiece. */ public static final int ROUTE_EARPIECE = 0x00000001; @@ -64,6 +69,12 @@ public final class AudioState implements Parcelable { supportedRouteMask = state.getSupportedRouteMask(); } + public AudioState(CallAudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + @Override public boolean equals(Object obj) { if (obj == null) { diff --git a/telecomm/java/android/telecom/CallAudioState.aidl b/telecomm/java/android/telecom/CallAudioState.aidl new file mode 100644 index 000000000000..90dbbe5c1bb3 --- /dev/null +++ b/telecomm/java/android/telecom/CallAudioState.aidl @@ -0,0 +1,22 @@ +/* + * Copyright 2014, 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.telecom; + +/** + * {@hide} + */ +parcelable CallAudioState; diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java new file mode 100644 index 000000000000..2b1672209a3d --- /dev/null +++ b/telecomm/java/android/telecom/CallAudioState.java @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2014 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.telecom; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Locale; + +/** + * Encapsulates the telecom audio state, including the current audio routing, supported audio + * routing and mute. + */ +public final class CallAudioState implements Parcelable { + /** Direct the audio stream through the device's earpiece. */ + public static final int ROUTE_EARPIECE = 0x00000001; + + /** Direct the audio stream through Bluetooth. */ + public static final int ROUTE_BLUETOOTH = 0x00000002; + + /** Direct the audio stream through a wired headset. */ + public static final int ROUTE_WIRED_HEADSET = 0x00000004; + + /** Direct the audio stream through the device's speakerphone. */ + public static final int ROUTE_SPEAKER = 0x00000008; + + /** + * Direct the audio stream through the device's earpiece or wired headset if one is + * connected. + */ + public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET; + + /** Bit mask of all possible audio routes. */ + private static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET | + ROUTE_SPEAKER; + + private final boolean isMuted; + private final int route; + private final int supportedRouteMask; + + /** + * Constructor for a {@link CallAudioState} object. + * + * @param muted {@code true} if the call is muted, {@code false} otherwise. + * @param route The current audio route being used. + * Allowed values: + * {@link #ROUTE_EARPIECE} + * {@link #ROUTE_BLUETOOTH} + * {@link #ROUTE_WIRED_HEADSET} + * {@link #ROUTE_SPEAKER} + * @param supportedRouteMask Bit mask of all routes supported by this call. This should be a + * bitwise combination of the following values: + * {@link #ROUTE_EARPIECE} + * {@link #ROUTE_BLUETOOTH} + * {@link #ROUTE_WIRED_HEADSET} + * {@link #ROUTE_SPEAKER} + */ + public CallAudioState(boolean muted, int route, int supportedRouteMask) { + this.isMuted = muted; + this.route = route; + this.supportedRouteMask = supportedRouteMask; + } + + /** @hide */ + public CallAudioState(CallAudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + + /** @hide */ + @SuppressWarnings("deprecation") + public CallAudioState(AudioState state) { + isMuted = state.isMuted(); + route = state.getRoute(); + supportedRouteMask = state.getSupportedRouteMask(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof CallAudioState)) { + return false; + } + CallAudioState state = (CallAudioState) obj; + return isMuted() == state.isMuted() && getRoute() == state.getRoute() && + getSupportedRouteMask() == state.getSupportedRouteMask(); + } + + @Override + public String toString() { + return String.format(Locale.US, + "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]", + isMuted, + audioRouteToString(route), + audioRouteToString(supportedRouteMask)); + } + + /** + * @return {@code true} if the call is muted, {@code false} otherwise. + */ + public boolean isMuted() { + return isMuted; + } + + /** + * @return The current audio route being used. + */ + public int getRoute() { + return route; + } + + /** + * @return Bit mask of all routes supported by this call. + */ + public int getSupportedRouteMask() { + return supportedRouteMask; + } + + /** + * Converts the provided audio route into a human readable string representation. + * + * @param route to convert into a string. + * + * @return String representation of the provided audio route. + */ + public static String audioRouteToString(int route) { + if (route == 0 || (route & ~ROUTE_ALL) != 0x0) { + return "UNKNOWN"; + } + + StringBuffer buffer = new StringBuffer(); + if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) { + listAppend(buffer, "EARPIECE"); + } + if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) { + listAppend(buffer, "BLUETOOTH"); + } + if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) { + listAppend(buffer, "WIRED_HEADSET"); + } + if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) { + listAppend(buffer, "SPEAKER"); + } + + return buffer.toString(); + } + + /** + * Responsible for creating AudioState objects for deserialized Parcels. + */ + public static final Parcelable.Creator<CallAudioState> CREATOR = + new Parcelable.Creator<CallAudioState> () { + + @Override + public CallAudioState createFromParcel(Parcel source) { + boolean isMuted = source.readByte() == 0 ? false : true; + int route = source.readInt(); + int supportedRouteMask = source.readInt(); + return new CallAudioState(isMuted, route, supportedRouteMask); + } + + @Override + public CallAudioState[] newArray(int size) { + return new CallAudioState[size]; + } + }; + + /** + * {@inheritDoc} + */ + @Override + public int describeContents() { + return 0; + } + + /** + * Writes AudioState object into a serializeable Parcel. + */ + @Override + public void writeToParcel(Parcel destination, int flags) { + destination.writeByte((byte) (isMuted ? 1 : 0)); + destination.writeInt(route); + destination.writeInt(supportedRouteMask); + } + + private static void listAppend(StringBuffer buffer, String str) { + if (buffer.length() > 0) { + buffer.append(", "); + } + buffer.append(str); + } +} diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index 6fa94b95e882..d8d9ab614d28 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -63,7 +63,7 @@ public abstract class Conference implements Conferenceable { Collections.unmodifiableList(mConferenceableConnections); private PhoneAccountHandle mPhoneAccount; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private int mState = Connection.STATE_NEW; private DisconnectCause mDisconnectCause; private int mConnectionCapabilities; @@ -173,9 +173,22 @@ public abstract class Conference implements Conferenceable { * @return The audio state of the conference, describing how its audio is currently * being routed by the system. This is {@code null} if this Conference * does not directly know about its audio state. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @Deprecated + @SystemApi public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * @return The audio state of the conference, describing how its audio is currently + * being routed by the system. This is {@code null} if this Conference + * does not directly know about its audio state. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } /** @@ -249,10 +262,21 @@ public abstract class Conference implements Conferenceable { * Notifies this conference that the {@link #getAudioState()} property has a new value. * * @param state The new call audio state. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead. + * @hide */ + @SystemApi + @Deprecated public void onAudioStateChanged(AudioState state) {} /** + * Notifies this conference that the {@link #getCallAudioState()} property has a new value. + * + * @param state The new call audio state. + */ + public void onCallAudioStateChanged(CallAudioState state) {} + + /** * Notifies this conference that a connection has been added to it. * * @param connection The newly added connection. @@ -515,10 +539,11 @@ public abstract class Conference implements Conferenceable { * @param state The new audio state. * @hide */ - final void setAudioState(AudioState state) { - Log.d(this, "setAudioState %s", state); - mAudioState = state; - onAudioStateChanged(state); + final void setCallAudioState(CallAudioState state) { + Log.d(this, "setCallAudioState %s", state); + mCallAudioState = state; + onAudioStateChanged(getAudioState()); + onCallAudioStateChanged(state); } private void setState(int newState) { diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 2ee5d25d463f..f39f813494f4 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -20,6 +20,7 @@ import com.android.internal.os.SomeArgs; import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -817,7 +818,7 @@ public abstract class Connection implements Conferenceable { Collections.unmodifiableList(mConferenceables); private int mState = STATE_NEW; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private Uri mAddress; private int mAddressPresentation; private String mCallerDisplayName; @@ -892,9 +893,22 @@ public abstract class Connection implements Conferenceable { * @return The audio state of the connection, describing how its audio is currently * being routed by the system. This is {@code null} if this Connection * does not directly know about its audio state. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @SystemApi + @Deprecated public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * @return The audio state of the connection, describing how its audio is currently + * being routed by the system. This is {@code null} if this Connection + * does not directly know about its audio state. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } /** @@ -968,11 +982,12 @@ public abstract class Connection implements Conferenceable { * @param state The new audio state. * @hide */ - final void setAudioState(AudioState state) { + final void setCallAudioState(CallAudioState state) { checkImmutable(); Log.d(this, "setAudioState %s", state); - mAudioState = state; - onAudioStateChanged(state); + mCallAudioState = state; + onAudioStateChanged(getAudioState()); + onCallAudioStateChanged(state); } /** @@ -1359,10 +1374,21 @@ public abstract class Connection implements Conferenceable { * Notifies this Connection that the {@link #getAudioState()} property has a new value. * * @param state The new connection audio state. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead. + * @hide */ + @SystemApi + @Deprecated public void onAudioStateChanged(AudioState state) {} /** + * Notifies this Connection that the {@link #getCallAudioState()} property has a new value. + * + * @param state The new connection audio state. + */ + public void onCallAudioStateChanged(CallAudioState state) {} + + /** * Notifies this Connection of an internal state change. This method is called after the * state is changed. * diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 13eb016e8ec1..199100b3e5f3 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -50,7 +50,7 @@ import java.util.concurrent.ConcurrentHashMap; * <pre> * <service android:name="com.example.package.MyConnectionService" * android:label="@string/some_label_for_my_connection_service" - * android:permission="android.permission.BIND_CONNECTION_SERVICE"> + * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"> * <intent-filter> * <action android:name="android.telecom.ConnectionService" /> * </intent-filter> @@ -90,7 +90,7 @@ public abstract class ConnectionService extends Service { private static final int MSG_DISCONNECT = 6; private static final int MSG_HOLD = 7; private static final int MSG_UNHOLD = 8; - private static final int MSG_ON_AUDIO_STATE_CHANGED = 9; + private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9; private static final int MSG_PLAY_DTMF_TONE = 10; private static final int MSG_STOP_DTMF_TONE = 11; private static final int MSG_CONFERENCE = 12; @@ -180,11 +180,11 @@ public abstract class ConnectionService extends Service { } @Override - public void onAudioStateChanged(String callId, AudioState audioState) { + public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { SomeArgs args = SomeArgs.obtain(); args.arg1 = callId; - args.arg2 = audioState; - mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget(); + args.arg2 = callAudioState; + mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget(); } @Override @@ -304,12 +304,12 @@ public abstract class ConnectionService extends Service { case MSG_UNHOLD: unhold((String) msg.obj); break; - case MSG_ON_AUDIO_STATE_CHANGED: { + case MSG_ON_CALL_AUDIO_STATE_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; try { String callId = (String) args.arg1; - AudioState audioState = (AudioState) args.arg2; - onAudioStateChanged(callId, audioState); + CallAudioState audioState = (CallAudioState) args.arg2; + onCallAudioStateChanged(callId, new CallAudioState(audioState)); } finally { args.recycle(); } @@ -688,12 +688,14 @@ public abstract class ConnectionService extends Service { } } - private void onAudioStateChanged(String callId, AudioState audioState) { - Log.d(this, "onAudioStateChanged %s %s", callId, audioState); + private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) { + Log.d(this, "onAudioStateChanged %s %s", callId, callAudioState); if (mConnectionById.containsKey(callId)) { - findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState); + findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState( + callAudioState); } else { - findConferenceForAction(callId, "onAudioStateChanged").setAudioState(audioState); + findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState( + callAudioState); } } diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index 62b8dea946b4..0cf7212ba55b 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -119,7 +119,7 @@ public final class InCallAdapter { } /** - * Sets the audio route (speaker, bluetooth, etc...). See {@link AudioState}. + * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}. * * @param route The audio route to use. */ diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java index 182a7f52a85f..e37cff763b34 100644 --- a/telecomm/java/android/telecom/InCallService.java +++ b/telecomm/java/android/telecom/InCallService.java @@ -52,7 +52,7 @@ public abstract class InCallService extends Service { private static final int MSG_ADD_CALL = 2; private static final int MSG_UPDATE_CALL = 3; private static final int MSG_SET_POST_DIAL_WAIT = 4; - private static final int MSG_ON_AUDIO_STATE_CHANGED = 5; + private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 5; private static final int MSG_BRING_TO_FOREGROUND = 6; private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7; @@ -87,8 +87,8 @@ public abstract class InCallService extends Service { } break; } - case MSG_ON_AUDIO_STATE_CHANGED: - mPhone.internalAudioStateChanged((AudioState) msg.obj); + case MSG_ON_CALL_AUDIO_STATE_CHANGED: + mPhone.internalCallAudioStateChanged((CallAudioState) msg.obj); break; case MSG_BRING_TO_FOREGROUND: mPhone.internalBringToForeground(msg.arg1 == 1); @@ -133,8 +133,8 @@ public abstract class InCallService extends Service { } @Override - public void onAudioStateChanged(AudioState audioState) { - mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget(); + public void onCallAudioStateChanged(CallAudioState callAudioState) { + mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, callAudioState).sendToTarget(); } @Override @@ -156,6 +156,10 @@ public abstract class InCallService extends Service { InCallService.this.onAudioStateChanged(audioState); } + public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { + InCallService.this.onCallAudioStateChanged(callAudioState); + }; + /** ${inheritDoc} */ @Override public void onBringToForeground(Phone phone, boolean showDialpad) { @@ -248,14 +252,27 @@ public abstract class InCallService extends Service { * * @return An object encapsulating the audio state. Returns null if the service is not * fully initialized. + * @deprecated Use {@link #getCallAudioState()} instead. + * @hide */ + @Deprecated public final AudioState getAudioState() { return mPhone == null ? null : mPhone.getAudioState(); } /** + * Obtains the current phone call audio state. + * + * @return An object encapsulating the audio state. Returns null if the service is not + * fully initialized. + */ + public final CallAudioState getCallAudioState() { + return mPhone == null ? null : mPhone.getCallAudioState(); + } + + /** * Sets the microphone mute state. When this request is honored, there will be change to - * the {@link #getAudioState()}. + * the {@link #getCallAudioState()}. * * @param state {@code true} if the microphone should be muted; {@code false} otherwise. */ @@ -267,7 +284,7 @@ public abstract class InCallService extends Service { /** * Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will - * be change to the {@link #getAudioState()}. + * be change to the {@link #getCallAudioState()}. * * @param route The audio route to use. */ @@ -311,11 +328,22 @@ public abstract class InCallService extends Service { * Called when the audio state changes. * * @param audioState The new {@link AudioState}. + * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState) instead}. + * @hide */ + @Deprecated public void onAudioStateChanged(AudioState audioState) { } /** + * Called when the audio state changes. + * + * @param audioState The new {@link CallAudioState}. + */ + public void onCallAudioStateChanged(CallAudioState audioState) { + } + + /** * Called to bring the in-call screen to the foreground. The in-call experience should * respond immediately by coming to the foreground to inform the user of the state of * ongoing {@code Call}s. diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java index 4cdfd2eb8f56..8eb091b732af 100644 --- a/telecomm/java/android/telecom/Phone.java +++ b/telecomm/java/android/telecom/Phone.java @@ -41,10 +41,21 @@ public final class Phone { * * @param phone The {@code Phone} calling this method. * @param audioState The new {@link AudioState}. + * + * @deprecated Use {@link #onCallAudioStateChanged(Phone, CallAudioState)} instead. */ + @Deprecated public void onAudioStateChanged(Phone phone, AudioState audioState) { } /** + * Called when the audio state changes. + * + * @param phone The {@code Phone} calling this method. + * @param callAudioState The new {@link CallAudioState}. + */ + public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { } + + /** * Called to bring the in-call screen to the foreground. The in-call experience should * respond immediately by coming to the foreground to inform the user of the state of * ongoing {@code Call}s. @@ -100,7 +111,7 @@ public final class Phone { private final InCallAdapter mInCallAdapter; - private AudioState mAudioState; + private CallAudioState mCallAudioState; private final List<Listener> mListeners = new CopyOnWriteArrayList<>(); @@ -145,10 +156,10 @@ public final class Phone { } } - final void internalAudioStateChanged(AudioState audioState) { - if (!Objects.equals(mAudioState, audioState)) { - mAudioState = audioState; - fireAudioStateChanged(audioState); + final void internalCallAudioStateChanged(CallAudioState callAudioState) { + if (!Objects.equals(mCallAudioState, callAudioState)) { + mCallAudioState = callAudioState; + fireCallAudioStateChanged(callAudioState); } } @@ -271,9 +282,20 @@ public final class Phone { * Obtains the current phone call audio state of the {@code Phone}. * * @return An object encapsulating the audio state. + * @deprecated Use {@link #getCallAudioState()} instead. */ + @Deprecated public final AudioState getAudioState() { - return mAudioState; + return new AudioState(mCallAudioState); + } + + /** + * Obtains the current phone call audio state of the {@code Phone}. + * + * @return An object encapsulating the audio state. + */ + public final CallAudioState getCallAudioState() { + return mCallAudioState; } private void fireCallAdded(Call call) { @@ -288,9 +310,10 @@ public final class Phone { } } - private void fireAudioStateChanged(AudioState audioState) { + private void fireCallAudioStateChanged(CallAudioState audioState) { for (Listener listener : mListeners) { - listener.onAudioStateChanged(this, audioState); + listener.onCallAudioStateChanged(this, audioState); + listener.onAudioStateChanged(this, new AudioState(audioState)); } } diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 86475b1cea1c..f05a1ef59052 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -26,6 +26,7 @@ import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -127,6 +128,7 @@ public final class PhoneAccount implements Parcelable { /** * Indicating no icon tint is set. + * @hide */ public static final int NO_ICON_TINT = 0; @@ -144,14 +146,11 @@ public final class PhoneAccount implements Parcelable { private final Uri mAddress; private final Uri mSubscriptionAddress; private final int mCapabilities; - private final int mIconResId; - private final String mIconPackageName; - private final Bitmap mIconBitmap; - private final int mIconTint; private final int mHighlightColor; private final CharSequence mLabel; private final CharSequence mShortDescription; private final List<String> mSupportedUriSchemes; + private final Icon mIcon; /** * Helper class for creating a {@link PhoneAccount}. @@ -161,14 +160,11 @@ public final class PhoneAccount implements Parcelable { private Uri mAddress; private Uri mSubscriptionAddress; private int mCapabilities; - private int mIconResId; - private String mIconPackageName; - private Bitmap mIconBitmap; - private int mIconTint = NO_ICON_TINT; private int mHighlightColor = NO_HIGHLIGHT_COLOR; private CharSequence mLabel; private CharSequence mShortDescription; private List<String> mSupportedUriSchemes = new ArrayList<String>(); + private Icon mIcon; /** * Creates a builder with the specified {@link PhoneAccountHandle} and label. @@ -189,14 +185,11 @@ public final class PhoneAccount implements Parcelable { mAddress = phoneAccount.getAddress(); mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); mCapabilities = phoneAccount.getCapabilities(); - mIconResId = phoneAccount.getIconResId(); - mIconPackageName = phoneAccount.getIconPackageName(); - mIconBitmap = phoneAccount.getIconBitmap(); - mIconTint = phoneAccount.getIconTint(); mHighlightColor = phoneAccount.getHighlightColor(); mLabel = phoneAccount.getLabel(); mShortDescription = phoneAccount.getShortDescription(); mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); + mIcon = phoneAccount.getIcon(); } /** @@ -233,65 +226,12 @@ public final class PhoneAccount implements Parcelable { } /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param packageContext The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @return The builder. - */ - public Builder setIcon(Context packageContext, int iconResId) { - return setIcon(packageContext.getPackageName(), iconResId); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconPackageName The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @return The builder. - */ - public Builder setIcon(String iconPackageName, int iconResId) { - return setIcon(iconPackageName, iconResId, NO_ICON_TINT); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. + * Sets the icon. See {@link PhoneAccount#getIcon}. * - * @param packageContext The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @param iconTint A color with which to tint this icon. - * @return The builder. + * @param icon The icon to set. */ - public Builder setIcon(Context packageContext, int iconResId, int iconTint) { - return setIcon(packageContext.getPackageName(), iconResId, iconTint); - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconPackageName The package from which to load an icon. - * @param iconResId The resource in {@code iconPackageName} representing the icon. - * @param iconTint A color with which to tint this icon. - * @return The builder. - */ - public Builder setIcon(String iconPackageName, int iconResId, int iconTint) { - this.mIconPackageName = iconPackageName; - this.mIconResId = iconResId; - this.mIconTint = iconTint; - return this; - } - - /** - * Sets the icon. See {@link PhoneAccount#createIconDrawable}. - * - * @param iconBitmap The icon bitmap. - * @return The builder. - */ - public Builder setIcon(Bitmap iconBitmap) { - this.mIconBitmap = iconBitmap; - this.mIconPackageName = null; - this.mIconResId = NO_RESOURCE_ID; - this.mIconTint = NO_ICON_TINT; + public Builder setIcon(Icon icon) { + mIcon = icon; return this; } @@ -363,10 +303,7 @@ public final class PhoneAccount implements Parcelable { mAddress, mSubscriptionAddress, mCapabilities, - mIconResId, - mIconPackageName, - mIconBitmap, - mIconTint, + mIcon, mHighlightColor, mLabel, mShortDescription, @@ -379,10 +316,7 @@ public final class PhoneAccount implements Parcelable { Uri address, Uri subscriptionAddress, int capabilities, - int iconResId, - String iconPackageName, - Bitmap iconBitmap, - int iconTint, + Icon icon, int highlightColor, CharSequence label, CharSequence shortDescription, @@ -391,10 +325,7 @@ public final class PhoneAccount implements Parcelable { mAddress = address; mSubscriptionAddress = subscriptionAddress; mCapabilities = capabilities; - mIconResId = iconResId; - mIconPackageName = iconPackageName; - mIconBitmap = iconBitmap; - mIconTint = iconTint; + mIcon = icon; mHighlightColor = highlightColor; mLabel = label; mShortDescription = shortDescription; @@ -497,6 +428,15 @@ public final class PhoneAccount implements Parcelable { } /** + * The icon to represent this {@code PhoneAccount}. + * + * @return The icon. + */ + public Icon getIcon() { + return mIcon; + } + + /** * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI * scheme. * @@ -518,59 +458,6 @@ public final class PhoneAccount implements Parcelable { } /** - * The icon resource ID for the icon of this {@code PhoneAccount}. - * <p> - * Creators of a {@code PhoneAccount} who possess the icon in static resources should prefer - * this method of indicating the icon rather than using {@link #getIconBitmap()}, since it - * leads to less resource usage. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. - * - * @return A resource ID. - */ - public int getIconResId() { - return mIconResId; - } - - /** - * The package name from which to load the icon of this {@code PhoneAccount}. - * <p> - * If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from - * the package in the {@link ComponentName} of the {@link #getAccountHandle()}. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}. - * - * @return A package name. - */ - public String getIconPackageName() { - return mIconPackageName; - } - - /** - * A tint to apply to the icon of this {@code PhoneAccount}. - * - * @return A hexadecimal color value. - */ - public int getIconTint() { - return mIconTint; - } - - /** - * A literal icon bitmap to represent this {@code PhoneAccount} in a user interface. - * <p> - * If this property is specified, it is to be considered the preferred icon. Otherwise, the - * resource specified by {@link #getIconResId()} should be used. - * <p> - * Clients wishing to display a {@code PhoneAccount} should use - * {@link #createIconDrawable(Context)}. - * - * @return A bitmap. - */ - public Bitmap getIconBitmap() { - return mIconBitmap; - } - - /** * A highlight color to use in displaying information about this {@code PhoneAccount}. * * @return A hexadecimal color value. @@ -579,41 +466,6 @@ public final class PhoneAccount implements Parcelable { return mHighlightColor; } - /** - * Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user - * interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and - * {@link #getIconBitmap()} as necessary. - * - * @param context A {@code Context} to use for loading {@code Drawable}s. - * - * @return An icon for this {@code PhoneAccount}. - */ - public Drawable createIconDrawable(Context context) { - if (mIconBitmap != null) { - return new BitmapDrawable(context.getResources(), mIconBitmap); - } - - if (mIconResId != 0) { - try { - Context packageContext = context.createPackageContext(mIconPackageName, 0); - try { - Drawable iconDrawable = packageContext.getDrawable(mIconResId); - if (mIconTint != NO_ICON_TINT) { - iconDrawable.setTint(mIconTint); - } - return iconDrawable; - } catch (NotFoundException | MissingResourceException e) { - Log.e(this, e, "Cannot find icon %d in package %s", - mIconResId, mIconPackageName); - } - } catch (PackageManager.NameNotFoundException e) { - Log.w(this, "Cannot find package %s", mIconPackageName); - } - } - - return new ColorDrawable(Color.TRANSPARENT); - } - // // Parcelable implementation // @@ -644,19 +496,16 @@ public final class PhoneAccount implements Parcelable { mSubscriptionAddress.writeToParcel(out, flags); } out.writeInt(mCapabilities); - out.writeInt(mIconResId); - out.writeString(mIconPackageName); - if (mIconBitmap == null) { - out.writeInt(0); - } else { - out.writeInt(1); - mIconBitmap.writeToParcel(out, flags); - } - out.writeInt(mIconTint); out.writeInt(mHighlightColor); out.writeCharSequence(mLabel); out.writeCharSequence(mShortDescription); out.writeStringList(mSupportedUriSchemes); + if (mIcon == null) { + out.writeInt(0); + } else { + out.writeInt(1); + mIcon.writeToParcel(out, flags); + } } public static final Creator<PhoneAccount> CREATOR @@ -689,18 +538,15 @@ public final class PhoneAccount implements Parcelable { mSubscriptionAddress = null; } mCapabilities = in.readInt(); - mIconResId = in.readInt(); - mIconPackageName = in.readString(); - if (in.readInt() > 0) { - mIconBitmap = Bitmap.CREATOR.createFromParcel(in); - } else { - mIconBitmap = null; - } - mIconTint = in.readInt(); mHighlightColor = in.readInt(); mLabel = in.readCharSequence(); mShortDescription = in.readCharSequence(); mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList()); + if (in.readInt() > 0) { + mIcon = Icon.CREATOR.createFromParcel(in); + } else { + mIcon = null; + } } @Override diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java index b59584b58508..095a88feb41f 100644 --- a/telecomm/java/android/telecom/RemoteConference.java +++ b/telecomm/java/android/telecom/RemoteConference.java @@ -18,6 +18,7 @@ package android.telecom; import com.android.internal.telecom.IConnectionService; +import android.annotation.SystemApi; import android.os.Handler; import android.os.RemoteException; @@ -355,14 +356,27 @@ public final class RemoteConference { * can include audio routing (Bluetooth, Speaker, etc) and muting state. * * @see android.telecom.AudioState + * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead. + * @hide */ + @SystemApi + @Deprecated public void setAudioState(AudioState state) { + setCallAudioState(new CallAudioState(state)); + } + + /** + * Request to change the conference's audio routing to the specified state. The specified state + * can include audio routing (Bluetooth, Speaker, etc) and muting state. + */ + public void setCallAudioState(CallAudioState state) { try { - mConnectionService.onAudioStateChanged(mId, state); + mConnectionService.onCallAudioStateChanged(mId, state); } catch (RemoteException e) { } } + /** * Returns a list of independent connections that can me merged with this conference. * diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java index 19bb3f18e1f2..08485a30277b 100644 --- a/telecomm/java/android/telecom/RemoteConnection.java +++ b/telecomm/java/android/telecom/RemoteConnection.java @@ -20,6 +20,7 @@ import com.android.internal.telecom.IConnectionService; import com.android.internal.telecom.IVideoCallback; import com.android.internal.telecom.IVideoProvider; +import android.annotation.SystemApi; import android.net.Uri; import android.os.Handler; import android.os.IBinder; @@ -776,11 +777,24 @@ public final class RemoteConnection { * Set the audio state of this {@code RemoteConnection}. * * @param state The audio state of this {@code RemoteConnection}. + * @hide + * @deprecated Use {@link #setCallAudioState(CallAudioState) instead. */ + @SystemApi + @Deprecated public void setAudioState(AudioState state) { + setCallAudioState(new CallAudioState(state)); + } + + /** + * Set the audio state of this {@code RemoteConnection}. + * + * @param state The audio state of this {@code RemoteConnection}. + */ + public void setCallAudioState(CallAudioState state) { try { if (mConnected) { - mConnectionService.onAudioStateChanged(mConnectionId, state); + mConnectionService.onCallAudioStateChanged(mConnectionId, state); } } catch (RemoteException ignored) { } diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index b2c036cafb61..c8ed2b07a439 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -333,16 +333,24 @@ public class TelecomManager { * displayed to the user. */ - /** Property is displayed normally. */ + /** + * Indicates that the address or number of a call is allowed to be displayed for caller ID. + */ public static final int PRESENTATION_ALLOWED = 1; - /** Property was blocked. */ + /** + * Indicates that the address or number of a call is blocked by the other party. + */ public static final int PRESENTATION_RESTRICTED = 2; - /** Presentation was not specified or is unknown. */ + /** + * Indicates that the address or number of a call is not specified or known by the carrier. + */ public static final int PRESENTATION_UNKNOWN = 3; - /** Property should be displayed as a pay phone. */ + /** + * Indicates that the address or number of a call belongs to a pay phone. + */ public static final int PRESENTATION_PAYPHONE = 4; private static final String TAG = "TelecomManager"; diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl index 339a9829ed15..c2e8530b2dbd 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecom; import android.os.Bundle; -import android.telecom.AudioState; +import android.telecom.CallAudioState; import android.telecom.ConnectionRequest; import android.telecom.PhoneAccountHandle; @@ -56,7 +56,7 @@ oneway interface IConnectionService { void unhold(String callId); - void onAudioStateChanged(String activeCallId, in AudioState audioState); + void onCallAudioStateChanged(String activeCallId, in CallAudioState callAudioState); void playDtmfTone(String callId, char digit); diff --git a/telecomm/java/com/android/internal/telecom/IInCallService.aidl b/telecomm/java/com/android/internal/telecom/IInCallService.aidl index d26f6cb427ba..ded47d5a0562 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallService.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallService.aidl @@ -17,7 +17,7 @@ package com.android.internal.telecom; import android.app.PendingIntent; -import android.telecom.AudioState; +import android.telecom.CallAudioState; import android.telecom.ParcelableCall; import com.android.internal.telecom.IInCallAdapter; @@ -40,7 +40,7 @@ oneway interface IInCallService { void setPostDialWait(String callId, String remaining); - void onAudioStateChanged(in AudioState audioState); + void onCallAudioStateChanged(in CallAudioState callAudioState); void bringToForeground(boolean showDialpad); diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 5e996725007f..a2b1858aec82 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -757,7 +757,7 @@ public class WifiManager { * of state change events. * <p> * <b>Note:</b> If an application's target SDK version is - * {@link android.os.Build.VERSION_CODES#MNC} or newer, network + * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network * communication may not use Wi-Fi even if Wi-Fi is connected; traffic may * instead be sent through another network, such as cellular data, * Bluetooth tethering, or Ethernet. For example, traffic will never use a @@ -776,7 +776,7 @@ public class WifiManager { * @return {@code true} if the operation succeeded */ public boolean enableNetwork(int netId, boolean disableOthers) { - final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.MNC; + final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP; if (pin) { registerPinningNetworkCallback(); } @@ -1057,7 +1057,7 @@ public class WifiManager { } synchronized(this) { record = mService.reportActivityInfo(); - if (record.isValid()) { + if (record != null && record.isValid()) { return record; } else { return null; |