Merge "Added synchronization to handlePackagesChanged method" into lmp-mr1-dev
diff --git a/Android.mk b/Android.mk
index ed85df0..51a9846 100644
--- a/Android.mk
+++ b/Android.mk
@@ -202,6 +202,8 @@
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
+ core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl \
+ core/java/android/service/carriermessaging/ICarrierMessagingService.aidl \
core/java/android/service/notification/INotificationListener.aidl \
core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
core/java/android/service/notification/IConditionListener.aidl \
@@ -522,6 +524,8 @@
frameworks/base/core/java/android/view/textservice/SpellCheckerInfo.aidl \
frameworks/base/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl \
frameworks/base/core/java/android/view/textservice/SuggestionsInfo.aidl \
+ frameworks/base/core/java/android/service/carriermessaging/MessagePdu.aidl \
+ frameworks/base/core/java/android/service/carriermessaging/CarrierMessagingService.aidl \
frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
frameworks/base/core/java/android/speech/tts/Voice.aidl \
frameworks/base/core/java/android/app/usage/UsageEvents.aidl \
@@ -733,6 +737,7 @@
-samplegroup Content \
-samplegroup Input \
-samplegroup Media \
+ -samplegroup Notification \
-samplegroup RenderScript \
-samplegroup Security \
-samplegroup Sensors \
diff --git a/api/current.txt b/api/current.txt
index 1a882ac..cc5adb2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,6 +20,7 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
+ field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_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_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
@@ -2708,7 +2709,9 @@
method public void invalidateAuthToken(java.lang.String, java.lang.String);
method public static android.content.Intent newChooseAccountIntent(android.accounts.Account, java.util.ArrayList<android.accounts.Account>, java.lang.String[], boolean, java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle);
method public java.lang.String peekAuthToken(android.accounts.Account, java.lang.String);
- method public android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
+ method public deprecated android.accounts.AccountManagerFuture<java.lang.Boolean> removeAccount(android.accounts.Account, android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
+ method public android.accounts.AccountManagerFuture<android.os.Bundle> removeAccount(android.accounts.Account, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
+ method public boolean removeAccountExplicitly(android.accounts.Account);
method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
@@ -5393,11 +5396,13 @@
field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
+ field public static final java.lang.String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
+ field public static final java.lang.String EXTRA_PROVISIONING_DONT_DISABLE_SYSTEM_APPS = "android.app.extra.PROVISIONING_DONT_DISABLE_SYSTEM_APPS";
field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
@@ -10929,6 +10934,7 @@
method public boolean canClip();
method public float getAlpha();
method public boolean isEmpty();
+ method public void offset(int, int);
method public void set(android.graphics.Outline);
method public void setAlpha(float);
method public void setConvexPath(android.graphics.Path);
@@ -21854,6 +21860,7 @@
method public android.os.Bundle getData();
method public android.os.Handler getTarget();
method public long getWhen();
+ method public boolean isAsynchronous();
method public static android.os.Message obtain();
method public static android.os.Message obtain(android.os.Message);
method public static android.os.Message obtain(android.os.Handler);
@@ -21865,6 +21872,7 @@
method public android.os.Bundle peekData();
method public void recycle();
method public void sendToTarget();
+ method public void setAsynchronous(boolean);
method public void setData(android.os.Bundle);
method public void setTarget(android.os.Handler);
method public void writeToParcel(android.os.Parcel, int);
@@ -26888,6 +26896,83 @@
}
+package android.service.carriermessaging {
+
+ public abstract class CarrierMessagingService extends android.app.Service {
+ ctor public CarrierMessagingService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public int onDownloadMms(android.net.Uri, java.lang.String);
+ method public boolean onFilterSms(android.service.carriermessaging.MessagePdu, java.lang.String, int);
+ method public android.service.carriermessaging.CarrierMessagingService.SendSmsResponse onSendDataSms(byte[], java.lang.String, java.lang.String, int);
+ method public android.service.carriermessaging.CarrierMessagingService.SendMmsResult onSendMms(android.net.Uri, java.lang.String);
+ method public java.util.List<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse> onSendMultipartTextSms(java.util.List<java.lang.String>, java.lang.String, java.lang.String);
+ method public android.service.carriermessaging.CarrierMessagingService.SendSmsResponse onSendTextSms(java.lang.String, java.lang.String, java.lang.String);
+ field public static final int DOWNLOAD_STATUS_ERROR = 2; // 0x2
+ field public static final int DOWNLOAD_STATUS_OK = 0; // 0x0
+ field public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
+ field public static final int SEND_STATUS_ERROR = 2; // 0x2
+ field public static final int SEND_STATUS_OK = 0; // 0x0
+ field public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1; // 0x1
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.carriermessaging.CarrierMessagingService";
+ }
+
+ public static final class CarrierMessagingService.SendMmsResult {
+ ctor public CarrierMessagingService.SendMmsResult(int, byte[]);
+ method public int getResult();
+ method public byte[] getSendConfPdu();
+ }
+
+ public static final class CarrierMessagingService.SendSmsResponse implements android.os.Parcelable {
+ ctor public CarrierMessagingService.SendSmsResponse(int, byte[], int);
+ method public int describeContents();
+ method public byte[] getAckPdu();
+ method public int getErrorCode();
+ method public int getMessageRef();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse> CREATOR;
+ }
+
+ public abstract interface ICarrierMessagingCallback implements android.os.IInterface {
+ method public abstract void onDownloadMmsComplete(int) throws android.os.RemoteException;
+ method public abstract void onFilterComplete(boolean) throws android.os.RemoteException;
+ method public abstract void onSendMmsComplete(int, byte[]) throws android.os.RemoteException;
+ method public abstract void onSendMultipartSmsComplete(int, java.util.List<android.service.carriermessaging.CarrierMessagingService.SendSmsResponse>) throws android.os.RemoteException;
+ method public abstract void onSendSmsComplete(int, android.service.carriermessaging.CarrierMessagingService.SendSmsResponse) throws android.os.RemoteException;
+ }
+
+ public static abstract class ICarrierMessagingCallback.Stub extends android.os.Binder implements android.service.carriermessaging.ICarrierMessagingCallback {
+ ctor public ICarrierMessagingCallback.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.service.carriermessaging.ICarrierMessagingCallback asInterface(android.os.IBinder);
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ }
+
+ public abstract interface ICarrierMessagingService implements android.os.IInterface {
+ method public abstract void downloadMms(android.net.Uri, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void filterSms(android.service.carriermessaging.MessagePdu, java.lang.String, int, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendDataSms(byte[], java.lang.String, java.lang.String, int, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendMms(android.net.Uri, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendMultipartTextSms(java.util.List<java.lang.String>, java.lang.String, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ method public abstract void sendTextSms(java.lang.String, java.lang.String, java.lang.String, android.service.carriermessaging.ICarrierMessagingCallback) throws android.os.RemoteException;
+ }
+
+ public static abstract class ICarrierMessagingService.Stub extends android.os.Binder implements android.service.carriermessaging.ICarrierMessagingService {
+ ctor public ICarrierMessagingService.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.service.carriermessaging.ICarrierMessagingService asInterface(android.os.IBinder);
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ }
+
+ public final class MessagePdu implements android.os.Parcelable {
+ ctor public MessagePdu(java.util.List<byte[]>);
+ method public int describeContents();
+ method public java.util.List<byte[]> getPdus();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.carriermessaging.MessagePdu> CREATOR;
+ }
+
+}
+
package android.service.dreams {
public class DreamService extends android.app.Service implements android.view.Window.Callback {
@@ -35921,24 +36006,25 @@
enum_constant public static final android.webkit.ConsoleMessage.MessageLevel WARNING;
}
- public class CookieManager {
- method public synchronized boolean acceptCookie();
- method public boolean acceptThirdPartyCookies(android.webkit.WebView);
+ public abstract class CookieManager {
+ ctor public CookieManager();
+ method public abstract boolean acceptCookie();
+ method public abstract boolean acceptThirdPartyCookies(android.webkit.WebView);
method public static boolean allowFileSchemeCookies();
- method public void flush();
- method public java.lang.String getCookie(java.lang.String);
+ method public abstract void flush();
+ method public abstract java.lang.String getCookie(java.lang.String);
method public static synchronized android.webkit.CookieManager getInstance();
- method public synchronized boolean hasCookies();
- method public deprecated void removeAllCookie();
- method public void removeAllCookies(android.webkit.ValueCallback<java.lang.Boolean>);
- method public deprecated void removeExpiredCookie();
- method public deprecated void removeSessionCookie();
- method public void removeSessionCookies(android.webkit.ValueCallback<java.lang.Boolean>);
- method public synchronized void setAcceptCookie(boolean);
+ method public abstract boolean hasCookies();
+ method public abstract deprecated void removeAllCookie();
+ method public abstract void removeAllCookies(android.webkit.ValueCallback<java.lang.Boolean>);
+ method public abstract deprecated void removeExpiredCookie();
+ method public abstract deprecated void removeSessionCookie();
+ method public abstract void removeSessionCookies(android.webkit.ValueCallback<java.lang.Boolean>);
+ method public abstract void setAcceptCookie(boolean);
method public static void setAcceptFileSchemeCookies(boolean);
- method public void setAcceptThirdPartyCookies(android.webkit.WebView, boolean);
- method public void setCookie(java.lang.String, java.lang.String);
- method public void setCookie(java.lang.String, java.lang.String, android.webkit.ValueCallback<java.lang.Boolean>);
+ method public abstract void setAcceptThirdPartyCookies(android.webkit.WebView, boolean);
+ method public abstract void setCookie(java.lang.String, java.lang.String);
+ method public abstract void setCookie(java.lang.String, java.lang.String, android.webkit.ValueCallback<java.lang.Boolean>);
}
public final deprecated class CookieSyncManager extends android.webkit.WebSyncManager {
@@ -36047,11 +36133,13 @@
method public abstract void onReceiveValue(T);
}
- public class WebBackForwardList implements java.lang.Cloneable java.io.Serializable {
- method public synchronized int getCurrentIndex();
- method public synchronized android.webkit.WebHistoryItem getCurrentItem();
- method public synchronized android.webkit.WebHistoryItem getItemAtIndex(int);
- method public synchronized int getSize();
+ public abstract class WebBackForwardList implements java.lang.Cloneable java.io.Serializable {
+ ctor public WebBackForwardList();
+ method protected abstract android.webkit.WebBackForwardList clone();
+ method public abstract int getCurrentIndex();
+ method public abstract android.webkit.WebHistoryItem getCurrentItem();
+ method public abstract android.webkit.WebHistoryItem getItemAtIndex(int);
+ method public abstract int getSize();
}
public class WebChromeClient {
@@ -36103,21 +36191,24 @@
field public static final int MODE_SAVE = 3; // 0x3
}
- public class WebHistoryItem implements java.lang.Cloneable {
- method public android.graphics.Bitmap getFavicon();
- method public java.lang.String getOriginalUrl();
- method public java.lang.String getTitle();
- method public java.lang.String getUrl();
+ public abstract class WebHistoryItem implements java.lang.Cloneable {
+ ctor public WebHistoryItem();
+ method protected abstract android.webkit.WebHistoryItem clone();
+ method public abstract android.graphics.Bitmap getFavicon();
+ method public abstract java.lang.String getOriginalUrl();
+ method public abstract java.lang.String getTitle();
+ method public abstract java.lang.String getUrl();
}
- public deprecated class WebIconDatabase {
- method public void close();
+ public abstract deprecated class WebIconDatabase {
+ ctor public WebIconDatabase();
+ method public abstract void close();
method public static android.webkit.WebIconDatabase getInstance();
- method public void open(java.lang.String);
- method public void releaseIconForPageUrl(java.lang.String);
- method public void removeAllIcons();
- method public void requestIconForPageUrl(java.lang.String, android.webkit.WebIconDatabase.IconListener);
- method public void retainIconForPageUrl(java.lang.String);
+ method public abstract void open(java.lang.String);
+ method public abstract void releaseIconForPageUrl(java.lang.String);
+ method public abstract void removeAllIcons();
+ method public abstract void requestIconForPageUrl(java.lang.String, android.webkit.WebIconDatabase.IconListener);
+ method public abstract void retainIconForPageUrl(java.lang.String);
}
public static abstract deprecated interface WebIconDatabase.IconListener {
@@ -36149,98 +36240,99 @@
}
public abstract class WebSettings {
- method public deprecated boolean enableSmoothTransition();
- method public boolean getAllowContentAccess();
- method public boolean getAllowFileAccess();
+ ctor public WebSettings();
+ method public abstract deprecated boolean enableSmoothTransition();
+ method public abstract boolean getAllowContentAccess();
+ method public abstract boolean getAllowFileAccess();
method public abstract boolean getAllowFileAccessFromFileURLs();
method public abstract boolean getAllowUniversalAccessFromFileURLs();
- method public synchronized boolean getBlockNetworkImage();
- method public synchronized boolean getBlockNetworkLoads();
- method public boolean getBuiltInZoomControls();
- method public int getCacheMode();
- method public synchronized java.lang.String getCursiveFontFamily();
- method public synchronized boolean getDatabaseEnabled();
- method public deprecated synchronized java.lang.String getDatabasePath();
- method public synchronized int getDefaultFixedFontSize();
- method public synchronized int getDefaultFontSize();
- method public synchronized java.lang.String getDefaultTextEncodingName();
+ method public abstract boolean getBlockNetworkImage();
+ method public abstract boolean getBlockNetworkLoads();
+ method public abstract boolean getBuiltInZoomControls();
+ method public abstract int getCacheMode();
+ method public abstract java.lang.String getCursiveFontFamily();
+ method public abstract boolean getDatabaseEnabled();
+ method public abstract deprecated java.lang.String getDatabasePath();
+ method public abstract int getDefaultFixedFontSize();
+ method public abstract int getDefaultFontSize();
+ method public abstract java.lang.String getDefaultTextEncodingName();
method public static java.lang.String getDefaultUserAgent(android.content.Context);
- method public deprecated android.webkit.WebSettings.ZoomDensity getDefaultZoom();
- method public boolean getDisplayZoomControls();
- method public synchronized boolean getDomStorageEnabled();
- method public synchronized java.lang.String getFantasyFontFamily();
- method public synchronized java.lang.String getFixedFontFamily();
- method public synchronized boolean getJavaScriptCanOpenWindowsAutomatically();
- method public synchronized boolean getJavaScriptEnabled();
- method public synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
- method public deprecated boolean getLightTouchEnabled();
- method public boolean getLoadWithOverviewMode();
- method public synchronized boolean getLoadsImagesAutomatically();
- method public boolean getMediaPlaybackRequiresUserGesture();
- method public synchronized int getMinimumFontSize();
- method public synchronized int getMinimumLogicalFontSize();
+ method public abstract deprecated android.webkit.WebSettings.ZoomDensity getDefaultZoom();
+ method public abstract boolean getDisplayZoomControls();
+ method public abstract boolean getDomStorageEnabled();
+ method public abstract java.lang.String getFantasyFontFamily();
+ method public abstract java.lang.String getFixedFontFamily();
+ method public abstract boolean getJavaScriptCanOpenWindowsAutomatically();
+ method public abstract boolean getJavaScriptEnabled();
+ method public abstract android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
+ method public abstract deprecated boolean getLightTouchEnabled();
+ method public abstract boolean getLoadWithOverviewMode();
+ method public abstract boolean getLoadsImagesAutomatically();
+ method public abstract boolean getMediaPlaybackRequiresUserGesture();
+ method public abstract int getMinimumFontSize();
+ method public abstract int getMinimumLogicalFontSize();
method public abstract int getMixedContentMode();
- method public deprecated synchronized android.webkit.WebSettings.PluginState getPluginState();
- method public synchronized java.lang.String getSansSerifFontFamily();
- method public boolean getSaveFormData();
- method public deprecated boolean getSavePassword();
- method public synchronized java.lang.String getSerifFontFamily();
- method public synchronized java.lang.String getStandardFontFamily();
+ method public abstract deprecated android.webkit.WebSettings.PluginState getPluginState();
+ method public abstract java.lang.String getSansSerifFontFamily();
+ method public abstract boolean getSaveFormData();
+ method public abstract deprecated boolean getSavePassword();
+ method public abstract java.lang.String getSerifFontFamily();
+ method public abstract java.lang.String getStandardFontFamily();
method public deprecated synchronized android.webkit.WebSettings.TextSize getTextSize();
- method public synchronized int getTextZoom();
- method public synchronized boolean getUseWideViewPort();
- method public synchronized java.lang.String getUserAgentString();
- method public void setAllowContentAccess(boolean);
- method public void setAllowFileAccess(boolean);
+ method public abstract int getTextZoom();
+ method public abstract boolean getUseWideViewPort();
+ method public abstract java.lang.String getUserAgentString();
+ method public abstract void setAllowContentAccess(boolean);
+ method public abstract void setAllowFileAccess(boolean);
method public abstract void setAllowFileAccessFromFileURLs(boolean);
method public abstract void setAllowUniversalAccessFromFileURLs(boolean);
- method public synchronized void setAppCacheEnabled(boolean);
- method public deprecated synchronized void setAppCacheMaxSize(long);
- method public synchronized void setAppCachePath(java.lang.String);
- method public synchronized void setBlockNetworkImage(boolean);
- method public synchronized void setBlockNetworkLoads(boolean);
- method public void setBuiltInZoomControls(boolean);
- method public void setCacheMode(int);
- method public synchronized void setCursiveFontFamily(java.lang.String);
- method public synchronized void setDatabaseEnabled(boolean);
- method public deprecated synchronized void setDatabasePath(java.lang.String);
- method public synchronized void setDefaultFixedFontSize(int);
- method public synchronized void setDefaultFontSize(int);
- method public synchronized void setDefaultTextEncodingName(java.lang.String);
- method public deprecated void setDefaultZoom(android.webkit.WebSettings.ZoomDensity);
- method public void setDisplayZoomControls(boolean);
- method public synchronized void setDomStorageEnabled(boolean);
- method public deprecated void setEnableSmoothTransition(boolean);
- method public synchronized void setFantasyFontFamily(java.lang.String);
- method public synchronized void setFixedFontFamily(java.lang.String);
- method public synchronized void setGeolocationDatabasePath(java.lang.String);
- method public synchronized void setGeolocationEnabled(boolean);
- method public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean);
- method public synchronized void setJavaScriptEnabled(boolean);
- method public synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
- method public deprecated void setLightTouchEnabled(boolean);
- method public void setLoadWithOverviewMode(boolean);
- method public synchronized void setLoadsImagesAutomatically(boolean);
- method public void setMediaPlaybackRequiresUserGesture(boolean);
- method public synchronized void setMinimumFontSize(int);
- method public synchronized void setMinimumLogicalFontSize(int);
+ method public abstract void setAppCacheEnabled(boolean);
+ method public abstract deprecated void setAppCacheMaxSize(long);
+ method public abstract void setAppCachePath(java.lang.String);
+ method public abstract void setBlockNetworkImage(boolean);
+ method public abstract void setBlockNetworkLoads(boolean);
+ method public abstract void setBuiltInZoomControls(boolean);
+ method public abstract void setCacheMode(int);
+ method public abstract void setCursiveFontFamily(java.lang.String);
+ method public abstract void setDatabaseEnabled(boolean);
+ method public abstract deprecated void setDatabasePath(java.lang.String);
+ method public abstract void setDefaultFixedFontSize(int);
+ method public abstract void setDefaultFontSize(int);
+ method public abstract void setDefaultTextEncodingName(java.lang.String);
+ method public abstract deprecated void setDefaultZoom(android.webkit.WebSettings.ZoomDensity);
+ method public abstract void setDisplayZoomControls(boolean);
+ method public abstract void setDomStorageEnabled(boolean);
+ method public abstract deprecated void setEnableSmoothTransition(boolean);
+ method public abstract void setFantasyFontFamily(java.lang.String);
+ method public abstract void setFixedFontFamily(java.lang.String);
+ method public abstract void setGeolocationDatabasePath(java.lang.String);
+ method public abstract void setGeolocationEnabled(boolean);
+ method public abstract void setJavaScriptCanOpenWindowsAutomatically(boolean);
+ method public abstract void setJavaScriptEnabled(boolean);
+ method public abstract void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
+ method public abstract deprecated void setLightTouchEnabled(boolean);
+ method public abstract void setLoadWithOverviewMode(boolean);
+ method public abstract void setLoadsImagesAutomatically(boolean);
+ method public abstract void setMediaPlaybackRequiresUserGesture(boolean);
+ method public abstract void setMinimumFontSize(int);
+ method public abstract void setMinimumLogicalFontSize(int);
method public abstract void setMixedContentMode(int);
- method public void setNeedInitialFocus(boolean);
- method public deprecated synchronized void setPluginState(android.webkit.WebSettings.PluginState);
- method public deprecated synchronized void setRenderPriority(android.webkit.WebSettings.RenderPriority);
- method public synchronized void setSansSerifFontFamily(java.lang.String);
- method public void setSaveFormData(boolean);
- method public deprecated void setSavePassword(boolean);
- method public synchronized void setSerifFontFamily(java.lang.String);
- method public synchronized void setStandardFontFamily(java.lang.String);
- method public synchronized void setSupportMultipleWindows(boolean);
- method public void setSupportZoom(boolean);
+ method public abstract void setNeedInitialFocus(boolean);
+ method public abstract deprecated void setPluginState(android.webkit.WebSettings.PluginState);
+ method public abstract deprecated void setRenderPriority(android.webkit.WebSettings.RenderPriority);
+ method public abstract void setSansSerifFontFamily(java.lang.String);
+ method public abstract void setSaveFormData(boolean);
+ method public abstract deprecated void setSavePassword(boolean);
+ method public abstract void setSerifFontFamily(java.lang.String);
+ method public abstract void setStandardFontFamily(java.lang.String);
+ method public abstract void setSupportMultipleWindows(boolean);
+ method public abstract void setSupportZoom(boolean);
method public deprecated synchronized void setTextSize(android.webkit.WebSettings.TextSize);
- method public synchronized void setTextZoom(int);
- method public synchronized void setUseWideViewPort(boolean);
- method public synchronized void setUserAgentString(java.lang.String);
- method public synchronized boolean supportMultipleWindows();
- method public boolean supportZoom();
+ method public abstract void setTextZoom(int);
+ method public abstract void setUseWideViewPort(boolean);
+ method public abstract void setUserAgentString(java.lang.String);
+ method public abstract boolean supportMultipleWindows();
+ method public abstract boolean supportZoom();
field public static final int LOAD_CACHE_ELSE_NETWORK = 1; // 0x1
field public static final int LOAD_CACHE_ONLY = 3; // 0x3
field public static final int LOAD_DEFAULT = -1; // 0xffffffff
@@ -36490,14 +36582,15 @@
field public static final int ERROR_UNSUPPORTED_SCHEME = -10; // 0xfffffff6
}
- public class WebViewDatabase {
- method public void clearFormData();
- method public void clearHttpAuthUsernamePassword();
- method public deprecated void clearUsernamePassword();
+ public abstract class WebViewDatabase {
+ ctor public WebViewDatabase();
+ method public abstract void clearFormData();
+ method public abstract void clearHttpAuthUsernamePassword();
+ method public abstract deprecated void clearUsernamePassword();
method public static android.webkit.WebViewDatabase getInstance(android.content.Context);
- method public boolean hasFormData();
- method public boolean hasHttpAuthUsernamePassword();
- method public deprecated boolean hasUsernamePassword();
+ method public abstract boolean hasFormData();
+ method public abstract boolean hasHttpAuthUsernamePassword();
+ method public abstract deprecated boolean hasUsernamePassword();
}
public class WebViewFragment extends android.app.Fragment {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 09b484b..6957435c 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -17,37 +17,37 @@
package android.accounts;
import android.app.Activity;
-import android.content.Intent;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.content.IntentFilter;
-import android.content.BroadcastReceiver;
import android.content.res.Resources;
import android.database.SQLException;
+import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
import android.os.Parcelable;
-import android.os.Build;
import android.os.Process;
+import android.os.RemoteException;
import android.os.UserHandle;
-import android.util.Log;
import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+import com.google.android.collect.Maps;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.android.internal.R;
-import com.google.android.collect.Maps;
+import java.util.concurrent.TimeoutException;
/**
* This class provides access to a centralized registry of the user's
@@ -747,13 +747,17 @@
* null for the main thread
* @return An {@link AccountManagerFuture} which resolves to a Boolean,
* true if the account has been successfully removed
+ * @deprecated use
+ * {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)}
+ * instead
*/
+ @Deprecated
public AccountManagerFuture<Boolean> removeAccount(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler) {
if (account == null) throw new IllegalArgumentException("account is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.removeAccount(mResponse, account);
+ mService.removeAccount(mResponse, account, false);
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
@@ -765,9 +769,60 @@
}
/**
+ * Removes an account from the AccountManager. Does nothing if the account
+ * does not exist. Does not delete the account from the server.
+ * The authenticator may have its own policies preventing account
+ * deletion, in which case the account will not be deleted.
+ *
+ * <p>This method may be called from any thread, but the returned
+ * {@link AccountManagerFuture} must not be used on the main thread.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
+ *
+ * @param account The {@link Account} to remove
+ * @param activity The {@link Activity} context to use for launching a new
+ * authenticator-defined sub-Activity to prompt the user to delete an
+ * account; used only to call startActivity(); if null, the prompt
+ * will not be launched directly, but the {@link Intent} may be
+ * returned to the caller instead
+ * @param callback Callback to invoke when the request completes,
+ * null for no callback
+ * @param handler {@link Handler} identifying the callback thread,
+ * null for the main thread
+ * @return An {@link AccountManagerFuture} which resolves to a Bundle with
+ * {@link #KEY_BOOLEAN_RESULT} if activity was specified and an account
+ * was removed or if active. If no activity was specified, the returned
+ * Bundle contains only {@link #KEY_INTENT} with the {@link Intent}
+ * needed to launch the actual account removal process, if authenticator
+ * needs the activity launch. If an error occurred,
+ * {@link AccountManagerFuture#getResult()} throws:
+ * <ul>
+ * <li> {@link AuthenticatorException} if no authenticator was registered for
+ * this account type or the authenticator failed to respond
+ * <li> {@link OperationCanceledException} if the operation was canceled for
+ * any reason, including the user canceling the creation process or
+ * adding accounts (of this type) has been disabled by policy
+ * </ul>
+ */
+ public AccountManagerFuture<Bundle> removeAccount(final Account account,
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ return new AmsTask(activity, handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccount(mResponse, account, activity != null);
+ }
+ }.start();
+ }
+
+ /**
* @see #removeAccount(Account, AccountManagerCallback, Handler)
* @hide
+ * @deprecated use
+ * {@link #removeAccountAsUser(Account, Activity, AccountManagerCallback, Handler)}
+ * instead
*/
+ @Deprecated
public AccountManagerFuture<Boolean> removeAccountAsUser(final Account account,
AccountManagerCallback<Boolean> callback, Handler handler,
final UserHandle userHandle) {
@@ -775,7 +830,7 @@
if (userHandle == null) throw new IllegalArgumentException("userHandle is null");
return new Future2Task<Boolean>(handler, callback) {
public void doWork() throws RemoteException {
- mService.removeAccountAsUser(mResponse, account, userHandle.getIdentifier());
+ mService.removeAccountAsUser(mResponse, account, false, userHandle.getIdentifier());
}
public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
@@ -787,6 +842,52 @@
}
/**
+ * @see #removeAccount(Account, Activity, AccountManagerCallback, Handler)
+ * @hide
+ */
+ public AccountManagerFuture<Bundle> removeAccountAsUser(final Account account,
+ final Activity activity, AccountManagerCallback<Bundle> callback, Handler handler,
+ final UserHandle userHandle) {
+ if (account == null)
+ throw new IllegalArgumentException("account is null");
+ if (userHandle == null)
+ throw new IllegalArgumentException("userHandle is null");
+ return new AmsTask(activity, handler, callback) {
+ public void doWork() throws RemoteException {
+ mService.removeAccountAsUser(mResponse, account, activity != null,
+ userHandle.getIdentifier());
+ }
+ }.start();
+ }
+
+ /**
+ * Removes an account directly. Normally used by authenticators, not
+ * directly by applications. Does not delete the account from the server.
+ * The authenticator may have its own policies preventing account deletion,
+ * in which case the account will not be deleted.
+ * <p>
+ * It is safe to call this method from the main thread.
+ * <p>
+ * This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and to have the
+ * same UID or signature as the account's authenticator.
+ *
+ * @param account The {@link Account} to delete.
+ * @return True if the account was successfully deleted, false if the
+ * account did not exist, the account is null, or another error
+ * occurs.
+ */
+ public boolean removeAccountExplicitly(Account account) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ try {
+ return mService.removeAccountExplicitly(account);
+ } catch (RemoteException e) {
+ // won't ever happen
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Removes an auth token from the AccountManager's cache. Does nothing if
* the auth token is not currently in the cache. Applications must call this
* method when the auth token is found to have expired or otherwise become
@@ -1342,6 +1443,40 @@
}
/**
+ * Copies an account from the primary user to another user.
+ * @param account the account to copy
+ * @param user the target user
+ * @param callback Callback to invoke when the request completes,
+ * null for no callback
+ * @param handler {@link Handler} identifying the callback thread,
+ * null for the main thread
+ * @return An {@link AccountManagerFuture} which resolves to a Boolean indicated wether it
+ * succeeded.
+ * @hide
+ */
+ public AccountManagerFuture<Boolean> copyAccountToUser(
+ final Account account, final UserHandle user,
+ AccountManagerCallback<Boolean> callback, Handler handler) {
+ if (account == null) throw new IllegalArgumentException("account is null");
+ if (user == null) throw new IllegalArgumentException("user is null");
+
+ return new Future2Task<Boolean>(handler, callback) {
+ @Override
+ public void doWork() throws RemoteException {
+ mService.copyAccountToUser(
+ mResponse, account, UserHandle.USER_OWNER, user.getIdentifier());
+ }
+ @Override
+ public Boolean bundleToResult(Bundle bundle) throws AuthenticatorException {
+ if (!bundle.containsKey(KEY_BOOLEAN_RESULT)) {
+ throw new AuthenticatorException("no result in response");
+ }
+ return bundle.getBoolean(KEY_BOOLEAN_RESULT);
+ }
+ }.start();
+ }
+
+ /**
* @hide
* Removes the shared account.
* @param account the account to remove
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index a133788..aa41161 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -37,8 +37,13 @@
void hasFeatures(in IAccountManagerResponse response, in Account account, in String[] features);
void getAccountsByFeatures(in IAccountManagerResponse response, String accountType, in String[] features);
boolean addAccountExplicitly(in Account account, String password, in Bundle extras);
- void removeAccount(in IAccountManagerResponse response, in Account account);
- void removeAccountAsUser(in IAccountManagerResponse response, in Account account, int userId);
+ void removeAccount(in IAccountManagerResponse response, in Account account,
+ boolean expectActivityLaunch);
+ void removeAccountAsUser(in IAccountManagerResponse response, in Account account,
+ boolean expectActivityLaunch, int userId);
+ boolean removeAccountExplicitly(in Account account);
+ void copyAccountToUser(in IAccountManagerResponse response, in Account account,
+ int userFrom, int userTo);
void invalidateAuthToken(String accountType, String authToken);
String peekAuthToken(in Account account, String authTokenType);
void setAuthToken(in Account account, String authTokenType, String authToken);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5f21d75..a268b1c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -60,6 +60,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
+import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.Process;
@@ -965,6 +966,8 @@
int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
+ long parcelSize = Parcel.getGlobalAllocSize();
+ long parcelCount = Parcel.getGlobalAllocCount();
long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
@@ -1023,9 +1026,10 @@
printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
"Proxy Binders:", binderProxyObjectCount);
- printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
-
- printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
+ printRow(pw, TWO_COUNT_COLUMNS, "Parcel memory:", parcelSize/1024,
+ "Parcel count:", parcelCount);
+ printRow(pw, TWO_COUNT_COLUMNS, "Death Recipients:", binderDeathObjectCount,
+ "OpenSSL Sockets:", openSslSocketCount);
// SQLite mem info
pw.println(" ");
@@ -1948,7 +1952,7 @@
if (dumpFullInfo) {
printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
"Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
- printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "",
+ printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
"Clean", "Clean", "Dirty", "Size", "Alloc", "Free");
printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------",
"------", "------", "------", "------", "------", "------");
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 33cac75..ad1cf44 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -142,13 +142,24 @@
* {@link #ACTION_PROVISION_MANAGED_PROFILE} this package has to match the package name of the
* application that started provisioning. The package will be set as profile owner in that case.
*
- * <p>This package is set as device owner when device owner provisioning is started by an Nfc
- * message containing an Nfc record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}.
+ * <p>This package is set as device owner when device owner provisioning is started by an NFC
+ * message containing an NFC record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME";
/**
+ * An {@link android.accounts.Account} extra holding the account to migrate during managed
+ * profile provisioning. If the account supplied is present in the primary user, it will be
+ * copied, along with its credentials to the managed profile and removed from the primary user.
+ *
+ * Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}.
+ */
+
+ public static final String EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE
+ = "android.app.extra.PROVISIONING_ACCOUNT_TO_MIGRATE";
+
+ /**
* A String extra that, holds the email address of the account which a managed profile is
* created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and
* {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}.
@@ -165,11 +176,21 @@
= "android.app.extra.PROVISIONING_EMAIL_ADDRESS";
/**
+ * A Boolean extra that can be used by the mobile device management application to skip the
+ * disabling of system apps during provisioning when set to <code>true</code>.
+ *
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
+ */
+ public static final String EXTRA_PROVISIONING_DONT_DISABLE_SYSTEM_APPS =
+ "android.app.extra.PROVISIONING_DONT_DISABLE_SYSTEM_APPS";
+
+ /**
* A String extra holding the time zone {@link android.app.AlarmManager} that the device
* will be set to.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_TIME_ZONE
= "android.app.extra.PROVISIONING_TIME_ZONE";
@@ -178,8 +199,8 @@
* A Long extra holding the wall clock time (in milliseconds) to be set on the device's
* {@link android.app.AlarmManager}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_LOCAL_TIME
= "android.app.extra.PROVISIONING_LOCAL_TIME";
@@ -188,8 +209,8 @@
* A String extra holding the {@link java.util.Locale} that the device will be set to.
* Format: xx_yy, where xx is the language code, and yy the country code.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_LOCALE
= "android.app.extra.PROVISIONING_LOCALE";
@@ -198,8 +219,8 @@
* A String extra holding the ssid of the wifi network that should be used during nfc device
* owner provisioning for downloading the mobile device management application.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_SSID
= "android.app.extra.PROVISIONING_WIFI_SSID";
@@ -208,8 +229,8 @@
* A boolean extra indicating whether the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}
* is hidden or not.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_HIDDEN
= "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -218,8 +239,8 @@
* A String extra indicating the security type of the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE
= "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
@@ -228,8 +249,8 @@
* A String extra holding the password of the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_PASSWORD
= "android.app.extra.PROVISIONING_WIFI_PASSWORD";
@@ -238,8 +259,8 @@
* A String extra holding the proxy host for the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_PROXY_HOST
= "android.app.extra.PROVISIONING_WIFI_PROXY_HOST";
@@ -248,8 +269,8 @@
* An int extra holding the proxy port for the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_PROXY_PORT
= "android.app.extra.PROVISIONING_WIFI_PROXY_PORT";
@@ -258,8 +279,8 @@
* A String extra holding the proxy bypass for the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS
= "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS";
@@ -268,8 +289,8 @@
* A String extra holding the proxy auto-config (PAC) URL for the wifi network in
* {@link #EXTRA_PROVISIONING_WIFI_SSID}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_WIFI_PAC_URL
= "android.app.extra.PROVISIONING_WIFI_PAC_URL";
@@ -278,8 +299,8 @@
* A String extra holding a url that specifies the download location of the device admin
* package. When not provided it is assumed that the device admin package is already installed.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION";
@@ -288,8 +309,8 @@
* A String extra holding a http cookie header which should be used in the http request to the
* url specified in {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION}.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER";
@@ -300,8 +321,8 @@
* the file at the download location an error will be shown to the user and the user will be
* asked to factory reset the device.
*
- * <p>Use in an Nfc record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
- * provisioning via an Nfc bump.
+ * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+ * provisioning via an NFC bump.
*/
public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
= "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM";
@@ -317,9 +338,9 @@
* <p> A typical use case would be a device that is owned by a company, but used by either an
* employee or client.
*
- * <p> The Nfc message should be send to an unprovisioned device.
+ * <p> The NFC message should be send to an unprovisioned device.
*
- * <p>The Nfc record must contain a serialized {@link java.util.Properties} object which
+ * <p>The NFC record must contain a serialized {@link java.util.Properties} object which
* contains the following properties:
* <ul>
* <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}</li>
diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java
index 8a43472..335a45e 100644
--- a/core/java/android/content/pm/ParceledListSlice.java
+++ b/core/java/android/content/pm/ParceledListSlice.java
@@ -30,6 +30,12 @@
* Transfer a large list of Parcelable objects across an IPC. Splits into
* multiple transactions if needed.
*
+ * Caveat: for efficiency and security, all elements must be the same concrete type.
+ * In order to avoid writing the class name of each object, we must ensure that
+ * each object is the same type, or else unparceling then reparceling the data may yield
+ * a different result if the class name encoded in the Parcelable is a Base type.
+ * See b/17671747.
+ *
* @hide
*/
public class ParceledListSlice<T extends Parcelable> implements Parcelable {
@@ -56,13 +62,25 @@
if (N <= 0) {
return;
}
+
Parcelable.Creator<T> creator = p.readParcelableCreator(loader);
+ Class<?> listElementClass = null;
+
int i = 0;
while (i < N) {
if (p.readInt() == 0) {
break;
}
- mList.add(p.readCreator(creator, loader));
+
+ final T parcelable = p.readCreator(creator, loader);
+ if (listElementClass == null) {
+ listElementClass = parcelable.getClass();
+ } else {
+ verifySameType(listElementClass, parcelable.getClass());
+ }
+
+ mList.add(parcelable);
+
if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
i++;
}
@@ -82,7 +100,11 @@
return;
}
while (i < N && reply.readInt() != 0) {
- mList.add(reply.readCreator(creator, loader));
+ final T parcelable = reply.readCreator(creator, loader);
+ verifySameType(listElementClass, parcelable.getClass());
+
+ mList.add(parcelable);
+
if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
i++;
}
@@ -91,6 +113,14 @@
}
}
+ private static void verifySameType(final Class<?> expected, final Class<?> actual) {
+ if (!actual.equals(expected)) {
+ throw new IllegalArgumentException("Can't unparcel type "
+ + actual.getName() + " in list of type "
+ + expected.getName());
+ }
+ }
+
public List<T> getList() {
return mList;
}
@@ -116,11 +146,16 @@
dest.writeInt(N);
if (DEBUG) Log.d(TAG, "Writing " + N + " items");
if (N > 0) {
+ final Class<?> listElementClass = mList.get(0).getClass();
dest.writeParcelableCreator(mList.get(0));
int i = 0;
while (i < N && dest.dataSize() < MAX_FIRST_IPC_SIZE) {
dest.writeInt(1);
- mList.get(i).writeToParcel(dest, callFlags);
+
+ final T parcelable = mList.get(i);
+ verifySameType(listElementClass, parcelable.getClass());
+ parcelable.writeToParcel(dest, callFlags);
+
if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
i++;
}
@@ -137,7 +172,11 @@
if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
reply.writeInt(1);
- mList.get(i).writeToParcel(reply, callFlags);
+
+ final T parcelable = mList.get(i);
+ verifySameType(listElementClass, parcelable.getClass());
+ parcelable.writeToParcel(reply, callFlags);
+
if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
i++;
}
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index 7edf4b9..fdc54ae 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -22,12 +22,14 @@
import com.android.internal.util.ArrayUtils;
import java.io.ByteArrayInputStream;
+import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
/**
@@ -252,4 +254,53 @@
return (a.length == b.length) && ArrayUtils.containsAll(a, b)
&& ArrayUtils.containsAll(b, a);
}
+
+ /**
+ * Test if given {@link Signature} sets are effectively equal. In rare
+ * cases, certificates can have slightly malformed encoding which causes
+ * exact-byte checks to fail.
+ * <p>
+ * To identify effective equality, we bounce the certificates through an
+ * decode/encode pass before doing the exact-byte check. To reduce attack
+ * surface area, we only allow a byte size delta of a few bytes.
+ *
+ * @throws CertificateException if the before/after length differs
+ * substantially, usually a signal of something fishy going on.
+ * @hide
+ */
+ public static boolean areEffectiveMatch(Signature[] a, Signature[] b)
+ throws CertificateException {
+ final CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ final Signature[] aPrime = new Signature[a.length];
+ for (int i = 0; i < a.length; i++) {
+ aPrime[i] = bounce(cf, a[i]);
+ }
+ final Signature[] bPrime = new Signature[b.length];
+ for (int i = 0; i < b.length; i++) {
+ bPrime[i] = bounce(cf, b[i]);
+ }
+
+ return areExactMatch(aPrime, bPrime);
+ }
+
+ /**
+ * Bounce the given {@link Signature} through a decode/encode cycle.
+ *
+ * @throws CertificateException if the before/after length differs
+ * substantially, usually a signal of something fishy going on.
+ * @hide
+ */
+ public static Signature bounce(CertificateFactory cf, Signature s) throws CertificateException {
+ final InputStream is = new ByteArrayInputStream(s.mSignature);
+ final X509Certificate cert = (X509Certificate) cf.generateCertificate(is);
+ final Signature sPrime = new Signature(cert.getEncoded());
+
+ if (Math.abs(sPrime.mSignature.length - s.mSignature.length) > 2) {
+ throw new CertificateException("Bounced cert length looks fishy; before "
+ + s.mSignature.length + ", after " + sPrime.mSignature.length);
+ }
+
+ return sPrime;
+ }
}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index e578822..ecae52c 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -666,6 +666,14 @@
/**
* Get the locales that this asset manager contains data for.
+ *
+ * <p>On SDK 21 (Android 5.0: Lollipop) and above, Locale strings are valid
+ * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a> language tags and can be
+ * parsed using {@link java.util.Locale#forLanguageTag(String)}.
+ *
+ * <p>On SDK 20 (Android 4.4W: Kitkat for watches) and below, locale strings
+ * are of the form {@code ll_CC} where {@code ll} is a two letter language code,
+ * and {@code CC} is a two letter country code.
*/
public native final String[] getLocales();
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 746ead2..c85e97b 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -211,6 +211,43 @@
this.type = type;
this.data = data;
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode(data);
+ result = prime * result + type;
+ result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
+ result = prime * result + ((vendorUuid == null) ? 0 : vendorUuid.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof SoundModel))
+ return false;
+ SoundModel other = (SoundModel) obj;
+ if (!Arrays.equals(data, other.data))
+ return false;
+ if (type != other.type)
+ return false;
+ if (uuid == null) {
+ if (other.uuid != null)
+ return false;
+ } else if (!uuid.equals(other.uuid))
+ return false;
+ if (vendorUuid == null) {
+ if (other.vendorUuid != null)
+ return false;
+ } else if (!vendorUuid.equals(other.vendorUuid))
+ return false;
+ return true;
+ }
}
/*****************************************************************************
@@ -395,6 +432,28 @@
+ ", uuid=" + uuid + ", vendorUuid=" + vendorUuid
+ ", type=" + type + ", data=" + (data == null ? 0 : data.length) + "]";
}
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + Arrays.hashCode(keyphrases);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (!(obj instanceof KeyphraseSoundModel))
+ return false;
+ KeyphraseSoundModel other = (KeyphraseSoundModel) obj;
+ if (!Arrays.equals(keyphrases, other.keyphrases))
+ return false;
+ return true;
+ }
}
/**
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index 8126b75..24d4eb8 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -18,6 +18,8 @@
import static android.util.Patterns.GOOD_IRI_CHAR;
+import android.annotation.SystemApi;
+
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -38,6 +40,9 @@
* If given an https scheme but no port, fills in port
*
*/
+// TODO(igsolla): remove WebAddress from the system SDK once the WebView apk does not
+// longer need to be binary compatible with the API 21 version of the framework.
+@SystemApi
public class WebAddress {
private String mScheme;
@@ -136,42 +141,52 @@
return mScheme + "://" + authInfo + mHost + port + mPath;
}
+ /** {@hide} */
public void setScheme(String scheme) {
mScheme = scheme;
}
+ /** {@hide} */
public String getScheme() {
return mScheme;
}
+ /** {@hide} */
public void setHost(String host) {
mHost = host;
}
+ /** {@hide} */
public String getHost() {
return mHost;
}
+ /** {@hide} */
public void setPort(int port) {
mPort = port;
}
+ /** {@hide} */
public int getPort() {
return mPort;
}
+ /** {@hide} */
public void setPath(String path) {
mPath = path;
}
+ /** {@hide} */
public String getPath() {
return mPath;
}
+ /** {@hide} */
public void setAuthInfo(String authInfo) {
mAuthInfo = authInfo;
}
+ /** {@hide} */
public String getAuthInfo() {
return mAuthInfo;
}
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 52db060..878b7a0 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -156,7 +156,7 @@
* one that is strictly asynchronous.
*
* Asynchronous messages represent interrupts or events that do not require global ordering
- * with represent to synchronous messages. Asynchronous messages are not subject to
+ * with respect to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for
@@ -176,7 +176,7 @@
* one that is strictly asynchronous.
*
* Asynchronous messages represent interrupts or events that do not require global ordering
- * with represent to synchronous messages. Asynchronous messages are not subject to
+ * with respect to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
* @param callback The callback interface in which to handle messages, or null.
@@ -214,7 +214,7 @@
* one that is strictly asynchronous.
*
* Asynchronous messages represent interrupts or events that do not require global ordering
- * with represent to synchronous messages. Asynchronous messages are not subject to
+ * with respect to synchronous messages. Asynchronous messages are not subject to
* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
*
* @param looper The looper, must not be null.
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 6a0bddc..8c75847 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -417,38 +417,42 @@
}
/**
- * Returns true if the message is asynchronous.
- *
- * Asynchronous messages represent interrupts or events that do not require global ordering
- * with represent to synchronous messages. Asynchronous messages are not subject to
- * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
+ * Returns true if the message is asynchronous, meaning that it is not
+ * subject to {@link Looper} synchronization barriers.
*
* @return True if the message is asynchronous.
*
* @see #setAsynchronous(boolean)
- * @see MessageQueue#enqueueSyncBarrier(long)
- * @see MessageQueue#removeSyncBarrier(int)
- *
- * @hide
*/
public boolean isAsynchronous() {
return (flags & FLAG_ASYNCHRONOUS) != 0;
}
/**
- * Sets whether the message is asynchronous.
- *
- * Asynchronous messages represent interrupts or events that do not require global ordering
- * with represent to synchronous messages. Asynchronous messages are not subject to
- * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.
+ * Sets whether the message is asynchronous, meaning that it is not
+ * subject to {@link Looper} synchronization barriers.
+ * <p>
+ * Certain operations, such as view invalidation, may introduce synchronization
+ * barriers into the {@link Looper}'s message queue to prevent subsequent messages
+ * from being delivered until some condition is met. In the case of view invalidation,
+ * messages which are posted after a call to {@link android.view.View#invalidate}
+ * are suspended by means of a synchronization barrier until the next frame is
+ * ready to be drawn. The synchronization barrier ensures that the invalidation
+ * request is completely handled before resuming.
+ * </p><p>
+ * Asynchronous messages are exempt from synchronization barriers. They typically
+ * represent interrupts, input events, and other signals that must be handled independently
+ * even while other work has been suspended.
+ * </p><p>
+ * Note that asynchronous messages may be delivered out of order with respect to
+ * synchronous messages although they are always delivered in order among themselves.
+ * If the relative order of these messages matters then they probably should not be
+ * asynchronous in the first place. Use with caution.
+ * </p>
*
* @param async True if the message is asynchronous.
*
* @see #isAsynchronous()
- * @see MessageQueue#enqueueSyncBarrier(long)
- * @see MessageQueue#removeSyncBarrier(int)
- *
- * @hide
*/
public void setAsynchronous(boolean async) {
if (async) {
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 5230128..bedc695 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -340,6 +340,12 @@
}
}
+ /** @hide */
+ public static native long getGlobalAllocSize();
+
+ /** @hide */
+ public static native long getGlobalAllocCount();
+
/**
* Returns the total amount of data contained in the parcel.
*/
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingService.aidl b/core/java/android/service/carriermessaging/CarrierMessagingService.aidl
new file mode 100644
index 0000000..50c438a
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingService.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.service.carriermessaging;
+
+parcelable CarrierMessagingService.SendSmsResponse;
\ No newline at end of file
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingService.java b/core/java/android/service/carriermessaging/CarrierMessagingService.java
new file mode 100644
index 0000000..101f69b
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingService.java
@@ -0,0 +1,370 @@
+/*
+ * 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.service.carriermessaging;
+
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * A service that receives calls from the system when new SMS and MMS are
+ * sent or received.
+ * <p>To extend this class, you must declare the service in your manifest file with
+ * the {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE} permission
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ * <service android:name=".MyMessagingService"
+ * android:label="@string/service_name"
+ * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.service.carriermessaging.CarrierMessagingService" />
+ * </intent-filter>
+ * </service></pre>
+ */
+public abstract class CarrierMessagingService extends Service {
+ /**
+ * The {@link android.content.Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE
+ = "android.service.carriermessaging.CarrierMessagingService";
+
+ /**
+ * Indicates that an SMS or MMS message was successfully sent.
+ */
+ public static final int SEND_STATUS_OK = 0;
+
+ /**
+ * SMS/MMS sending failed. We should retry via the carrier network.
+ */
+ public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * SMS/MMS sending failed. We should not retry via the carrier network.
+ */
+ public static final int SEND_STATUS_ERROR = 2;
+
+ /**
+ * Successfully downloaded an MMS message.
+ */
+ public static final int DOWNLOAD_STATUS_OK = 0;
+
+ /**
+ * MMS downloading failed. We should retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * MMS downloading failed. We should not retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_ERROR = 2;
+
+ private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
+
+ /**
+ * Implement this method to filter SMS messages.
+ *
+ * @param pdu the PDUs of the message
+ * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+ * @param destPort the destination port of a binary SMS, this will be -1 for text SMS
+ *
+ * @return True to keep an inbound SMS message and delivered to SMS apps. False to
+ * drop the message.
+ */
+ public boolean onFilterSms(MessagePdu pdu, String format, int destPort) {
+ // optional
+ return true;
+ }
+
+ /**
+ * Implement this method to intercept text SMSs sent from the devcie.
+ *
+ * @param text the text to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ *
+ * @return a {@link SendSmsResponse}.
+ */
+ public SendSmsResponse onSendTextSms(String text, String format, String destAddress) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept binary SMSs sent from the device.
+ *
+ * @param data the binary content
+ * @param format format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort the destination port
+ *
+ * @return a {@link SendSmsResponse}
+ */
+ public SendSmsResponse onSendDataSms(byte[] data, String format, String destAddress,
+ int destPort) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept long SMSs sent from the device.
+ *
+ * @param parts a {@link List} of the message parts
+ * @param format format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ *
+ * @return a {@link List} of {@link SendSmsResponse}, one for each message part.
+ */
+ public List<SendSmsResponse> onSendMultipartTextSms(List<String> parts, String format,
+ String destAddress) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to intercept MMSs sent from the device.
+ *
+ * @param pduUri the content provider URI of the PDU to send
+ * @param locationUrl the optional URL to send this MMS PDU. If this is not specified,
+ * the PDU should be sent to the default MMSC URL.
+ *
+ * @return a {@link SendMmsResult}.
+ */
+ public SendMmsResult onSendMms(Uri pduUri, @Nullable String locationUrl) {
+ // optional
+ return null;
+ }
+
+ /**
+ * Implement this method to download MMSs received.
+ *
+ * @param contentUri the content provider URI of the PDU to be downloaded.
+ * @param locationUrl the URL of the message to be downloaded.
+ *
+ * @return a {@link SendMmsResult}.
+ */
+ public int onDownloadMms(Uri contentUri, String locationUrl) {
+ // optional
+ return DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK;
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ return null;
+ }
+ return mWrapper;
+ }
+
+ /**
+ * The result of sending an MMS.
+ */
+ public static final class SendMmsResult {
+ private int mResult;
+ private byte[] mSendConfPdu;
+
+ public SendMmsResult(int result, byte[] sendConfPdu) {
+ mResult = result;
+ mSendConfPdu = sendConfPdu;
+ }
+
+ /**
+ * @return the result which is one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}
+ */
+ public int getResult() {
+ return mResult;
+ }
+
+ /**
+ * @return the SendConf PDU, which confirms that the message was sent.
+ */
+ public byte[] getSendConfPdu() {
+ return mSendConfPdu;
+ }
+ }
+
+ /**
+ * Object passed in callbacks upon successful completion of
+ * {@link ICarrierMessagingService#sendTextSms},
+ * {@link ICarrierMessagingService#sendDataSms}, and
+ * {@link ICarrierMessagingService#sendMultipartTextSms}.
+ * Contains message reference and ackPdu.
+ */
+ public static final class SendSmsResponse implements Parcelable {
+ private int mMessageRef;
+ private byte[] mAckPdu;
+ private int mErrorCode;
+
+ /**
+ * @param messageRef message reference of the just-sent SMS
+ * @param ackPdu ackPdu for the just-sent SMS
+ * @param errorCode error code. See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+ * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ public SendSmsResponse(int messageRef, byte[] ackPdu, int errorCode) {
+ mMessageRef = messageRef;
+ mAckPdu = ackPdu;
+ mErrorCode = errorCode;
+ }
+
+ /**
+ * Returns the message reference of the just-sent SMS.
+ *
+ * @return the message reference
+ */
+ public int getMessageRef() {
+ return mMessageRef;
+ }
+
+ /**
+ * Returns the ackPdu for the just-sent SMS.
+ *
+ * @return the ackPdu
+ */
+ public byte[] getAckPdu() {
+ return mAckPdu;
+ }
+
+ /**
+ * Returns the error code upon encountering an error while sending the SMS, -1 if unknown or
+ * not applicable.
+ *
+ * @return errorCode the errorCode as defined in 3GPP 27.005, 3.2.5 for GSM/UMTS, and 3GPP2
+ * N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mMessageRef);
+ dest.writeByteArray(mAckPdu);
+ dest.writeInt(mErrorCode);
+ }
+
+ public static final Parcelable.Creator<SendSmsResponse> CREATOR
+ = new Parcelable.Creator<SendSmsResponse>() {
+ @Override
+ public SendSmsResponse createFromParcel(Parcel source) {
+ return new SendSmsResponse(source.readInt(),
+ source.createByteArray(),
+ source.readInt());
+ }
+
+ @Override
+ public SendSmsResponse[] newArray(int size) {
+ return new SendSmsResponse[size];
+ }
+ };
+ }
+
+ /**
+ * A wrapper around ICarrierMessagingService to enable the carrier messaging APP to implement
+ * methods it cares about in the {@link ICarrierMessagingService} interface.
+ */
+ private class ICarrierMessagingWrapper extends ICarrierMessagingService.Stub {
+ @Override
+ public void filterSms(MessagePdu pdu, String format, int destPort,
+ ICarrierMessagingCallback callback) {
+ try {
+ callback.onFilterComplete(onFilterSms(pdu, format, destPort));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendTextSms(String text, String format, String destAddress,
+ ICarrierMessagingCallback callback) {
+ try {
+ SendSmsResponse sendSmsResponse = onSendTextSms(text, format, destAddress);
+ if (sendSmsResponse == null) {
+ callback.onSendSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendSmsComplete(SEND_STATUS_OK, sendSmsResponse);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendDataSms(byte[] data, String format, String destAddress, int destPort,
+ ICarrierMessagingCallback callback) {
+ try {
+ SendSmsResponse sendSmsResponse = onSendDataSms(data, format, destAddress,
+ destPort);
+ if (sendSmsResponse == null) {
+ callback.onSendSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendSmsComplete(SEND_STATUS_OK, sendSmsResponse);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendMultipartTextSms(List<String> parts, String format, String destAddress,
+ ICarrierMessagingCallback callback) {
+ try {
+ List<SendSmsResponse> sendSmsResponses =
+ onSendMultipartTextSms(parts, format, destAddress);
+ if (sendSmsResponses == null) {
+ callback.onSendMultipartSmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendMultipartSmsComplete(SEND_STATUS_OK, sendSmsResponses);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void sendMms(Uri pduUri, String locationUrl, ICarrierMessagingCallback callback) {
+ try {
+ SendMmsResult result = onSendMms(pduUri, locationUrl);
+ if (result == null) {
+ callback.onSendMmsComplete(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null);
+ } else {
+ callback.onSendMmsComplete(SEND_STATUS_OK, result.getSendConfPdu());
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public void downloadMms(Uri contentUri, String locationUrl,
+ ICarrierMessagingCallback callback) {
+ try {
+ callback.onDownloadMmsComplete(onDownloadMms(contentUri, locationUrl));
+ } catch (RemoteException ex) {
+ }
+ }
+ }
+}
diff --git a/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java b/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java
new file mode 100644
index 0000000..56ee2c1
--- /dev/null
+++ b/core/java/android/service/carriermessaging/CarrierMessagingServiceManager.java
@@ -0,0 +1,97 @@
+/*
+ * 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.service.carriermessaging;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * Provides basic structure for platform to connect to the carrier messaging service.
+ * <p>
+ * <code>
+ * CarrierMessagingServiceManager carrierMessagingServiceManager =
+ * new CarrierMessagingServiceManagerImpl();
+ * if (carrierMessagingServiceManager.bindToCarrierMessagingService(context, carrierPackageName)) {
+ * // wait for onServiceReady callback
+ * } else {
+ * // Unable to bind: handle error.
+ * }
+ * </code>
+ * <p> Upon completion {@link #disposeConnection} should be called to unbind the
+ * CarrierMessagingService.
+ * @hide
+ */
+public abstract class CarrierMessagingServiceManager {
+ // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
+ // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
+ private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
+
+ /**
+ * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
+ * should be called exactly once.
+ *
+ * @param context the context
+ * @param carrierPackageName the carrier package name
+ * @return true upon successfully binding to a carrier messaging service, false otherwise
+ */
+ public boolean bindToCarrierMessagingService(Context context, String carrierPackageName) {
+ Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+
+ Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
+ intent.setPackage(carrierPackageName);
+ mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
+ return context.bindService(intent, mCarrierMessagingServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ /**
+ * Unbinds the carrier messaging service. This method should be called exactly once.
+ *
+ * @param context the context
+ */
+ public void disposeConnection(Context context) {
+ Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
+ context.unbindService(mCarrierMessagingServiceConnection);
+ mCarrierMessagingServiceConnection = null;
+ }
+
+ /**
+ * Implemented by subclasses to use the carrier messaging service once it is ready.
+ *
+ * @param carrierMessagingService the carirer messaing service interface
+ */
+ protected abstract void onServiceReady(ICarrierMessagingService carrierMessagingService);
+
+ /**
+ * A basic {@link ServiceConnection}.
+ */
+ private final class CarrierMessagingServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ onServiceReady(ICarrierMessagingService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ }
+}
diff --git a/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl b/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl
new file mode 100644
index 0000000..da56ad1
--- /dev/null
+++ b/core/java/android/service/carriermessaging/ICarrierMessagingCallback.aidl
@@ -0,0 +1,33 @@
+/**
+ * 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.service.carriermessaging;
+
+import android.service.carriermessaging.CarrierMessagingService;
+
+/**
+ * Callback interface definition for the Carrier Messaging Service client to get informed of the
+ * result of various API invocations.
+ */
+oneway interface ICarrierMessagingCallback {
+ void onFilterComplete(boolean keepMessage);
+ void onSendSmsComplete(
+ int result, in CarrierMessagingService.SendSmsResponse sendSmsResponse);
+ void onSendMultipartSmsComplete(
+ int result, in List<CarrierMessagingService.SendSmsResponse> sendSmsResponses);
+ void onSendMmsComplete(int result, in byte[] sendConfPdu);
+ void onDownloadMmsComplete(int result);
+}
diff --git a/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl b/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl
new file mode 100644
index 0000000..6e9e3fa
--- /dev/null
+++ b/core/java/android/service/carriermessaging/ICarrierMessagingService.aidl
@@ -0,0 +1,103 @@
+/**
+ * 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.service.carriermessaging;
+
+import android.net.Uri;
+import android.service.carriermessaging.ICarrierMessagingCallback;
+import android.service.carriermessaging.MessagePdu;
+
+/**
+ * <p class="note"><strong>Note:</strong>
+ * This service can only be implemented by a carrier privileged app.
+ */
+oneway interface ICarrierMessagingService {
+ /**
+ * Request filtering an incoming SMS message.
+ * The service will call callback.onFilterComplete with the filtering result.
+ *
+ * @param pdu the PDUs of the message
+ * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+ * @param destPort the destination port of a data SMS. It will be -1 for text SMS
+ * @param callback the callback to notify upon completion
+ */
+ void filterSms(
+ in MessagePdu pdu, String format, int destPort, in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param text the text to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendTextSms(String text, String format, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new data SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param data the data to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort port number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendDataSms(in byte[] data, String format, String destAddress, int destPort,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new multi-part text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMultipartSmsComplete}
+ * with the send status.
+ *
+ * @param parts the parts of the multi-part text SMS to send
+ * @param format the format of the response PDU, typically "3gpp" or "3gpp2"
+ * @param destAddress phone number of the recipient of the message
+ * @param callback the callback to notify upon completion
+ */
+ void sendMultipartTextSms(in List<String> parts, String format, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * Request sending a new MMS PDU from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMmsComplete} with the send
+ * status.
+ *
+ * @param pduUri the content provider URI of the PDU to send
+ * @param locationUrl the optional url to send this MMS PDU.
+ * If this is not specified, PDU should be sent to the default MMSC url.
+ * @param callback the callback to notify upon completion
+ */
+ void sendMms(in Uri pduUri, String locationUrl, in ICarrierMessagingCallback callback);
+
+ /**
+ * Request downloading a new MMS.
+ * The service will call {@link ICarrierMessagingCallback#onDownloadMmsComplete} with the
+ * download status.
+ *
+ * @param pduUri the content provider URI of the PDU to be downloaded.
+ * @param locationUrl the URL of the message to be downloaded.
+ * @param callback the callback to notify upon completion
+ */
+ void downloadMms(in Uri pduUri, String locationUrl, in ICarrierMessagingCallback callback);
+}
+
diff --git a/core/java/android/service/carriermessaging/MessagePdu.aidl b/core/java/android/service/carriermessaging/MessagePdu.aidl
new file mode 100644
index 0000000..82b3fb3
--- /dev/null
+++ b/core/java/android/service/carriermessaging/MessagePdu.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.service.carriermessaging;
+
+parcelable MessagePdu;
\ No newline at end of file
diff --git a/core/java/android/service/carriermessaging/MessagePdu.java b/core/java/android/service/carriermessaging/MessagePdu.java
new file mode 100644
index 0000000..b81719f
--- /dev/null
+++ b/core/java/android/service/carriermessaging/MessagePdu.java
@@ -0,0 +1,94 @@
+/*
+ * 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.service.carriermessaging;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A parcelable list of PDUs representing contents of a possibly multi-part SMS.
+ */
+public final class MessagePdu implements Parcelable {
+ private static final int NULL_LENGTH = -1;
+
+ private final List<byte[]> mPduList;
+
+ /**
+ * @param pduList the list of message PDUs
+ */
+ public MessagePdu(List<byte[]> pduList) {
+ mPduList = pduList;
+ }
+
+ /**
+ * Returns the contents of a possibly multi-part SMS.
+ *
+ * @return the list of PDUs
+ */
+ public List<byte[]> getPdus() {
+ return mPduList;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes the PDU into a {@link Parcel}.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (mPduList == null) {
+ dest.writeInt(NULL_LENGTH);
+ } else {
+ dest.writeInt(mPduList.size());
+ for (byte[] messagePdu : mPduList) {
+ dest.writeByteArray(messagePdu);
+ }
+ }
+ }
+
+ /**
+ * Constructs a {@link MessagePdu} from a {@link Parcel}.
+ */
+ public static final Parcelable.Creator<MessagePdu> CREATOR
+ = new Parcelable.Creator<MessagePdu>() {
+ @Override
+ public MessagePdu createFromParcel(Parcel source) {
+ int size = source.readInt();
+ List<byte[]> pduList;
+ if (size == NULL_LENGTH) {
+ pduList = null;
+ } else {
+ pduList = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ pduList.add(source.createByteArray());
+ }
+ }
+ return new MessagePdu(pduList);
+ }
+
+ @Override
+ public MessagePdu[] newArray(int size) {
+ return new MessagePdu[size];
+ }
+ };
+}
diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index e5f3b2c..92b19be 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -280,7 +280,7 @@
* @param path The target Path object.
*/
public static void nodesToPath(PathDataNode[] node, Path path) {
- float[] current = new float[4];
+ float[] current = new float[6];
char previousCommand = 'm';
for (int i = 0; i < node.length; i++) {
addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
@@ -313,6 +313,8 @@
float currentY = current[1];
float ctrlPointX = current[2];
float ctrlPointY = current[3];
+ float currentSegmentStartX = current[4];
+ float currentSegmentStartY = current[5];
float reflectiveCtrlPointX;
float reflectiveCtrlPointY;
@@ -320,7 +322,15 @@
case 'z':
case 'Z':
path.close();
- return;
+ // Path is closed here, but we need to move the pen to the
+ // closed position. So we cache the segment's starting position,
+ // and restore it here.
+ currentX = currentSegmentStartX;
+ currentY = currentSegmentStartY;
+ ctrlPointX = currentSegmentStartX;
+ ctrlPointY = currentSegmentStartY;
+ path.moveTo(currentX, currentY);
+ break;
case 'm':
case 'M':
case 'l':
@@ -350,17 +360,22 @@
incr = 7;
break;
}
+
for (int k = 0; k < val.length; k += incr) {
switch (cmd) {
case 'm': // moveto - Start a new sub-path (relative)
path.rMoveTo(val[k + 0], val[k + 1]);
currentX += val[k + 0];
currentY += val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
break;
case 'M': // moveto - Start a new sub-path
path.moveTo(val[k + 0], val[k + 1]);
currentX = val[k + 0];
currentY = val[k + 1];
+ currentSegmentStartX = currentX;
+ currentSegmentStartY = currentY;
break;
case 'l': // lineto - Draw a line from the current point (relative)
path.rLineTo(val[k + 0], val[k + 1]);
@@ -372,10 +387,6 @@
currentX = val[k + 0];
currentY = val[k + 1];
break;
- case 'z': // closepath - Close the current subpath
- case 'Z': // closepath - Close the current subpath
- path.close();
- break;
case 'h': // horizontal lineto - Draws a horizontal line (relative)
path.rLineTo(val[k + 0], 0);
currentX += val[k + 0];
@@ -526,6 +537,8 @@
current[1] = currentY;
current[2] = ctrlPointX;
current[3] = ctrlPointY;
+ current[4] = currentSegmentStartX;
+ current[5] = currentSegmentStartY;
}
private static void drawArc(Path p,
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index b86455a..6de06d4 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -994,4 +994,15 @@
int indexOffset, int indexCount, Paint paint) {
// TODO: Implement
}
+
+ @Override
+ public void setOverrideXfermode(PorterDuff.Mode xfermode) {
+ int xfermodeValue = -1;
+ if (xfermode != null) {
+ xfermodeValue = xfermode.nativeInt;
+ }
+ nSetOverrideXfermode(mRenderer, xfermodeValue);
+ }
+
+ private static native void nSetOverrideXfermode(long renderer, int xfermode);
}
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index 1ecdf30..e2ad3ad 100644
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -196,6 +196,13 @@
public abstract long getEventTimeNano();
/**
+ * Marks the input event as being canceled.
+ *
+ * @hide
+ */
+ public abstract void cancel();
+
+ /**
* Gets the unique sequence number of this event.
* Every input event that is created or received by a process has a
* unique sequence number. Moreover, a new sequence number is obtained
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 0701b53..243a0fc 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2304,6 +2304,16 @@
}
/**
+ * Set {@link #FLAG_CANCELED} flag for the key event.
+ *
+ * @hide
+ */
+ @Override
+ public final void cancel() {
+ mFlags |= FLAG_CANCELED;
+ }
+
+ /**
* Call this during {@link Callback#onKeyDown} to have the system track
* the key through its final up (possibly including a long press). Note
* that only one key can be tracked at a time -- if another key down
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ae39b7a..1c5c41c 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -3168,6 +3168,12 @@
return ev;
}
+ /** @hide */
+ @Override
+ public final void cancel() {
+ setAction(ACTION_CANCEL);
+ }
+
public void writeToParcel(Parcel out, int flags) {
out.writeInt(PARCEL_TOKEN_MOTION_EVENT);
nativeWriteToParcel(mNativePtr, out);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1d09696..77c1d7b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5901,6 +5901,12 @@
region.op(interactiveRegion, Region.Op.INTERSECT);
}
+ // Take into account the window bounds.
+ final View root = getRootView();
+ if (root != null) {
+ region.op(dx, dy, root.getWidth() + dx, root.getHeight() + dy, Region.Op.INTERSECT);
+ }
+
// If the view is completely covered, done.
if (region.isEmpty()) {
return false;
@@ -11842,7 +11848,7 @@
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
boolean fullInvalidate) {
if (mGhostView != null) {
- mGhostView.invalidate(invalidateCache);
+ mGhostView.invalidate(true);
return;
}
@@ -13174,7 +13180,7 @@
}
// Should resolve Drawables before Padding because we need the layout direction of the
// Drawable to correctly resolve Padding.
- if (!isDrawablesResolved()) {
+ if (!areDrawablesResolved()) {
resolveDrawables();
}
if (!isPaddingResolved()) {
@@ -13438,6 +13444,14 @@
* @hide
*/
public void resetResolvedPadding() {
+ resetResolvedPaddingInternal();
+ }
+
+ /**
+ * Used when we only want to reset *this* view's padding and not trigger overrides
+ * in ViewGroup that reset children too.
+ */
+ void resetResolvedPaddingInternal() {
mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
}
@@ -15974,6 +15988,10 @@
onResolveDrawables(layoutDirection);
}
+ boolean areDrawablesResolved() {
+ return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
+ }
+
/**
* Called when layout direction has been resolved.
*
@@ -15993,11 +16011,11 @@
* @hide
*/
protected void resetResolvedDrawables() {
- mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
+ resetResolvedDrawablesInternal();
}
- private boolean isDrawablesResolved() {
- return (mPrivateFlags2 & PFLAG2_DRAWABLE_RESOLVED) == PFLAG2_DRAWABLE_RESOLVED;
+ void resetResolvedDrawablesInternal() {
+ mPrivateFlags2 &= ~PFLAG2_DRAWABLE_RESOLVED;
}
/**
@@ -16297,10 +16315,10 @@
padding = new Rect();
sThreadLocal.set(padding);
}
- resetResolvedDrawables();
+ resetResolvedDrawablesInternal();
background.setLayoutDirection(getLayoutDirection());
if (background.getPadding(padding)) {
- resetResolvedPadding();
+ resetResolvedPaddingInternal();
switch (background.getLayoutDirection()) {
case LAYOUT_DIRECTION_RTL:
mUserPaddingLeftInitial = padding.right;
@@ -16500,7 +16518,7 @@
* @param bottom the bottom padding in pixels
*/
public void setPadding(int left, int top, int right, int bottom) {
- resetResolvedPadding();
+ resetResolvedPaddingInternal();
mUserPaddingStart = UNDEFINED_PADDING;
mUserPaddingEnd = UNDEFINED_PADDING;
@@ -16592,7 +16610,7 @@
* @param bottom the bottom padding in pixels
*/
public void setPaddingRelative(int start, int top, int end, int bottom) {
- resetResolvedPadding();
+ resetResolvedPaddingInternal();
mUserPaddingStart = start;
mUserPaddingEnd = end;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5c433c1..bae0b12 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5023,7 +5023,7 @@
rect.set(r);
if (!child.hasIdentityMatrix()) {
- child.getMatrix().mapRect(rect);
+ child.getMatrix().mapRect(rect);
}
int dx = child.mLeft - mScrollX;
@@ -5045,14 +5045,30 @@
offset.y += dy;
}
- if (rect.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {
- if (mParent == null) return true;
- r.set((int) (rect.left + 0.5f), (int) (rect.top + 0.5f),
- (int) (rect.right + 0.5f), (int) (rect.bottom + 0.5f));
- return mParent.getChildVisibleRect(this, r, offset);
+ boolean rectIsVisible = true;
+ if (mParent instanceof ViewGroup && ((ViewGroup)mParent).getClipChildren()) {
+ // clipChildren clips to the child's bounds
+ rectIsVisible = rect.intersect(0, 0, mRight - mLeft, mBottom - mTop);
}
- return false;
+ if (rectIsVisible && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
+ // Clip to padding
+ rectIsVisible = rect.intersect(mPaddingLeft, mPaddingTop,
+ mRight - mLeft - mPaddingLeft - mPaddingRight,
+ mBottom - mTop - mPaddingTop - mPaddingBottom);
+ }
+
+ if (rectIsVisible && mClipBounds != null) {
+ // Clip to clipBounds
+ rectIsVisible = rect.intersect(mClipBounds.left, mClipBounds.top, mClipBounds.right,
+ mClipBounds.bottom);
+ }
+ r.set((int) (rect.left + 0.5f), (int) (rect.top + 0.5f), (int) (rect.right + 0.5f),
+ (int) (rect.bottom + 0.5f));
+ if (rectIsVisible && mParent != null) {
+ rectIsVisible = mParent.getChildVisibleRect(this, r, offset);
+ }
+ return rectIsVisible;
}
/**
@@ -6134,7 +6150,7 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
- if (child.isLayoutDirectionInherited()) {
+ if (child.isLayoutDirectionInherited() && !child.isPaddingResolved()) {
child.resolvePadding();
}
}
@@ -6149,7 +6165,7 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
- if (child.isLayoutDirectionInherited()) {
+ if (child.isLayoutDirectionInherited() && !child.areDrawablesResolved()) {
child.resolveDrawables();
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5d2a24b..fe17417 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3596,12 +3596,19 @@
if (mView == null || !mAdded) {
Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
return true;
- } else if (!mAttachInfo.mHasWindowFocus &&
- !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) &&
- !isTerminalInputEvent(q.mEvent)) {
- // If this is a focused event and the window doesn't currently have input focus,
- // then drop this event. This could be an event that came back from the previous
- // stage but the window has lost focus in the meantime.
+ } else if ((!mAttachInfo.mHasWindowFocus || mStopped)
+ && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ // This is a focus event and the window doesn't currently have input focus or
+ // has stopped. This could be an event that came back from the previous stage
+ // but the window has lost focus or stopped in the meantime.
+ if (isTerminalInputEvent(q.mEvent)) {
+ // Don't drop terminal input events, however mark them as canceled.
+ q.mEvent.cancel();
+ Slog.w(TAG, "Cancelling event due to no window focus: " + q.mEvent);
+ return false;
+ }
+
+ // Drop non-terminal input events.
Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent);
return true;
}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 20ef646..eca96f9 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -16,18 +16,14 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.net.WebAddress;
/**
* Manages the cookies used by an application's {@link WebView} instances.
* Cookies are manipulated according to RFC2109.
*/
-public class CookieManager {
- /**
- * @hide Only for use by WebViewProvider implementations
- */
- protected CookieManager() {
- }
+public abstract class CookieManager {
@Override
protected Object clone() throws CloneNotSupportedException {
@@ -59,9 +55,7 @@
* @param accept whether {@link WebView} instances should send and accept
* cookies
*/
- public synchronized void setAcceptCookie(boolean accept) {
- throw new MustOverrideException();
- }
+ public abstract void setAcceptCookie(boolean accept);
/**
* Gets whether the application's {@link WebView} instances send and accept
@@ -69,9 +63,7 @@
*
* @return true if {@link WebView} instances send and accept cookies
*/
- public synchronized boolean acceptCookie() {
- throw new MustOverrideException();
- }
+ public abstract boolean acceptCookie();
/**
* Sets whether the {@link WebView} should allow third party cookies to be set.
@@ -87,9 +79,7 @@
* @param accept whether the {@link WebView} instance should accept
* third party cookies
*/
- public void setAcceptThirdPartyCookies(WebView webview, boolean accept) {
- throw new MustOverrideException();
- }
+ public abstract void setAcceptThirdPartyCookies(WebView webview, boolean accept);
/**
* Gets whether the {@link WebView} should allow third party cookies to be set.
@@ -97,9 +87,7 @@
* @param webview the {@link WebView} instance to get the cookie policy for
* @return true if the {@link WebView} accepts third party cookies
*/
- public boolean acceptThirdPartyCookies(WebView webview) {
- throw new MustOverrideException();
- }
+ public abstract boolean acceptThirdPartyCookies(WebView webview);
/**
* Sets a cookie for the given URL. Any existing cookie with the same host,
@@ -110,9 +98,7 @@
* @param value the cookie as a string, using the format of the 'Set-Cookie'
* HTTP response header
*/
- public void setCookie(String url, String value) {
- throw new MustOverrideException();
- }
+ public abstract void setCookie(String url, String value);
/**
* Sets a cookie for the given URL. Any existing cookie with the same host,
@@ -133,9 +119,7 @@
* HTTP response header
* @param callback a callback to be executed when the cookie has been set
*/
- public void setCookie(String url, String value, ValueCallback<Boolean> callback) {
- throw new MustOverrideException();
- }
+ public abstract void setCookie(String url, String value, ValueCallback<Boolean> callback);
/**
* Gets the cookies for the given URL.
@@ -144,9 +128,7 @@
* @return value the cookies as a string, using the format of the 'Cookie'
* HTTP request header
*/
- public String getCookie(String url) {
- throw new MustOverrideException();
- }
+ public abstract String getCookie(String url);
/**
* See {@link #getCookie(String)}.
@@ -155,11 +137,10 @@
* @param privateBrowsing whether to use the private browsing cookie jar
* @return value the cookies as a string, using the format of the 'Cookie'
* HTTP request header
- * @hide Used by Browser, no intention to publish.
+ * @hide Used by Browser and by WebViewProvider implementations.
*/
- public String getCookie(String url, boolean privateBrowsing) {
- throw new MustOverrideException();
- }
+ @SystemApi
+ public abstract String getCookie(String url, boolean privateBrowsing);
/**
* Gets cookie(s) for a given uri so that it can be set to "cookie:" in http
@@ -168,10 +149,11 @@
* @param uri the WebAddress for which the cookies are requested
* @return value the cookies as a string, using the format of the 'Cookie'
* HTTP request header
- * @hide Used by RequestHandle, no intention to publish.
+ * @hide Used by RequestHandle and by WebViewProvider implementations.
*/
+ @SystemApi
public synchronized String getCookie(WebAddress uri) {
- throw new MustOverrideException();
+ return getCookie(uri.toString());
}
/**
@@ -179,9 +161,7 @@
* date.
* @deprecated use {@link #removeSessionCookies(ValueCallback)} instead.
*/
- public void removeSessionCookie() {
- throw new MustOverrideException();
- }
+ public abstract void removeSessionCookie();
/**
* Removes all session cookies, which are cookies without an expiration
@@ -197,18 +177,14 @@
* method from a thread without a Looper.
* @param callback a callback which is executed when the session cookies have been removed
*/
- public void removeSessionCookies(ValueCallback<Boolean> callback) {
- throw new MustOverrideException();
- }
+ public abstract void removeSessionCookies(ValueCallback<Boolean> callback);
/**
* Removes all cookies.
* @deprecated Use {@link #removeAllCookies(ValueCallback)} instead.
*/
@Deprecated
- public void removeAllCookie() {
- throw new MustOverrideException();
- }
+ public abstract void removeAllCookie();
/**
* Removes all cookies.
@@ -223,54 +199,37 @@
* method from a thread without a Looper.
* @param callback a callback which is executed when the cookies have been removed
*/
- public void removeAllCookies(ValueCallback<Boolean> callback) {
- throw new MustOverrideException();
- }
+ public abstract void removeAllCookies(ValueCallback<Boolean> callback);
/**
* Gets whether there are stored cookies.
*
* @return true if there are stored cookies
*/
- public synchronized boolean hasCookies() {
- throw new MustOverrideException();
- }
+ public abstract boolean hasCookies();
/**
* See {@link #hasCookies()}.
*
* @param privateBrowsing whether to use the private browsing cookie jar
- * @hide Used by Browser, no intention to publish.
+ * @hide Used by Browser and WebViewProvider implementations.
*/
- public synchronized boolean hasCookies(boolean privateBrowsing) {
- throw new MustOverrideException();
- }
+ @SystemApi
+ public abstract boolean hasCookies(boolean privateBrowsing);
/**
* Removes all expired cookies.
* @deprecated The WebView handles removing expired cookies automatically.
*/
@Deprecated
- public void removeExpiredCookie() {
- throw new MustOverrideException();
- }
+ public abstract void removeExpiredCookie();
/**
* Ensures all cookies currently accessible through the getCookie API are
* written to persistent storage.
* This call will block the caller until it is done and may perform I/O.
*/
- public void flush() {
- flushCookieStore();
- }
-
- /**
- * Flushes all cookies managed by the Chrome HTTP stack to flash.
- *
- * @hide Package level api, called from CookieSyncManager
- */
- protected void flushCookieStore() {
- }
+ public abstract void flush();
/**
* Gets whether the application's {@link WebView} instances send and accept
@@ -289,9 +248,8 @@
*
* @hide Only for use by WebViewProvider implementations
*/
- protected boolean allowFileSchemeCookiesImpl() {
- throw new MustOverrideException();
- }
+ @SystemApi
+ protected abstract boolean allowFileSchemeCookiesImpl();
/**
* Sets whether the application's {@link WebView} instances should send and
@@ -314,7 +272,6 @@
*
* @hide Only for use by WebViewProvider implementations
*/
- protected void setAcceptFileSchemeCookiesImpl(boolean accept) {
- throw new MustOverrideException();
- }
+ @SystemApi
+ protected abstract void setAcceptFileSchemeCookiesImpl(boolean accept);
}
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
deleted file mode 100644
index 7b3cb1b..0000000
--- a/core/java/android/webkit/DebugFlags.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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.
- */
-
-package android.webkit;
-
-/**
- * This class is a container for all of the debug flags used in the Java
- * components of webkit. These flags must be final in order to ensure that
- * the compiler optimizes the code that uses them out of the final executable.
- *
- * The name of each flags maps directly to the name of the class in which that
- * flag is used.
- *
- * @hide Only used by WebView implementations.
- */
-public class DebugFlags {
-
- public static final boolean COOKIE_SYNC_MANAGER = false;
- public static final boolean TRACE_API = false;
- public static final boolean TRACE_CALLBACK = false;
- public static final boolean URL_UTIL = false;
- public static final boolean WEB_SYNC_MANAGER = false;
-
-}
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index c68b450..ab6a2f9 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
@@ -36,6 +37,7 @@
/**
* @hide
*/
+@SystemApi
public class FindActionModeCallback implements ActionMode.Callback, TextWatcher,
View.OnClickListener, WebView.FindListener {
private View mCustomView;
diff --git a/core/java/android/webkit/GeolocationPermissions.java b/core/java/android/webkit/GeolocationPermissions.java
index bc3d035..7187f22 100644
--- a/core/java/android/webkit/GeolocationPermissions.java
+++ b/core/java/android/webkit/GeolocationPermissions.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.SystemApi;
+
import java.util.Set;
/**
@@ -136,5 +138,6 @@
* way to call createHandler() and createUIHandler(), so it would not work).
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public GeolocationPermissions() {}
}
diff --git a/core/java/android/webkit/HttpAuthHandler.java b/core/java/android/webkit/HttpAuthHandler.java
index ee3b3698..45fc1f5 100644
--- a/core/java/android/webkit/HttpAuthHandler.java
+++ b/core/java/android/webkit/HttpAuthHandler.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.os.Handler;
/**
@@ -30,6 +31,7 @@
/**
* @hide Only for use by WebViewProvider implementations.
*/
+ @SystemApi
public HttpAuthHandler() {
}
diff --git a/core/java/android/webkit/JsDialogHelper.java b/core/java/android/webkit/JsDialogHelper.java
index bb0339e..cc475c3 100644
--- a/core/java/android/webkit/JsDialogHelper.java
+++ b/core/java/android/webkit/JsDialogHelper.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
@@ -34,8 +35,9 @@
* Helper class to create JavaScript dialogs. It is used by
* different WebView implementations.
*
- * @hide Helper class for internal use
+ * @hide
*/
+@SystemApi
public class JsDialogHelper {
private static final String TAG = "JsDialogHelper";
diff --git a/core/java/android/webkit/JsPromptResult.java b/core/java/android/webkit/JsPromptResult.java
index a1bf124..771cc32 100644
--- a/core/java/android/webkit/JsPromptResult.java
+++ b/core/java/android/webkit/JsPromptResult.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.SystemApi;
+
/**
* Public class for handling JavaScript prompt requests. The WebChromeClient will receive a
@@ -39,6 +41,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public JsPromptResult(ResultReceiver receiver) {
super(receiver);
}
@@ -46,6 +49,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public String getStringResult() {
return mStringResult;
}
diff --git a/core/java/android/webkit/JsResult.java b/core/java/android/webkit/JsResult.java
index e4e6851..d36ab418 100644
--- a/core/java/android/webkit/JsResult.java
+++ b/core/java/android/webkit/JsResult.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.SystemApi;
+
/**
* An instance of this class is passed as a parameter in various {@link WebChromeClient} action
* notifications. The object is used as a handle onto the underlying JavaScript-originated request,
@@ -27,6 +29,7 @@
* notifications when the JavaScript result represented by a JsResult instance has
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public interface ResultReceiver {
public void onJsResultComplete(JsResult result);
}
@@ -54,6 +57,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public JsResult(ResultReceiver receiver) {
mReceiver = receiver;
}
@@ -61,6 +65,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public final boolean getResult() {
return mResult;
}
diff --git a/core/java/android/webkit/MustOverrideException.java b/core/java/android/webkit/MustOverrideException.java
deleted file mode 100644
index 0643bf0..0000000
--- a/core/java/android/webkit/MustOverrideException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2012 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.webkit;
-
-// TODO: Remove MustOverrideException and make all methods throwing it abstract instead;
-// needs API file update.
-class MustOverrideException extends RuntimeException {
- MustOverrideException() {
- super("abstract function called: must be overriden!");
- }
-}
\ No newline at end of file
diff --git a/core/java/android/webkit/SslErrorHandler.java b/core/java/android/webkit/SslErrorHandler.java
index af31544..537065d 100644
--- a/core/java/android/webkit/SslErrorHandler.java
+++ b/core/java/android/webkit/SslErrorHandler.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.os.Handler;
/**
@@ -30,6 +31,7 @@
/**
* @hide Only for use by WebViewProvider implementations.
*/
+ @SystemApi
public SslErrorHandler() {}
/**
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index d115984..f5233b6 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -29,6 +29,7 @@
public final class URLUtil {
private static final String LOGTAG = "webkit";
+ private static final boolean TRACE = false;
// to refer to bar.png under your package's asset/foo/ directory, use
// "file:///android_asset/foo/bar.png".
@@ -49,7 +50,7 @@
String retVal = inUrl;
WebAddress webAddress;
- if (DebugFlags.URL_UTIL) Log.v(LOGTAG, "guessURL before queueRequest: " + inUrl);
+ if (TRACE) Log.v(LOGTAG, "guessURL before queueRequest: " + inUrl);
if (inUrl.length() == 0) return inUrl;
if (inUrl.startsWith("about:")) return inUrl;
@@ -69,7 +70,7 @@
webAddress = new WebAddress(inUrl);
} catch (ParseException ex) {
- if (DebugFlags.URL_UTIL) {
+ if (TRACE) {
Log.v(LOGTAG, "smartUrlFilter: failed to parse url = " + inUrl);
}
return retVal;
@@ -286,7 +287,7 @@
}
return url;
}
-
+
/**
* Guesses canonical filename that a download would have, using
* the URL and contentDisposition. File extension, if not defined,
@@ -294,7 +295,7 @@
* @param url Url to the content
* @param contentDisposition Content-Disposition HTTP header or null
* @param mimeType Mime-type of the content or null
- *
+ *
* @return suggested filename
*/
public static final String guessFileName(
diff --git a/core/java/android/webkit/WebBackForwardList.java b/core/java/android/webkit/WebBackForwardList.java
index bfef2e7..e671376 100644
--- a/core/java/android/webkit/WebBackForwardList.java
+++ b/core/java/android/webkit/WebBackForwardList.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import java.io.Serializable;
/**
@@ -23,56 +24,38 @@
* WebView.copyBackForwardList() will return a copy of this class used to
* inspect the entries in the list.
*/
-public class WebBackForwardList implements Cloneable, Serializable {
-
- /**
- * @hide
- */
- public WebBackForwardList() {
- }
-
+public abstract class WebBackForwardList implements Cloneable, Serializable {
/**
* Return the current history item. This method returns null if the list is
* empty.
* @return The current history item.
*/
- public synchronized WebHistoryItem getCurrentItem() {
- throw new MustOverrideException();
- }
+ public abstract WebHistoryItem getCurrentItem();
/**
* Get the index of the current history item. This index can be used to
* directly index into the array list.
* @return The current index from 0...n or -1 if the list is empty.
*/
- public synchronized int getCurrentIndex() {
- throw new MustOverrideException();
- }
+ public abstract int getCurrentIndex();
/**
* Get the history item at the given index. The index range is from 0...n
* where 0 is the first item and n is the last item.
* @param index The index to retrieve.
*/
- public synchronized WebHistoryItem getItemAtIndex(int index) {
- throw new MustOverrideException();
- }
+ public abstract WebHistoryItem getItemAtIndex(int index);
/**
* Get the total size of the back/forward list.
* @return The size of the list.
*/
- public synchronized int getSize() {
- throw new MustOverrideException();
- }
+ public abstract int getSize();
/**
* Clone the entire object to be used in the UI thread by clients of
* WebView. This creates a copy that should never be modified by any of the
* webkit package classes.
*/
- protected synchronized WebBackForwardList clone() {
- throw new MustOverrideException();
- }
-
+ protected abstract WebBackForwardList clone();
}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 46a7fd0..768dc9f 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
@@ -509,6 +510,7 @@
* @deprecated Use {@link #showFileChooser} instead.
* @hide This method was not published in any SDK version.
*/
+ @SystemApi
@Deprecated
public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
uploadFile.onReceiveValue(null);
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index 9a588e4..569fccd 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.graphics.Bitmap;
/**
@@ -24,14 +25,7 @@
* item. Each history item may be updated during the load of a page.
* @see WebBackForwardList
*/
-public class WebHistoryItem implements Cloneable {
-
- /**
- * @hide
- */
- public WebHistoryItem() {
- }
-
+public abstract class WebHistoryItem implements Cloneable {
/**
* Return an identifier for this history item. If an item is a copy of
* another item, the identifiers will be the same even if they are not the
@@ -40,10 +34,9 @@
* @deprecated This method is now obsolete.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public int getId() {
- throw new MustOverrideException();
- }
+ public abstract int getId();
/**
* Return the url of this history item. The url is the base url of this
@@ -53,29 +46,23 @@
* Note: The VM ensures 32-bit atomic read/write operations so we don't have
* to synchronize this method.
*/
- public String getUrl() {
- throw new MustOverrideException();
- }
+ public abstract String getUrl();
/**
* Return the original url of this history item. This was the requested
- * url, the final url may be different as there might have been
+ * url, the final url may be different as there might have been
* redirects while loading the site.
* @return The original url of this history item.
*/
- public String getOriginalUrl() {
- throw new MustOverrideException();
- }
-
+ public abstract String getOriginalUrl();
+
/**
* Return the document title of this history item.
* @return The document title of this history item.
* Note: The VM ensures 32-bit atomic read/write operations so we don't have
* to synchronize this method.
*/
- public String getTitle() {
- throw new MustOverrideException();
- }
+ public abstract String getTitle();
/**
* Return the favicon of this history item or null if no favicon was found.
@@ -83,15 +70,10 @@
* Note: The VM ensures 32-bit atomic read/write operations so we don't have
* to synchronize this method.
*/
- public Bitmap getFavicon() {
- throw new MustOverrideException();
- }
+ public abstract Bitmap getFavicon();
/**
* Clone the history item for use by clients of WebView.
*/
- protected synchronized WebHistoryItem clone() {
- throw new MustOverrideException();
- }
-
+ protected abstract WebHistoryItem clone();
}
diff --git a/core/java/android/webkit/WebIconDatabase.java b/core/java/android/webkit/WebIconDatabase.java
index e574593..08956e0 100644
--- a/core/java/android/webkit/WebIconDatabase.java
+++ b/core/java/android/webkit/WebIconDatabase.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.ContentResolver;
import android.graphics.Bitmap;
@@ -32,7 +33,7 @@
* up to {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
*/
@Deprecated
-public class WebIconDatabase {
+public abstract class WebIconDatabase {
/**
* Interface for receiving icons from the database.
* @deprecated This interface is obsolete.
@@ -52,23 +53,17 @@
* Open a the icon database and store the icons in the given path.
* @param path The directory path where the icon database will be stored.
*/
- public void open(String path) {
- throw new MustOverrideException();
- }
+ public abstract void open(String path);
/**
* Close the shared instance of the icon database.
*/
- public void close() {
- throw new MustOverrideException();
- }
+ public abstract void close();
/**
* Removes all the icons in the database.
*/
- public void removeAllIcons() {
- throw new MustOverrideException();
- }
+ public abstract void removeAllIcons();
/**
* Request the Bitmap representing the icon for the given page
@@ -76,32 +71,25 @@
* @param url The page's url.
* @param listener An implementation on IconListener to receive the result.
*/
- public void requestIconForPageUrl(String url, IconListener listener) {
- throw new MustOverrideException();
- }
+ public abstract void requestIconForPageUrl(String url, IconListener listener);
/** {@hide}
*/
- public void bulkRequestIconForPageUrl(ContentResolver cr, String where,
- IconListener listener) {
- throw new MustOverrideException();
- }
+ @SystemApi
+ public abstract void bulkRequestIconForPageUrl(ContentResolver cr, String where,
+ IconListener listener);
/**
* Retain the icon for the given page url.
* @param url The page's url.
*/
- public void retainIconForPageUrl(String url) {
- throw new MustOverrideException();
- }
+ public abstract void retainIconForPageUrl(String url);
/**
* Release the icon for the given page url.
* @param url The page's url.
*/
- public void releaseIconForPageUrl(String url) {
- throw new MustOverrideException();
- }
+ public abstract void releaseIconForPageUrl(String url);
/**
* Get the global instance of WebIconDatabase.
@@ -113,9 +101,4 @@
// XXX: Must be created in the UI thread.
return WebViewFactory.getProvider().getWebIconDatabase();
}
-
- /**
- * @hide Only for use by WebViewProvider implementations
- */
- protected WebIconDatabase() {}
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 7cf3cb5..1d2c311 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -204,25 +204,15 @@
public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2;
/**
- * Hidden constructor to prevent clients from creating a new settings
- * instance or deriving the class.
- *
- * @hide
- */
- protected WebSettings() {
- }
-
- /**
* Enables dumping the pages navigation cache to a text file. The default
* is false.
*
* @deprecated This method is now obsolete.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public void setNavDump(boolean enabled) {
- throw new MustOverrideException();
- }
+ public abstract void setNavDump(boolean enabled);
/**
* Gets whether dumping the navigation cache is enabled.
@@ -232,10 +222,9 @@
* @deprecated This method is now obsolete.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public boolean getNavDump() {
- throw new MustOverrideException();
- }
+ public abstract boolean getNavDump();
/**
* Sets whether the WebView should support zooming using its on-screen zoom
@@ -246,9 +235,7 @@
*
* @param support whether the WebView should support zoom
*/
- public void setSupportZoom(boolean support) {
- throw new MustOverrideException();
- }
+ public abstract void setSupportZoom(boolean support);
/**
* Gets whether the WebView supports zoom.
@@ -256,9 +243,7 @@
* @return true if the WebView supports zoom
* @see #setSupportZoom
*/
- public boolean supportZoom() {
- throw new MustOverrideException();
- }
+ public abstract boolean supportZoom();
/**
* Sets whether the WebView requires a user gesture to play media.
@@ -266,9 +251,7 @@
*
* @param require whether the WebView requires a user gesture to play media
*/
- public void setMediaPlaybackRequiresUserGesture(boolean require) {
- throw new MustOverrideException();
- }
+ public abstract void setMediaPlaybackRequiresUserGesture(boolean require);
/**
* Gets whether the WebView requires a user gesture to play media.
@@ -276,9 +259,7 @@
* @return true if the WebView requires a user gesture to play media
* @see #setMediaPlaybackRequiresUserGesture
*/
- public boolean getMediaPlaybackRequiresUserGesture() {
- throw new MustOverrideException();
- }
+ public abstract boolean getMediaPlaybackRequiresUserGesture();
/**
* Sets whether the WebView should use its built-in zoom mechanisms. The
@@ -295,9 +276,7 @@
// This method was intended to select between the built-in zoom mechanisms
// and the separate zoom controls. The latter were obtained using
// {@link WebView#getZoomControls}, which is now hidden.
- public void setBuiltInZoomControls(boolean enabled) {
- throw new MustOverrideException();
- }
+ public abstract void setBuiltInZoomControls(boolean enabled);
/**
* Gets whether the zoom mechanisms built into WebView are being used.
@@ -305,9 +284,7 @@
* @return true if the zoom mechanisms built into WebView are being used
* @see #setBuiltInZoomControls
*/
- public boolean getBuiltInZoomControls() {
- throw new MustOverrideException();
- }
+ public abstract boolean getBuiltInZoomControls();
/**
* Sets whether the WebView should display on-screen zoom controls when
@@ -316,9 +293,7 @@
*
* @param enabled whether the WebView should display on-screen zoom controls
*/
- public void setDisplayZoomControls(boolean enabled) {
- throw new MustOverrideException();
- }
+ public abstract void setDisplayZoomControls(boolean enabled);
/**
* Gets whether the WebView displays on-screen zoom controls when using
@@ -328,9 +303,7 @@
* the built-in zoom mechanisms
* @see #setDisplayZoomControls
*/
- public boolean getDisplayZoomControls() {
- throw new MustOverrideException();
- }
+ public abstract boolean getDisplayZoomControls();
/**
* Enables or disables file access within WebView. File access is enabled by
@@ -338,36 +311,28 @@
* Assets and resources are still accessible using file:///android_asset and
* file:///android_res.
*/
- public void setAllowFileAccess(boolean allow) {
- throw new MustOverrideException();
- }
+ public abstract void setAllowFileAccess(boolean allow);
/**
* Gets whether this WebView supports file access.
*
* @see #setAllowFileAccess
*/
- public boolean getAllowFileAccess() {
- throw new MustOverrideException();
- }
+ public abstract boolean getAllowFileAccess();
/**
* Enables or disables content URL access within WebView. Content URL
* access allows WebView to load content from a content provider installed
* in the system. The default is enabled.
*/
- public void setAllowContentAccess(boolean allow) {
- throw new MustOverrideException();
- }
+ public abstract void setAllowContentAccess(boolean allow);
/**
* Gets whether this WebView supports content URL access.
*
* @see #setAllowContentAccess
*/
- public boolean getAllowContentAccess() {
- throw new MustOverrideException();
- }
+ public abstract boolean getAllowContentAccess();
/**
* Sets whether the WebView loads pages in overview mode, that is,
@@ -376,9 +341,7 @@
* of the WebView control, for example, when {@link #getUseWideViewPort}
* is enabled. The default is false.
*/
- public void setLoadWithOverviewMode(boolean overview) {
- throw new MustOverrideException();
- }
+ public abstract void setLoadWithOverviewMode(boolean overview);
/**
* Gets whether this WebView loads pages in overview mode.
@@ -386,9 +349,7 @@
* @return whether this WebView loads pages in overview mode
* @see #setLoadWithOverviewMode
*/
- public boolean getLoadWithOverviewMode() {
- throw new MustOverrideException();
- }
+ public abstract boolean getLoadWithOverviewMode();
/**
* Sets whether the WebView will enable smooth transition while panning or
@@ -400,9 +361,7 @@
* @deprecated This method is now obsolete, and will become a no-op in future.
*/
@Deprecated
- public void setEnableSmoothTransition(boolean enable) {
- throw new MustOverrideException();
- }
+ public abstract void setEnableSmoothTransition(boolean enable);
/**
* Gets whether the WebView enables smooth transition while panning or
@@ -413,9 +372,7 @@
* @deprecated This method is now obsolete, and will become a no-op in future.
*/
@Deprecated
- public boolean enableSmoothTransition() {
- throw new MustOverrideException();
- }
+ public abstract boolean enableSmoothTransition();
/**
* Sets whether the WebView uses its background for over scroll background.
@@ -425,10 +382,9 @@
* @deprecated This method is now obsolete.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
- throw new MustOverrideException();
- }
+ public abstract void setUseWebViewBackgroundForOverscrollBackground(boolean view);
/**
* Gets whether this WebView uses WebView's background instead of
@@ -438,17 +394,14 @@
* @deprecated This method is now obsolete.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public boolean getUseWebViewBackgroundForOverscrollBackground() {
- throw new MustOverrideException();
- }
+ public abstract boolean getUseWebViewBackgroundForOverscrollBackground();
/**
* Sets whether the WebView should save form data. The default is true.
*/
- public void setSaveFormData(boolean save) {
- throw new MustOverrideException();
- }
+ public abstract void setSaveFormData(boolean save);
/**
* Gets whether the WebView saves form data.
@@ -456,18 +409,14 @@
* @return whether the WebView saves form data
* @see #setSaveFormData
*/
- public boolean getSaveFormData() {
- throw new MustOverrideException();
- }
+ public abstract boolean getSaveFormData();
/**
* Sets whether the WebView should save passwords. The default is true.
* @deprecated Saving passwords in WebView will not be supported in future versions.
*/
@Deprecated
- public void setSavePassword(boolean save) {
- throw new MustOverrideException();
- }
+ public abstract void setSavePassword(boolean save);
/**
* Gets whether the WebView saves passwords.
@@ -477,18 +426,14 @@
* @deprecated Saving passwords in WebView will not be supported in future versions.
*/
@Deprecated
- public boolean getSavePassword() {
- throw new MustOverrideException();
- }
+ public abstract boolean getSavePassword();
/**
* Sets the text zoom of the page in percent. The default is 100.
*
* @param textZoom the text zoom in percent
*/
- public synchronized void setTextZoom(int textZoom) {
- throw new MustOverrideException();
- }
+ public abstract void setTextZoom(int textZoom);
/**
* Gets the text zoom of the page in percent.
@@ -496,27 +441,23 @@
* @return the text zoom of the page in percent
* @see #setTextZoom
*/
- public synchronized int getTextZoom() {
- throw new MustOverrideException();
- }
+ public abstract int getTextZoom();
/**
* Sets policy for third party cookies.
* Developers should access this via {@link CookieManager#setShouldAcceptThirdPartyCookies}.
* @hide Internal API.
*/
- public void setAcceptThirdPartyCookies(boolean accept) {
- throw new MustOverrideException();
- }
+ @SystemApi
+ public abstract void setAcceptThirdPartyCookies(boolean accept);
/**
* Gets policy for third party cookies.
* Developers should access this via {@link CookieManager#getShouldAcceptThirdPartyCookies}.
* @hide Internal API
*/
- public boolean getAcceptThirdPartyCookies() {
- throw new MustOverrideException();
- }
+ @SystemApi
+ public abstract boolean getAcceptThirdPartyCookies();
/**
* Sets the text size of the page. The default is {@link TextSize#NORMAL}.
@@ -569,9 +510,7 @@
* recommended alternatives.
*/
@Deprecated
- public void setDefaultZoom(ZoomDensity zoom) {
- throw new MustOverrideException();
- }
+ public abstract void setDefaultZoom(ZoomDensity zoom);
/**
* Gets the default zoom density of the page. This should be called from
@@ -583,9 +522,7 @@
* @see #setDefaultZoom
* @deprecated Will only return the default value.
*/
- public ZoomDensity getDefaultZoom() {
- throw new MustOverrideException();
- }
+ public abstract ZoomDensity getDefaultZoom();
/**
* Enables using light touches to make a selection and activate mouseovers.
@@ -593,9 +530,7 @@
* setting is obsolete and has no effect.
*/
@Deprecated
- public void setLightTouchEnabled(boolean enabled) {
- throw new MustOverrideException();
- }
+ public abstract void setLightTouchEnabled(boolean enabled);
/**
* Gets whether light touches are enabled.
@@ -603,9 +538,7 @@
* @deprecated This setting is obsolete.
*/
@Deprecated
- public boolean getLightTouchEnabled() {
- throw new MustOverrideException();
- }
+ public abstract boolean getLightTouchEnabled();
/**
* Controlled a rendering optimization that is no longer present. Setting
@@ -615,7 +548,7 @@
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
@Deprecated
- public synchronized void setUseDoubleTree(boolean use) {
+ public void setUseDoubleTree(boolean use) {
// Specified to do nothing, so no need for derived classes to override.
}
@@ -627,7 +560,7 @@
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
@Deprecated
- public synchronized boolean getUseDoubleTree() {
+ public boolean getUseDoubleTree() {
// Returns false unconditionally, so no need for derived classes to override.
return false;
}
@@ -645,10 +578,9 @@
* @deprecated Please use {@link #setUserAgentString} instead.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public synchronized void setUserAgent(int ua) {
- throw new MustOverrideException();
- }
+ public abstract void setUserAgent(int ua);
/**
* Gets the user-agent as an integer code.
@@ -664,10 +596,9 @@
* @deprecated Please use {@link #getUserAgentString} instead.
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
+ @SystemApi
@Deprecated
- public synchronized int getUserAgent() {
- throw new MustOverrideException();
- }
+ public abstract int getUserAgent();
/**
* Sets whether the WebView should enable support for the "viewport"
@@ -680,9 +611,7 @@
*
* @param use whether to enable support for the viewport meta tag
*/
- public synchronized void setUseWideViewPort(boolean use) {
- throw new MustOverrideException();
- }
+ public abstract void setUseWideViewPort(boolean use);
/**
* Gets whether the WebView supports the "viewport"
@@ -691,9 +620,7 @@
* @return true if the WebView supports the viewport meta tag
* @see #setUseWideViewPort
*/
- public synchronized boolean getUseWideViewPort() {
- throw new MustOverrideException();
- }
+ public abstract boolean getUseWideViewPort();
/**
* Sets whether the WebView whether supports multiple windows. If set to
@@ -702,9 +629,7 @@
*
* @param support whether to suport multiple windows
*/
- public synchronized void setSupportMultipleWindows(boolean support) {
- throw new MustOverrideException();
- }
+ public abstract void setSupportMultipleWindows(boolean support);
/**
* Gets whether the WebView supports multiple windows.
@@ -712,9 +637,7 @@
* @return true if the WebView supports multiple windows
* @see #setSupportMultipleWindows
*/
- public synchronized boolean supportMultipleWindows() {
- throw new MustOverrideException();
- }
+ public abstract boolean supportMultipleWindows();
/**
* Sets the underlying layout algorithm. This will cause a relayout of the
@@ -722,9 +645,7 @@
*
* @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value
*/
- public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
- throw new MustOverrideException();
- }
+ public abstract void setLayoutAlgorithm(LayoutAlgorithm l);
/**
* Gets the current layout algorithm.
@@ -732,18 +653,14 @@
* @return the layout algorithm in use, as a {@link LayoutAlgorithm} value
* @see #setLayoutAlgorithm
*/
- public synchronized LayoutAlgorithm getLayoutAlgorithm() {
- throw new MustOverrideException();
- }
+ public abstract LayoutAlgorithm getLayoutAlgorithm();
/**
* Sets the standard font family name. The default is "sans-serif".
*
* @param font a font family name
*/
- public synchronized void setStandardFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setStandardFontFamily(String font);
/**
* Gets the standard font family name.
@@ -751,18 +668,14 @@
* @return the standard font family name as a string
* @see #setStandardFontFamily
*/
- public synchronized String getStandardFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getStandardFontFamily();
/**
* Sets the fixed font family name. The default is "monospace".
*
* @param font a font family name
*/
- public synchronized void setFixedFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setFixedFontFamily(String font);
/**
* Gets the fixed font family name.
@@ -770,18 +683,14 @@
* @return the fixed font family name as a string
* @see #setFixedFontFamily
*/
- public synchronized String getFixedFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getFixedFontFamily();
/**
* Sets the sans-serif font family name. The default is "sans-serif".
*
* @param font a font family name
*/
- public synchronized void setSansSerifFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setSansSerifFontFamily(String font);
/**
* Gets the sans-serif font family name.
@@ -789,18 +698,14 @@
* @return the sans-serif font family name as a string
* @see #setSansSerifFontFamily
*/
- public synchronized String getSansSerifFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getSansSerifFontFamily();
/**
* Sets the serif font family name. The default is "sans-serif".
*
* @param font a font family name
*/
- public synchronized void setSerifFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setSerifFontFamily(String font);
/**
* Gets the serif font family name. The default is "serif".
@@ -808,18 +713,14 @@
* @return the serif font family name as a string
* @see #setSerifFontFamily
*/
- public synchronized String getSerifFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getSerifFontFamily();
/**
* Sets the cursive font family name. The default is "cursive".
*
* @param font a font family name
*/
- public synchronized void setCursiveFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setCursiveFontFamily(String font);
/**
* Gets the cursive font family name.
@@ -827,18 +728,14 @@
* @return the cursive font family name as a string
* @see #setCursiveFontFamily
*/
- public synchronized String getCursiveFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getCursiveFontFamily();
/**
* Sets the fantasy font family name. The default is "fantasy".
*
* @param font a font family name
*/
- public synchronized void setFantasyFontFamily(String font) {
- throw new MustOverrideException();
- }
+ public abstract void setFantasyFontFamily(String font);
/**
* Gets the fantasy font family name.
@@ -846,9 +743,7 @@
* @return the fantasy font family name as a string
* @see #setFantasyFontFamily
*/
- public synchronized String getFantasyFontFamily() {
- throw new MustOverrideException();
- }
+ public abstract String getFantasyFontFamily();
/**
* Sets the minimum font size. The default is 8.
@@ -856,9 +751,7 @@
* @param size a non-negative integer between 1 and 72. Any number outside
* the specified range will be pinned.
*/
- public synchronized void setMinimumFontSize(int size) {
- throw new MustOverrideException();
- }
+ public abstract void setMinimumFontSize(int size);
/**
* Gets the minimum font size.
@@ -866,9 +759,7 @@
* @return a non-negative integer between 1 and 72
* @see #setMinimumFontSize
*/
- public synchronized int getMinimumFontSize() {
- throw new MustOverrideException();
- }
+ public abstract int getMinimumFontSize();
/**
* Sets the minimum logical font size. The default is 8.
@@ -876,9 +767,7 @@
* @param size a non-negative integer between 1 and 72. Any number outside
* the specified range will be pinned.
*/
- public synchronized void setMinimumLogicalFontSize(int size) {
- throw new MustOverrideException();
- }
+ public abstract void setMinimumLogicalFontSize(int size);
/**
* Gets the minimum logical font size.
@@ -886,9 +775,7 @@
* @return a non-negative integer between 1 and 72
* @see #setMinimumLogicalFontSize
*/
- public synchronized int getMinimumLogicalFontSize() {
- throw new MustOverrideException();
- }
+ public abstract int getMinimumLogicalFontSize();
/**
* Sets the default font size. The default is 16.
@@ -896,9 +783,7 @@
* @param size a non-negative integer between 1 and 72. Any number outside
* the specified range will be pinned.
*/
- public synchronized void setDefaultFontSize(int size) {
- throw new MustOverrideException();
- }
+ public abstract void setDefaultFontSize(int size);
/**
* Gets the default font size.
@@ -906,9 +791,7 @@
* @return a non-negative integer between 1 and 72
* @see #setDefaultFontSize
*/
- public synchronized int getDefaultFontSize() {
- throw new MustOverrideException();
- }
+ public abstract int getDefaultFontSize();
/**
* Sets the default fixed font size. The default is 16.
@@ -916,9 +799,7 @@
* @param size a non-negative integer between 1 and 72. Any number outside
* the specified range will be pinned.
*/
- public synchronized void setDefaultFixedFontSize(int size) {
- throw new MustOverrideException();
- }
+ public abstract void setDefaultFixedFontSize(int size);
/**
* Gets the default fixed font size.
@@ -926,9 +807,7 @@
* @return a non-negative integer between 1 and 72
* @see #setDefaultFixedFontSize
*/
- public synchronized int getDefaultFixedFontSize() {
- throw new MustOverrideException();
- }
+ public abstract int getDefaultFixedFontSize();
/**
* Sets whether the WebView should load image resources. Note that this method
@@ -941,9 +820,7 @@
*
* @param flag whether the WebView should load image resources
*/
- public synchronized void setLoadsImagesAutomatically(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setLoadsImagesAutomatically(boolean flag);
/**
* Gets whether the WebView loads image resources. This includes
@@ -952,9 +829,7 @@
* @return true if the WebView loads image resources
* @see #setLoadsImagesAutomatically
*/
- public synchronized boolean getLoadsImagesAutomatically() {
- throw new MustOverrideException();
- }
+ public abstract boolean getLoadsImagesAutomatically();
/**
* Sets whether the WebView should not load image resources from the
@@ -971,9 +846,7 @@
* network
* @see #setBlockNetworkLoads
*/
- public synchronized void setBlockNetworkImage(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setBlockNetworkImage(boolean flag);
/**
* Gets whether the WebView does not load image resources from the network.
@@ -981,9 +854,7 @@
* @return true if the WebView does not load image resources from the network
* @see #setBlockNetworkImage
*/
- public synchronized boolean getBlockNetworkImage() {
- throw new MustOverrideException();
- }
+ public abstract boolean getBlockNetworkImage();
/**
* Sets whether the WebView should not load resources from the network.
@@ -1003,9 +874,7 @@
* network
* @see android.webkit.WebView#reload
*/
- public synchronized void setBlockNetworkLoads(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setBlockNetworkLoads(boolean flag);
/**
* Gets whether the WebView does not load any resources from the network.
@@ -1013,9 +882,7 @@
* @return true if the WebView does not load any resources from the network
* @see #setBlockNetworkLoads
*/
- public synchronized boolean getBlockNetworkLoads() {
- throw new MustOverrideException();
- }
+ public abstract boolean getBlockNetworkLoads();
/**
* Tells the WebView to enable JavaScript execution.
@@ -1023,9 +890,7 @@
*
* @param flag true if the WebView should execute JavaScript
*/
- public synchronized void setJavaScriptEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setJavaScriptEnabled(boolean flag);
/**
* Sets whether JavaScript running in the context of a file scheme URL
@@ -1076,10 +941,9 @@
* {@link #setPluginState}
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
*/
+ @SystemApi
@Deprecated
- public synchronized void setPluginsEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setPluginsEnabled(boolean flag);
/**
* Tells the WebView to enable, disable, or have plugins on demand. On
@@ -1092,9 +956,7 @@
* @deprecated Plugins will not be supported in future, and should not be used.
*/
@Deprecated
- public synchronized void setPluginState(PluginState state) {
- throw new MustOverrideException();
- }
+ public abstract void setPluginState(PluginState state);
/**
* Sets a custom path to plugins used by the WebView. This method is
@@ -1106,7 +968,7 @@
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
*/
@Deprecated
- public synchronized void setPluginsPath(String pluginsPath) {
+ public void setPluginsPath(String pluginsPath) {
// Specified to do nothing, so no need for derived classes to override.
}
@@ -1125,9 +987,7 @@
// Note that the WebCore Database Tracker only allows the path to be set
// once.
@Deprecated
- public synchronized void setDatabasePath(String databasePath) {
- throw new MustOverrideException();
- }
+ public abstract void setDatabasePath(String databasePath);
/**
* Sets the path where the Geolocation databases should be saved. In order
@@ -1138,9 +998,7 @@
* saved.
*/
// This will update WebCore when the Sync runs in the C++ side.
- public synchronized void setGeolocationDatabasePath(String databasePath) {
- throw new MustOverrideException();
- }
+ public abstract void setGeolocationDatabasePath(String databasePath);
/**
* Sets whether the Application Caches API should be enabled. The default
@@ -1150,9 +1008,7 @@
*
* @param flag true if the WebView should enable Application Caches
*/
- public synchronized void setAppCacheEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setAppCacheEnabled(boolean flag);
/**
* Sets the path to the Application Caches files. In order for the
@@ -1164,9 +1020,7 @@
* Application Caches files.
* @see #setAppCacheEnabled
*/
- public synchronized void setAppCachePath(String appCachePath) {
- throw new MustOverrideException();
- }
+ public abstract void setAppCachePath(String appCachePath);
/**
* Sets the maximum size for the Application Cache content. The passed size
@@ -1180,9 +1034,7 @@
* @deprecated In future quota will be managed automatically.
*/
@Deprecated
- public synchronized void setAppCacheMaxSize(long appCacheMaxSize) {
- throw new MustOverrideException();
- }
+ public abstract void setAppCacheMaxSize(long appCacheMaxSize);
/**
* Sets whether the database storage API is enabled. The default value is
@@ -1196,18 +1048,14 @@
*
* @param flag true if the WebView should use the database storage API
*/
- public synchronized void setDatabaseEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setDatabaseEnabled(boolean flag);
/**
* Sets whether the DOM storage API is enabled. The default value is false.
*
* @param flag true if the WebView should use the DOM storage API
*/
- public synchronized void setDomStorageEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setDomStorageEnabled(boolean flag);
/**
* Gets whether the DOM Storage APIs are enabled.
@@ -1215,9 +1063,8 @@
* @return true if the DOM Storage APIs are enabled
* @see #setDomStorageEnabled
*/
- public synchronized boolean getDomStorageEnabled() {
- throw new MustOverrideException();
- }
+ public abstract boolean getDomStorageEnabled();
+
/**
* Gets the path to where database storage API databases are saved.
*
@@ -1226,9 +1073,7 @@
* @deprecated Database paths are managed by the implementation this method is obsolete.
*/
@Deprecated
- public synchronized String getDatabasePath() {
- throw new MustOverrideException();
- }
+ public abstract String getDatabasePath();
/**
* Gets whether the database storage API is enabled.
@@ -1236,9 +1081,7 @@
* @return true if the database storage API is enabled
* @see #setDatabaseEnabled
*/
- public synchronized boolean getDatabaseEnabled() {
- throw new MustOverrideException();
- }
+ public abstract boolean getDatabaseEnabled();
/**
* Sets whether Geolocation is enabled. The default is true.
@@ -1260,9 +1103,7 @@
*
* @param flag whether Geolocation should be enabled
*/
- public synchronized void setGeolocationEnabled(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setGeolocationEnabled(boolean flag);
/**
* Gets whether JavaScript is enabled.
@@ -1270,9 +1111,7 @@
* @return true if JavaScript is enabled
* @see #setJavaScriptEnabled
*/
- public synchronized boolean getJavaScriptEnabled() {
- throw new MustOverrideException();
- }
+ public abstract boolean getJavaScriptEnabled();
/**
* Gets whether JavaScript running in the context of a file scheme URL can
@@ -1303,10 +1142,9 @@
* @deprecated This method has been replaced by {@link #getPluginState}
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
*/
+ @SystemApi
@Deprecated
- public synchronized boolean getPluginsEnabled() {
- throw new MustOverrideException();
- }
+ public abstract boolean getPluginsEnabled();
/**
* Gets the current state regarding whether plugins are enabled.
@@ -1316,9 +1154,7 @@
* @deprecated Plugins will not be supported in future, and should not be used.
*/
@Deprecated
- public synchronized PluginState getPluginState() {
- throw new MustOverrideException();
- }
+ public abstract PluginState getPluginState();
/**
* Gets the directory that contains the plugin libraries. This method is
@@ -1330,7 +1166,7 @@
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
*/
@Deprecated
- public synchronized String getPluginsPath() {
+ public String getPluginsPath() {
// Unconditionally returns empty string, so no need for derived classes to override.
return "";
}
@@ -1341,9 +1177,7 @@
*
* @param flag true if JavaScript can open windows automatically
*/
- public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setJavaScriptCanOpenWindowsAutomatically(boolean flag);
/**
* Gets whether JavaScript can open windows automatically.
@@ -1352,9 +1186,7 @@
* window.open()
* @see #setJavaScriptCanOpenWindowsAutomatically
*/
- public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
- throw new MustOverrideException();
- }
+ public abstract boolean getJavaScriptCanOpenWindowsAutomatically();
/**
* Sets the default text encoding name to use when decoding html pages.
@@ -1362,9 +1194,7 @@
*
* @param encoding the text encoding name
*/
- public synchronized void setDefaultTextEncodingName(String encoding) {
- throw new MustOverrideException();
- }
+ public abstract void setDefaultTextEncodingName(String encoding);
/**
* Gets the default text encoding name.
@@ -1372,17 +1202,13 @@
* @return the default text encoding name as a string
* @see #setDefaultTextEncodingName
*/
- public synchronized String getDefaultTextEncodingName() {
- throw new MustOverrideException();
- }
+ public abstract String getDefaultTextEncodingName();
/**
* Sets the WebView's user-agent string. If the string is null or empty,
* the system default value will be used.
*/
- public synchronized void setUserAgentString(String ua) {
- throw new MustOverrideException();
- }
+ public abstract void setUserAgentString(String ua);
/**
* Gets the WebView's user-agent string.
@@ -1390,9 +1216,7 @@
* @return the WebView's user-agent string
* @see #setUserAgentString
*/
- public synchronized String getUserAgentString() {
- throw new MustOverrideException();
- }
+ public abstract String getUserAgentString();
/**
* Returns the default User-Agent used by a WebView.
@@ -1412,9 +1236,7 @@
*
* @param flag whether the WebView needs to set a node
*/
- public void setNeedInitialFocus(boolean flag) {
- throw new MustOverrideException();
- }
+ public abstract void setNeedInitialFocus(boolean flag);
/**
* Sets the priority of the Render thread. Unlike the other settings, this
@@ -1426,9 +1248,7 @@
* not be supported in future versions.
*/
@Deprecated
- public synchronized void setRenderPriority(RenderPriority priority) {
- throw new MustOverrideException();
- }
+ public abstract void setRenderPriority(RenderPriority priority);
/**
* Overrides the way the cache is used. The way the cache is used is based
@@ -1442,9 +1262,7 @@
*
* @param mode the mode to use
*/
- public void setCacheMode(int mode) {
- throw new MustOverrideException();
- }
+ public abstract void setCacheMode(int mode);
/**
* Gets the current setting for overriding the cache mode.
@@ -1452,9 +1270,7 @@
* @return the current setting for overriding the cache mode
* @see #setCacheMode
*/
- public int getCacheMode() {
- throw new MustOverrideException();
- }
+ public abstract int getCacheMode();
/**
* Configures the WebView's behavior when a secure origin attempts to load a resource from an
diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java
index 3bfe9cf..947d0cb 100644
--- a/core/java/android/webkit/WebStorage.java
+++ b/core/java/android/webkit/WebStorage.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.SystemApi;
+
import java.util.Map;
/**
@@ -65,23 +67,13 @@
private long mUsage = 0;
/** @hide */
+ @SystemApi
protected Origin(String origin, long quota, long usage) {
mOrigin = origin;
mQuota = quota;
mUsage = usage;
}
- /** @hide */
- protected Origin(String origin, long quota) {
- mOrigin = origin;
- mQuota = quota;
- }
-
- /** @hide */
- protected Origin(String origin) {
- mOrigin = origin;
- }
-
/**
* Gets the string representation of this origin.
*
@@ -210,5 +202,6 @@
* way to call createHandler() and createUIHandler(), so it would not work).
* @hide
*/
+ @SystemApi
public WebStorage() {}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 40aee96..8d2c51f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.annotation.Widget;
import android.content.Context;
import android.content.res.Configuration;
@@ -256,10 +257,12 @@
* always stay as a hidden API.
* @hide
*/
+ @SystemApi
public static final String DATA_REDUCTION_PROXY_SETTING_CHANGED =
"android.webkit.DATA_REDUCTION_PROXY_SETTING_CHANGED";
private static final String LOGTAG = "WebView";
+ private static final boolean TRACE = false;
// Throwing an exception for incorrect thread usage if the
// build target is JB MR2 or newer. Defaults to false, and is
@@ -394,6 +397,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public HitTestResult() {
mType = UNKNOWN_TYPE;
}
@@ -401,6 +405,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public void setType(int type) {
mType = type;
}
@@ -408,6 +413,7 @@
/**
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public void setExtra(String extra) {
mExtra = extra;
}
@@ -542,7 +548,7 @@
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "WebView<init>");
+ if (TRACE) Log.d(LOGTAG, "WebView<init>");
ensureProviderCreated();
mProvider.init(javaScriptInterfaces, privateBrowsing);
@@ -557,7 +563,7 @@
*/
public void setHorizontalScrollbarOverlay(boolean overlay) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
+ if (TRACE) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
mProvider.setHorizontalScrollbarOverlay(overlay);
}
@@ -568,7 +574,7 @@
*/
public void setVerticalScrollbarOverlay(boolean overlay) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
+ if (TRACE) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
mProvider.setVerticalScrollbarOverlay(overlay);
}
@@ -623,7 +629,7 @@
@Deprecated
public void setCertificate(SslCertificate certificate) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setCertificate=" + certificate);
+ if (TRACE) Log.d(LOGTAG, "setCertificate=" + certificate);
mProvider.setCertificate(certificate);
}
@@ -647,7 +653,7 @@
@Deprecated
public void savePassword(String host, String username, String password) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePassword=" + host);
+ if (TRACE) Log.d(LOGTAG, "savePassword=" + host);
mProvider.savePassword(host, username, password);
}
@@ -667,7 +673,7 @@
public void setHttpAuthUsernamePassword(String host, String realm,
String username, String password) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
+ if (TRACE) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
}
@@ -697,7 +703,7 @@
*/
public void destroy() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "destroy");
+ if (TRACE) Log.d(LOGTAG, "destroy");
mProvider.destroy();
}
@@ -743,7 +749,7 @@
*/
public void setNetworkAvailable(boolean networkUp) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
+ if (TRACE) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
mProvider.setNetworkAvailable(networkUp);
}
@@ -760,7 +766,7 @@
*/
public WebBackForwardList saveState(Bundle outState) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveState");
+ if (TRACE) Log.d(LOGTAG, "saveState");
return mProvider.saveState(outState);
}
@@ -777,7 +783,7 @@
@Deprecated
public boolean savePicture(Bundle b, final File dest) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePicture=" + dest.getName());
+ if (TRACE) Log.d(LOGTAG, "savePicture=" + dest.getName());
return mProvider.savePicture(b, dest);
}
@@ -795,7 +801,7 @@
@Deprecated
public boolean restorePicture(Bundle b, File src) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restorePicture=" + src.getName());
+ if (TRACE) Log.d(LOGTAG, "restorePicture=" + src.getName());
return mProvider.restorePicture(b, src);
}
@@ -813,7 +819,7 @@
*/
public WebBackForwardList restoreState(Bundle inState) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restoreState");
+ if (TRACE) Log.d(LOGTAG, "restoreState");
return mProvider.restoreState(inState);
}
@@ -830,7 +836,7 @@
*/
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
checkThread();
- if (DebugFlags.TRACE_API) {
+ if (TRACE) {
StringBuilder headers = new StringBuilder();
if (additionalHttpHeaders != null) {
for (Map.Entry<String, String> entry : additionalHttpHeaders.entrySet()) {
@@ -849,7 +855,7 @@
*/
public void loadUrl(String url) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl=" + url);
+ if (TRACE) Log.d(LOGTAG, "loadUrl=" + url);
mProvider.loadUrl(url);
}
@@ -864,7 +870,7 @@
*/
public void postUrl(String url, byte[] postData) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
+ if (TRACE) Log.d(LOGTAG, "postUrl=" + url);
if (URLUtil.isNetworkUrl(url)) {
mProvider.postUrl(url, postData);
} else {
@@ -903,7 +909,7 @@
*/
public void loadData(String data, String mimeType, String encoding) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadData");
+ if (TRACE) Log.d(LOGTAG, "loadData");
mProvider.loadData(data, mimeType, encoding);
}
@@ -936,7 +942,7 @@
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
+ if (TRACE) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}
@@ -953,7 +959,7 @@
*/
public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "evaluateJavascript=" + script);
+ if (TRACE) Log.d(LOGTAG, "evaluateJavascript=" + script);
mProvider.evaluateJavaScript(script, resultCallback);
}
@@ -964,7 +970,7 @@
*/
public void saveWebArchive(String filename) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive=" + filename);
+ if (TRACE) Log.d(LOGTAG, "saveWebArchive=" + filename);
mProvider.saveWebArchive(filename);
}
@@ -982,7 +988,7 @@
*/
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
+ if (TRACE) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
mProvider.saveWebArchive(basename, autoname, callback);
}
@@ -991,7 +997,7 @@
*/
public void stopLoading() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "stopLoading");
+ if (TRACE) Log.d(LOGTAG, "stopLoading");
mProvider.stopLoading();
}
@@ -1000,7 +1006,7 @@
*/
public void reload() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "reload");
+ if (TRACE) Log.d(LOGTAG, "reload");
mProvider.reload();
}
@@ -1019,7 +1025,7 @@
*/
public void goBack() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBack");
+ if (TRACE) Log.d(LOGTAG, "goBack");
mProvider.goBack();
}
@@ -1038,7 +1044,7 @@
*/
public void goForward() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goForward");
+ if (TRACE) Log.d(LOGTAG, "goForward");
mProvider.goForward();
}
@@ -1064,7 +1070,7 @@
*/
public void goBackOrForward(int steps) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBackOrForwad=" + steps);
+ if (TRACE) Log.d(LOGTAG, "goBackOrForwad=" + steps);
mProvider.goBackOrForward(steps);
}
@@ -1084,7 +1090,7 @@
*/
public boolean pageUp(boolean top) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageUp");
+ if (TRACE) Log.d(LOGTAG, "pageUp");
return mProvider.pageUp(top);
}
@@ -1096,7 +1102,7 @@
*/
public boolean pageDown(boolean bottom) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageDown");
+ if (TRACE) Log.d(LOGTAG, "pageDown");
return mProvider.pageDown(bottom);
}
@@ -1109,7 +1115,7 @@
@Deprecated
public void clearView() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearView");
+ if (TRACE) Log.d(LOGTAG, "clearView");
mProvider.clearView();
}
@@ -1140,7 +1146,7 @@
@Deprecated
public Picture capturePicture() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "capturePicture");
+ if (TRACE) Log.d(LOGTAG, "capturePicture");
return mProvider.capturePicture();
}
@@ -1151,7 +1157,7 @@
@Deprecated
public PrintDocumentAdapter createPrintDocumentAdapter() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "createPrintDocumentAdapter");
+ if (TRACE) Log.d(LOGTAG, "createPrintDocumentAdapter");
return mProvider.createPrintDocumentAdapter("default");
}
@@ -1170,7 +1176,7 @@
*/
public PrintDocumentAdapter createPrintDocumentAdapter(String documentName) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "createPrintDocumentAdapter");
+ if (TRACE) Log.d(LOGTAG, "createPrintDocumentAdapter");
return mProvider.createPrintDocumentAdapter(documentName);
}
@@ -1210,7 +1216,7 @@
*/
public void setInitialScale(int scaleInPercent) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
+ if (TRACE) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
mProvider.setInitialScale(scaleInPercent);
}
@@ -1221,7 +1227,7 @@
*/
public void invokeZoomPicker() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "invokeZoomPicker");
+ if (TRACE) Log.d(LOGTAG, "invokeZoomPicker");
mProvider.invokeZoomPicker();
}
@@ -1245,7 +1251,7 @@
*/
public HitTestResult getHitTestResult() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "getHitTestResult");
+ if (TRACE) Log.d(LOGTAG, "getHitTestResult");
return mProvider.getHitTestResult();
}
@@ -1264,7 +1270,7 @@
*/
public void requestFocusNodeHref(Message hrefMsg) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestFocusNodeHref");
+ if (TRACE) Log.d(LOGTAG, "requestFocusNodeHref");
mProvider.requestFocusNodeHref(hrefMsg);
}
@@ -1277,7 +1283,7 @@
*/
public void requestImageRef(Message msg) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestImageRef");
+ if (TRACE) Log.d(LOGTAG, "requestImageRef");
mProvider.requestImageRef(msg);
}
@@ -1382,7 +1388,7 @@
*/
public void pauseTimers() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pauseTimers");
+ if (TRACE) Log.d(LOGTAG, "pauseTimers");
mProvider.pauseTimers();
}
@@ -1392,7 +1398,7 @@
*/
public void resumeTimers() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "resumeTimers");
+ if (TRACE) Log.d(LOGTAG, "resumeTimers");
mProvider.resumeTimers();
}
@@ -1405,7 +1411,7 @@
*/
public void onPause() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onPause");
+ if (TRACE) Log.d(LOGTAG, "onPause");
mProvider.onPause();
}
@@ -1414,7 +1420,7 @@
*/
public void onResume() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onResume");
+ if (TRACE) Log.d(LOGTAG, "onResume");
mProvider.onResume();
}
@@ -1437,7 +1443,7 @@
@Deprecated
public void freeMemory() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "freeMemory");
+ if (TRACE) Log.d(LOGTAG, "freeMemory");
mProvider.freeMemory();
}
@@ -1449,7 +1455,7 @@
*/
public void clearCache(boolean includeDiskFiles) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearCache");
+ if (TRACE) Log.d(LOGTAG, "clearCache");
mProvider.clearCache(includeDiskFiles);
}
@@ -1461,7 +1467,7 @@
*/
public void clearFormData() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearFormData");
+ if (TRACE) Log.d(LOGTAG, "clearFormData");
mProvider.clearFormData();
}
@@ -1470,7 +1476,7 @@
*/
public void clearHistory() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearHistory");
+ if (TRACE) Log.d(LOGTAG, "clearHistory");
mProvider.clearHistory();
}
@@ -1480,7 +1486,7 @@
*/
public void clearSslPreferences() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearSslPreferences");
+ if (TRACE) Log.d(LOGTAG, "clearSslPreferences");
mProvider.clearSslPreferences();
}
@@ -1496,7 +1502,7 @@
* callback. The runnable will be called in UI thread.
*/
public static void clearClientCertPreferences(Runnable onCleared) {
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearClientCertPreferences");
+ if (TRACE) Log.d(LOGTAG, "clearClientCertPreferences");
getFactory().getStatics().clearClientCertPreferences(onCleared);
}
@@ -1538,7 +1544,7 @@
*/
public void findNext(boolean forward) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findNext");
+ if (TRACE) Log.d(LOGTAG, "findNext");
mProvider.findNext(forward);
}
@@ -1554,7 +1560,7 @@
@Deprecated
public int findAll(String find) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAll");
+ if (TRACE) Log.d(LOGTAG, "findAll");
StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync");
return mProvider.findAll(find);
}
@@ -1569,7 +1575,7 @@
*/
public void findAllAsync(String find) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAllAsync");
+ if (TRACE) Log.d(LOGTAG, "findAllAsync");
mProvider.findAllAsync(find);
}
@@ -1590,7 +1596,7 @@
@Deprecated
public boolean showFindDialog(String text, boolean showIme) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "showFindDialog");
+ if (TRACE) Log.d(LOGTAG, "showFindDialog");
return mProvider.showFindDialog(text, showIme);
}
@@ -1646,7 +1652,7 @@
*/
public void clearMatches() {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearMatches");
+ if (TRACE) Log.d(LOGTAG, "clearMatches");
mProvider.clearMatches();
}
@@ -1707,7 +1713,7 @@
@Deprecated
public void setPictureListener(PictureListener listener) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setPictureListener=" + listener);
+ if (TRACE) Log.d(LOGTAG, "setPictureListener=" + listener);
mProvider.setPictureListener(listener);
}
@@ -1764,7 +1770,7 @@
*/
public void addJavascriptInterface(Object object, String name) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "addJavascriptInterface=" + name);
+ if (TRACE) Log.d(LOGTAG, "addJavascriptInterface=" + name);
mProvider.addJavascriptInterface(object, name);
}
@@ -1777,7 +1783,7 @@
*/
public void removeJavascriptInterface(String name) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
+ if (TRACE) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
mProvider.removeJavascriptInterface(name);
}
@@ -1881,7 +1887,7 @@
public void flingScroll(int vx, int vy) {
checkThread();
- if (DebugFlags.TRACE_API) Log.d(LOGTAG, "flingScroll");
+ if (TRACE) Log.d(LOGTAG, "flingScroll");
mProvider.flingScroll(vx, vy);
}
@@ -2006,6 +2012,7 @@
*
* @hide WebViewProvider is not public API.
*/
+ @SystemApi
public WebViewProvider getWebViewProvider() {
return mProvider;
}
@@ -2015,6 +2022,7 @@
* and fields, and make super-class calls in this WebView instance.
* @hide Only for use by WebViewProvider implementations
*/
+ @SystemApi
public class PrivateAccess {
// ---- Access to super-class methods ----
public int super_getScrollBarStyle() {
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 99e0ffb..bfea481 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.Context;
/**
@@ -28,18 +29,12 @@
* <li>Data entered into text fields (e.g. for autocomplete suggestions)</li>
* </ul>
*/
-public class WebViewDatabase {
+public abstract class WebViewDatabase {
/**
* @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
*/
protected static final String LOGTAG = "webviewdatabase";
- /**
- * @hide Only for use by WebViewProvider implementations.
- */
- protected WebViewDatabase() {
- }
-
public static WebViewDatabase getInstance(Context context) {
return WebViewFactory.getProvider().getWebViewDatabase(context);
}
@@ -54,9 +49,7 @@
* @deprecated Saving passwords in WebView will not be supported in future versions.
*/
@Deprecated
- public boolean hasUsernamePassword() {
- throw new MustOverrideException();
- }
+ public abstract boolean hasUsernamePassword();
/**
* Clears any saved username/password pairs for web forms.
@@ -67,9 +60,7 @@
* @deprecated Saving passwords in WebView will not be supported in future versions.
*/
@Deprecated
- public void clearUsernamePassword() {
- throw new MustOverrideException();
- }
+ public abstract void clearUsernamePassword();
/**
* Gets whether there are any saved credentials for HTTP authentication.
@@ -79,9 +70,7 @@
* @see WebView#setHttpAuthUsernamePassword
* @see #clearHttpAuthUsernamePassword
*/
- public boolean hasHttpAuthUsernamePassword() {
- throw new MustOverrideException();
- }
+ public abstract boolean hasHttpAuthUsernamePassword();
/**
* Clears any saved credentials for HTTP authentication.
@@ -90,9 +79,7 @@
* @see WebView#setHttpAuthUsernamePassword
* @see #hasHttpAuthUsernamePassword
*/
- public void clearHttpAuthUsernamePassword() {
- throw new MustOverrideException();
- }
+ public abstract void clearHttpAuthUsernamePassword();
/**
* Gets whether there is any saved data for web forms.
@@ -100,16 +87,12 @@
* @return whether there is any saved data for web forms
* @see #clearFormData
*/
- public boolean hasFormData() {
- throw new MustOverrideException();
- }
+ public abstract boolean hasFormData();
/**
* Clears any saved data for web forms.
*
* @see #hasFormData
*/
- public void clearFormData() {
- throw new MustOverrideException();
- }
+ public abstract void clearFormData();
}
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
new file mode 100644
index 0000000..3dcfda3
--- /dev/null
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -0,0 +1,163 @@
+/*
+ * 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.webkit;
+
+import android.annotation.SystemApi;
+import android.app.ActivityThread;
+import android.app.Application;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.net.http.ErrorStrings;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.util.SparseArray;
+import android.view.HardwareCanvas;
+import android.view.View;
+import android.view.ViewRootImpl;
+
+/**
+ * Delegate used by the WebView provider implementation to access
+ * the required framework functionality needed to implement a {@link WebView}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class WebViewDelegate {
+
+ /* package */ WebViewDelegate() { }
+
+ /**
+ * Listener that gets notified whenever tracing has been enabled/disabled.
+ */
+ public interface OnTraceEnabledChangeListener {
+ void onTraceEnabledChange(boolean enabled);
+ }
+
+ /**
+ * Register a callback to be invoked when tracing for the WebView component has been
+ * enabled/disabled.
+ */
+ public void setOnTraceEnabledChangeListener(final OnTraceEnabledChangeListener listener) {
+ SystemProperties.addChangeCallback(new Runnable() {
+ @Override
+ public void run() {
+ listener.onTraceEnabledChange(isTraceTagEnabled());
+ }
+ });
+ }
+
+ /**
+ * Returns true if the WebView trace tag is enabled and false otherwise.
+ */
+ public boolean isTraceTagEnabled() {
+ return Trace.isTagEnabled(Trace.TRACE_TAG_WEBVIEW);
+ }
+
+ /**
+ * Returns true if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor})
+ * and false otherwise.
+ */
+ public boolean canInvokeDrawGlFunctor(View containerView) {
+ ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
+ // viewRootImpl can be null during teardown when window is leaked.
+ return viewRootImpl != null;
+ }
+
+ /**
+ * Invokes the draw GL functor. If waitForCompletion is false the functor
+ * may be invoked asynchronously.
+ *
+ * @param nativeDrawGLFunctor the pointer to the native functor that implements
+ * system/core/include/utils/Functor.h
+ */
+ public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor,
+ boolean waitForCompletion) {
+ ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
+ viewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion);
+ }
+
+ /**
+ * Calls the function specified with the nativeDrawGLFunctor functor pointer. This
+ * functionality is used by the WebView for calling into their renderer from the
+ * framework display lists.
+ *
+ * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()})
+ * @param nativeDrawGLFunctor the pointer to the native functor that implements
+ * system/core/include/utils/Functor.h
+ * @throws IllegalArgumentException if the canvas is not hardware accelerated
+ */
+ public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
+ if (!(canvas instanceof HardwareCanvas)) {
+ // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
+ throw new IllegalArgumentException(canvas.getClass().getName()
+ + " is not hardware accelerated");
+ }
+ ((HardwareCanvas) canvas).callDrawGLFunction(nativeDrawGLFunctor);
+ }
+
+ /**
+ * Detaches the draw GL functor.
+ *
+ * @param nativeDrawGLFunctor the pointer to the native functor that implements
+ * system/core/include/utils/Functor.h
+ */
+ public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) {
+ ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
+ if (nativeDrawGLFunctor != 0 && viewRootImpl != null) {
+ viewRootImpl.detachFunctor(nativeDrawGLFunctor);
+ }
+ }
+
+ /**
+ * Returns the package id of the given {@code packageName}.
+ */
+ public int getPackageId(Resources resources, String packageName) {
+ SparseArray<String> packageIdentifiers =
+ resources.getAssets().getAssignedPackageIdentifiers();
+ for (int i = 0; i < packageIdentifiers.size(); i++) {
+ final String name = packageIdentifiers.valueAt(i);
+
+ if (packageName.equals(name)) {
+ return packageIdentifiers.keyAt(i);
+ }
+ }
+ throw new RuntimeException("Package not found: " + packageName);
+ }
+
+ /**
+ * Returns the application which is embedding the WebView.
+ */
+ public Application getApplication() {
+ return ActivityThread.currentApplication();
+ }
+
+ /**
+ * Returns the error string for the given {@code errorCode}.
+ */
+ public String getErrorString(Context context, int errorCode) {
+ return ErrorStrings.getString(errorCode, context);
+ }
+
+ /**
+ * Adds the WebView asset path to {@link AssetManager}.
+ */
+ public void addWebViewAssetPath(Context context) {
+ context.getAssets().addAssetPath(
+ WebViewFactory.getLoadedPackageInfo().applicationInfo.sourceDir);
+ }
+}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index c7ffedc..7b23d8f 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.app.ActivityManagerInternal;
import android.app.Application;
import android.app.AppGlobals;
@@ -46,6 +47,7 @@
*
* @hide
*/
+@SystemApi
public final class WebViewFactory {
private static final String CHROMIUM_WEBVIEW_FACTORY =
@@ -109,7 +111,12 @@
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()");
try {
- sProviderInstance = providerClass.newInstance();
+ try {
+ sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
+ .newInstance(new WebViewDelegate());
+ } catch (Exception e) {
+ sProviderInstance = providerClass.newInstance();
+ }
if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
return sProviderInstance;
} catch (Exception e) {
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index d37d217..9105394 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -26,6 +27,7 @@
* implementation of this interface, and make it available to the WebView via mechanism TBD.
* @hide
*/
+@SystemApi
public interface WebViewFactoryProvider {
/**
* This Interface provides glue for implementing the backend of WebView static methods which
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index fe18138..2aee57b 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -53,6 +54,7 @@
*
* @hide Not part of the public API; only required by system implementors.
*/
+@SystemApi
public interface WebViewProvider {
//-------------------------------------------------------------------------
// Main interface for backend provider of the WebView class.
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 3b16aba..e6392b9 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -1005,6 +1005,12 @@
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+ if (mTemporaryDetach) {
+ // If we are temporarily in the detach state, then do nothing.
+ return;
+ }
+
// Perform validation if the view is losing focus.
if (!focused) {
performValidation();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0917b32..5e83602 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -287,9 +287,11 @@
private int mCurTextColor;
private int mCurHintTextColor;
private boolean mFreezesText;
- private boolean mTemporaryDetach;
private boolean mDispatchTemporaryDetach;
+ /** Whether this view is temporarily detached from the parent view. */
+ boolean mTemporaryDetach;
+
private Editable.Factory mEditableFactory = Editable.Factory.getInstance();
private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance();
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index e3e5647..1b25486 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -2746,6 +2746,7 @@
pw.print("total");
dumpAdjTimesCheckin(pw, ",", mMemFactorDurations, mMemFactor,
mStartTime, now);
+ pw.println();
if (mSysMemUsageTable != null) {
pw.print("sysmemusage");
for (int i=0; i<mSysMemUsageTableSize; i++) {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 376db6e..2db466a 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -840,7 +840,7 @@
}
if (N > 1) {
Comparator<ResolveInfo> rComparator =
- new ResolverComparator(ResolverActivity.this);
+ new ResolverComparator(ResolverActivity.this, mIntent);
Collections.sort(currentResolveList, rComparator);
}
// First put the initial items at the top.
@@ -1093,11 +1093,20 @@
}
}
+ static final boolean isSpecificUriMatch(int match) {
+ match = match&IntentFilter.MATCH_CATEGORY_MASK;
+ return match >= IntentFilter.MATCH_CATEGORY_HOST
+ && match <= IntentFilter.MATCH_CATEGORY_PATH;
+ }
+
class ResolverComparator implements Comparator<ResolveInfo> {
private final Collator mCollator;
+ private final boolean mHttp;
- public ResolverComparator(Context context) {
+ public ResolverComparator(Context context, Intent intent) {
mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
+ String scheme = intent.getScheme();
+ mHttp = "http".equals(scheme) || "https".equals(scheme);
}
@Override
@@ -1107,6 +1116,17 @@
return 1;
}
+ if (mHttp) {
+ // Special case: we want filters that match URI paths/schemes to be
+ // ordered before others. This is for the case when opening URIs,
+ // to make native apps go above browsers.
+ final boolean lhsSpecific = isSpecificUriMatch(lhs.match);
+ final boolean rhsSpecific = isSpecificUriMatch(rhs.match);
+ if (lhsSpecific != rhsSpecific) {
+ return lhsSpecific ? -1 : 1;
+ }
+ }
+
if (mStats != null) {
final long timeDiff =
getPackageTimeSpent(rhs.activityInfo.packageName) -
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 31c7b9f..533313a 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1278,7 +1278,7 @@
}
BAIL_IF_INVALID(writer->addEntry(TAG_CAMERACALIBRATION2, entry2.count,
- calibrationTransform1, TIFF_IFD_0), env, TAG_CAMERACALIBRATION2, writer);
+ calibrationTransform2, TIFF_IFD_0), env, TAG_CAMERACALIBRATION2, writer);
}
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index f099289..4b4b367 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -160,6 +160,9 @@
{
// remove global references
JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (env == NULL) {
+ return;
+ }
env->DeleteGlobalRef(mObject);
env->DeleteGlobalRef(mClass);
}
@@ -167,7 +170,9 @@
void JNIAudioPortCallback::sendEvent(int event)
{
JNIEnv *env = AndroidRuntime::getJNIEnv();
-
+ if (env == NULL) {
+ return;
+ }
env->CallStaticVoidMethod(mClass, gPostEventFromNative, mObject,
event, 0, 0, NULL);
if (env->ExceptionCheck()) {
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 44863cc..960acc0 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -688,6 +688,16 @@
"Binder invocation to an incorrect interface");
}
+static jlong android_os_Parcel_getGlobalAllocSize(JNIEnv* env, jclass clazz)
+{
+ return Parcel::getGlobalAllocSize();
+}
+
+static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz)
+{
+ return Parcel::getGlobalAllocCount();
+}
+
// ----------------------------------------------------------------------------
static const JNINativeMethod gParcelMethods[] = {
@@ -737,6 +747,9 @@
{"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
{"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken},
{"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface},
+
+ {"getGlobalAllocSize", "()J", (void*)android_os_Parcel_getGlobalAllocSize},
+ {"getGlobalAllocCount", "()J", (void*)android_os_Parcel_getGlobalAllocCount},
};
const char* const kParcelPathName = "android/os/Parcel";
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index b023ebd..fe64aba 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -172,6 +172,12 @@
return Caches::getInstance().maxTextureSize;
}
+static void android_view_GLES20Canvas_setOverrideXfermode(JNIEnv* env, jobject clazz,
+ jlong rendererPtr, int xfermode) {
+ DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
+ renderer->setOverrideXfermode(xfermode);
+}
+
// ----------------------------------------------------------------------------
// State
// ----------------------------------------------------------------------------
@@ -964,6 +970,8 @@
{ "nGetMaximumTextureWidth", "()I", (void*) android_view_GLES20Canvas_getMaxTextureWidth },
{ "nGetMaximumTextureHeight", "()I", (void*) android_view_GLES20Canvas_getMaxTextureHeight },
+ { "nSetOverrideXfermode", "(JI)V", (void*) android_view_GLES20Canvas_setOverrideXfermode },
+
#endif
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b03103e..4d6fc9c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2895,6 +2895,12 @@
android:description="@string/permdesc_removeDrmCertificates"
android:protectionLevel="signature|system" />
+ <!-- Must be required by a {@link android.service.carriermessaging.CarrierMessagingService}.
+ Any service that filters for this intent must be a carrier privileged app. -->
+ <permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
+ android:label="@string/permlab_bindCarrierMessagingService"
+ android:description="@string/permdesc_bindCarrierMessagingService" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
index aa75a7a..912b5bf 100644
--- a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
+++ b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
@@ -27,7 +27,7 @@
android:name="background_track"
android:pathData="M -180.0,-1.0 l 360.0,0 l 0,2.0 l -360.0,0 Z"
android:fillColor="?attr/colorControlActivated"
- android:fillAlpha="0.1"/>
+ android:fillAlpha="?attr/disabledAlpha"/>
<group
android:name="rect2_grp"
android:translateX="-197.60001"
diff --git a/core/res/res/values-mcc310-mnc160/config.xml b/core/res/res/values-mcc310-mnc160/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc160/config.xml
+++ b/core/res/res/values-mcc310-mnc160/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc200/config.xml b/core/res/res/values-mcc310-mnc200/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc200/config.xml
+++ b/core/res/res/values-mcc310-mnc200/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc210/config.xml b/core/res/res/values-mcc310-mnc210/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc210/config.xml
+++ b/core/res/res/values-mcc310-mnc210/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc220/config.xml b/core/res/res/values-mcc310-mnc220/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc220/config.xml
+++ b/core/res/res/values-mcc310-mnc220/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc230/config.xml b/core/res/res/values-mcc310-mnc230/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc230/config.xml
+++ b/core/res/res/values-mcc310-mnc230/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc240/config.xml b/core/res/res/values-mcc310-mnc240/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc240/config.xml
+++ b/core/res/res/values-mcc310-mnc240/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc250/config.xml b/core/res/res/values-mcc310-mnc250/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc250/config.xml
+++ b/core/res/res/values-mcc310-mnc250/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc270/config.xml b/core/res/res/values-mcc310-mnc270/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc270/config.xml
+++ b/core/res/res/values-mcc310-mnc270/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc300/config.xml b/core/res/res/values-mcc310-mnc300/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc300/config.xml
+++ b/core/res/res/values-mcc310-mnc300/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc310/config.xml b/core/res/res/values-mcc310-mnc310/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc310/config.xml
+++ b/core/res/res/values-mcc310-mnc310/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc490/config.xml b/core/res/res/values-mcc310-mnc490/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc490/config.xml
+++ b/core/res/res/values-mcc310-mnc490/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc530/config.xml b/core/res/res/values-mcc310-mnc530/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc530/config.xml
+++ b/core/res/res/values-mcc310-mnc530/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc580/config.xml b/core/res/res/values-mcc310-mnc580/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc580/config.xml
+++ b/core/res/res/values-mcc310-mnc580/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc590/config.xml b/core/res/res/values-mcc310-mnc590/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc590/config.xml
+++ b/core/res/res/values-mcc310-mnc590/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc640/config.xml b/core/res/res/values-mcc310-mnc640/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc640/config.xml
+++ b/core/res/res/values-mcc310-mnc640/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc660/config.xml b/core/res/res/values-mcc310-mnc660/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc660/config.xml
+++ b/core/res/res/values-mcc310-mnc660/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values-mcc310-mnc800/config.xml b/core/res/res/values-mcc310-mnc800/config.xml
index 28cd695..6bfc3d1 100644
--- a/core/res/res/values-mcc310-mnc800/config.xml
+++ b/core/res/res/values-mcc310-mnc800/config.xml
@@ -25,8 +25,8 @@
-->
<integer name="config_mobile_mtu">1440</integer>
- <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of
+ <!-- Flag specifying whether VoLTE should be available for carrier: independent of
carrier provisioning. If false: hard disabled. If true: then depends on carrier
provisioning, availability etc -->
- <bool name="config_carrier_volte_vt_available">true</bool>
+ <bool name="config_carrier_volte_available">true</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d6bc38f..0cc007b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2344,6 +2344,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_removeDrmCertificates">Allows an application to remove DRM certficates. Should never be needed for normal apps.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_bindCarrierMessagingService">bind to a carrier messaging service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</string>
+
<!-- Policy administration -->
<!-- Title of policy access to limiting the user's password choices -->
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index f1bc5da..1ebc708 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -28,6 +28,8 @@
to work properly. -->
<item name="windowIsTranslucent">true</item>
<item name="windowSwipeToDismiss">true</item>
+ <!-- Required to force windowInsets dispatch through application UI. -->
+ <item name="windowOverscan">true</item>
</style>
<style name="Theme.Micro.Light" parent="Theme.Holo.Light.NoActionBar">
@@ -44,6 +46,8 @@
to work properly. -->
<item name="windowIsTranslucent">true</item>
<item name="windowSwipeToDismiss">true</item>
+ <!-- Required to force windowInsets dispatch through application UI. -->
+ <item name="windowOverscan">true</item>
</style>
<style name="Theme.Micro.Dialog" parent="Theme.Holo.Light.Dialog">
@@ -52,6 +56,8 @@
<item name="windowFullscreen">true</item>
<item name="textAppearance">@style/TextAppearance.Micro</item>
<item name="textAppearanceInverse">@style/TextAppearance.Micro</item>
+ <!-- Required to force windowInsets dispatch through application UI. -->
+ <item name="windowOverscan">true</item>
</style>
<style name="Theme.Micro.Dialog.Alert">
diff --git a/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
new file mode 100644
index 0000000..e7f4bad
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
@@ -0,0 +1,263 @@
+package android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ParceledListSliceTest extends TestCase {
+
+ public void testSmallList() throws Exception {
+ final int objectCount = 100;
+ List<SmallObject> list = new ArrayList<>();
+ for (int i = 0; i < objectCount; i++) {
+ list.add(new SmallObject(i * 2, (i * 2) + 1));
+ }
+
+ ParceledListSlice<SmallObject> slice;
+
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeParcelable(new ParceledListSlice<>(list), 0);
+ parcel.setDataPosition(0);
+ slice = parcel.readParcelable(getClass().getClassLoader());
+ } finally {
+ parcel.recycle();
+ }
+
+ assertNotNull(slice);
+ assertNotNull(slice.getList());
+ assertEquals(objectCount, slice.getList().size());
+
+ for (int i = 0; i < objectCount; i++) {
+ assertEquals(i * 2, slice.getList().get(i).mFieldA);
+ assertEquals((i * 2) + 1, slice.getList().get(i).mFieldB);
+ }
+ }
+
+ private static int measureLargeObject() {
+ Parcel p = Parcel.obtain();
+ try {
+ new LargeObject(0, 0, 0, 0, 0).writeToParcel(p, 0);
+ return p.dataPosition();
+ } finally {
+ p.recycle();
+ }
+ }
+
+ /**
+ * Test that when the list is large, the data is successfully parceled
+ * and unparceled (the implementation will send pieces of the list in
+ * separate round-trips to avoid the IPC limit).
+ */
+ public void testLargeList() throws Exception {
+ final int thresholdBytes = 256 * 1024;
+ final int objectCount = thresholdBytes / measureLargeObject();
+
+ List<LargeObject> list = new ArrayList<>();
+ for (int i = 0; i < objectCount; i++) {
+ list.add(new LargeObject(
+ i * 5,
+ (i * 5) + 1,
+ (i * 5) + 2,
+ (i * 5) + 3,
+ (i * 5) + 4
+ ));
+ }
+
+ ParceledListSlice<LargeObject> slice;
+
+ Parcel parcel = Parcel.obtain();
+ try {
+ parcel.writeParcelable(new ParceledListSlice<>(list), 0);
+ parcel.setDataPosition(0);
+ slice = parcel.readParcelable(getClass().getClassLoader());
+ } finally {
+ parcel.recycle();
+ }
+
+ assertNotNull(slice);
+ assertNotNull(slice.getList());
+ assertEquals(objectCount, slice.getList().size());
+
+ for (int i = 0; i < objectCount; i++) {
+ assertEquals(i * 5, slice.getList().get(i).mFieldA);
+ assertEquals((i * 5) + 1, slice.getList().get(i).mFieldB);
+ assertEquals((i * 5) + 2, slice.getList().get(i).mFieldC);
+ assertEquals((i * 5) + 3, slice.getList().get(i).mFieldD);
+ assertEquals((i * 5) + 4, slice.getList().get(i).mFieldE);
+ }
+ }
+
+ /**
+ * Test that only homogeneous elements may be unparceled.
+ */
+ public void testHomogeneousElements() throws Exception {
+ List<BaseObject> list = new ArrayList<>();
+ list.add(new LargeObject(0, 1, 2, 3, 4));
+ list.add(new SmallObject(5, 6));
+ list.add(new SmallObject(7, 8));
+
+ Parcel parcel = Parcel.obtain();
+ try {
+ writeEvilParceledListSlice(parcel, list);
+ parcel.setDataPosition(0);
+ try {
+ ParceledListSlice.CREATOR.createFromParcel(parcel, getClass().getClassLoader());
+ assertTrue("Unparceled heterogeneous ParceledListSlice", false);
+ } catch (IllegalArgumentException e) {
+ // Success, we're not allowed to process heterogeneous
+ // elements in a ParceledListSlice.
+ }
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+ /**
+ * Write a ParcelableListSlice that uses the BaseObject base class as the Creator.
+ * This is dangerous, as it may affect how the data is unparceled, then later parceled
+ * by the system, leading to a self-modifying data security vulnerability.
+ */
+ private static <T extends BaseObject> void writeEvilParceledListSlice(Parcel dest, List<T> list) {
+ final int listCount = list.size();
+
+ // Number of items.
+ dest.writeInt(listCount);
+
+ // The type/creator to use when unparceling. Here we use the base class
+ // to simulate an attack on ParceledListSlice.
+ dest.writeString(BaseObject.class.getName());
+
+ for (int i = 0; i < listCount; i++) {
+ // 1 means the item is present.
+ dest.writeInt(1);
+ list.get(i).writeToParcel(dest, 0);
+ }
+ }
+
+ public abstract static class BaseObject implements Parcelable {
+ protected static final int TYPE_SMALL = 0;
+ protected static final int TYPE_LARGE = 1;
+
+ protected void writeToParcel(Parcel dest, int flags, int type) {
+ dest.writeInt(type);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * This is *REALLY* bad, but we're doing it in the test to ensure that we handle
+ * the possible exploit when unparceling an object with the BaseObject written as
+ * Creator.
+ */
+ public static final Creator<BaseObject> CREATOR = new Creator<BaseObject>() {
+ @Override
+ public BaseObject createFromParcel(Parcel source) {
+ switch (source.readInt()) {
+ case TYPE_SMALL:
+ return SmallObject.createFromParcelBody(source);
+ case TYPE_LARGE:
+ return LargeObject.createFromParcelBody(source);
+ default:
+ throw new IllegalArgumentException("Unknown type");
+ }
+ }
+
+ @Override
+ public BaseObject[] newArray(int size) {
+ return new BaseObject[size];
+ }
+ };
+ }
+
+ public static class SmallObject extends BaseObject {
+ public int mFieldA;
+ public int mFieldB;
+
+ public SmallObject(int a, int b) {
+ mFieldA = a;
+ mFieldB = b;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags, TYPE_SMALL);
+ dest.writeInt(mFieldA);
+ dest.writeInt(mFieldB);
+ }
+
+ public static SmallObject createFromParcelBody(Parcel source) {
+ return new SmallObject(source.readInt(), source.readInt());
+ }
+
+ public static final Creator<SmallObject> CREATOR = new Creator<SmallObject>() {
+ @Override
+ public SmallObject createFromParcel(Parcel source) {
+ // Consume the type (as it is always written out).
+ source.readInt();
+ return createFromParcelBody(source);
+ }
+
+ @Override
+ public SmallObject[] newArray(int size) {
+ return new SmallObject[size];
+ }
+ };
+ }
+
+ public static class LargeObject extends BaseObject {
+ public int mFieldA;
+ public int mFieldB;
+ public int mFieldC;
+ public int mFieldD;
+ public int mFieldE;
+
+ public LargeObject(int a, int b, int c, int d, int e) {
+ mFieldA = a;
+ mFieldB = b;
+ mFieldC = c;
+ mFieldD = d;
+ mFieldE = e;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags, TYPE_LARGE);
+ dest.writeInt(mFieldA);
+ dest.writeInt(mFieldB);
+ dest.writeInt(mFieldC);
+ dest.writeInt(mFieldD);
+ dest.writeInt(mFieldE);
+ }
+
+ public static LargeObject createFromParcelBody(Parcel source) {
+ return new LargeObject(
+ source.readInt(),
+ source.readInt(),
+ source.readInt(),
+ source.readInt(),
+ source.readInt()
+ );
+ }
+
+ public static final Creator<LargeObject> CREATOR = new Creator<LargeObject>() {
+ @Override
+ public LargeObject createFromParcel(Parcel source) {
+ // Consume the type (as it is always written out).
+ source.readInt();
+ return createFromParcelBody(source);
+ }
+
+ @Override
+ public LargeObject[] newArray(int size) {
+ return new LargeObject[size];
+ }
+ };
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/SignatureTest.java b/core/tests/coretests/src/android/content/pm/SignatureTest.java
new file mode 100644
index 0000000..89d5997
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/SignatureTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.content.pm;
+
+import junit.framework.TestCase;
+
+public class SignatureTest extends TestCase {
+
+ /** Cert A with valid syntax */
+ private static final Signature A = new Signature("308201D33082013CA0030201020219373565373461363A31336534333439623635343A2D38303030300D06092A864886F70D01010505003017311530130603550403130C6269736F6E416E64726F6964301E170D3133303432343232323134345A170D3338303432353232323134345A3017311530130603550403130C6269736F6E416E64726F696430819F300D06092A864886F70D010101050003818D00308189028181009214CE08563B77FF3128D3A303254287301263A842D19D5D4EAF024EBEDF864F3802C215B2F3EA85432F3EFF1DB8F591B0854FA7C1C6E4A8A85132FA762CC2D12A8EBD34D8B15C241A91716577F03BB3D2AFFC24367AB1E5E03C387891E34E646E47FAD75B178C1FD077B9199B3ABA6D48E2464801F6592E98245124046E51A90203010001A317301530130603551D25040C300A06082B06010505070303300D06092A864886F70D0101050500038181000B71581EDDC20E8C18C1C140BEE72501A97E04CA12030C51D4C38767B6A9FB5155CF4858C565EF77E5E2C22687C1AAB04BBA2B81C9A73CFB8DE118B624094AAE43D8FC2D585D90839DAFA5033AF7B8C0DE27E6ADAE44C40508CE493E9C80F1F5DA9EC87ECA1844BAB12C83CC8EB5937E1BE36A42CD22086A826E00FB763CD577");
+ /** Cert A with malformed syntax */
+ private static final Signature M = new Signature("308201D43082013CA0030201020219373565373461363A31336534333439623635343A2D38303030300D06092A864886F70D01010505003017311530130603550403130C6269736F6E416E64726F6964301E170D3133303432343232323134345A170D3338303432353232323134345A3017311530130603550403130C6269736F6E416E64726F696430819F300D06092A864886F70D010101050003818D00308189028181009214CE08563B77FF3128D3A303254287301263A842D19D5D4EAF024EBEDF864F3802C215B2F3EA85432F3EFF1DB8F591B0854FA7C1C6E4A8A85132FA762CC2D12A8EBD34D8B15C241A91716577F03BB3D2AFFC24367AB1E5E03C387891E34E646E47FAD75B178C1FD077B9199B3ABA6D48E2464801F6592E98245124046E51A90203010001A317301530130603551D25040C300A06082B06010505070303300D06092A864886F70D010105050003820081000B71581EDDC20E8C18C1C140BEE72501A97E04CA12030C51D4C38767B6A9FB5155CF4858C565EF77E5E2C22687C1AAB04BBA2B81C9A73CFB8DE118B624094AAE43D8FC2D585D90839DAFA5033AF7B8C0DE27E6ADAE44C40508CE493E9C80F1F5DA9EC87ECA1844BAB12C83CC8EB5937E1BE36A42CD22086A826E00FB763CD577");
+ /** Cert B with valid syntax */
+ private static final Signature B = new Signature("308204a830820390a003020102020900a1573d0f45bea193300d06092a864886f70d0101050500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3131303931393138343232355a170d3339303230343138343232355a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100de1b51336afc909d8bcca5920fcdc8940578ec5c253898930e985481cfdea75ba6fc54b1f7bb492a03d98db471ab4200103a8314e60ee25fef6c8b83bc1b2b45b084874cffef148fa2001bb25c672b6beba50b7ac026b546da762ea223829a22b80ef286131f059d2c9b4ca71d54e515a8a3fd6bf5f12a2493dfc2619b337b032a7cf8bbd34b833f2b93aeab3d325549a93272093943bb59dfc0197ae4861ff514e019b73f5cf10023ad1a032adb4b9bbaeb4debecb4941d6a02381f1165e1ac884c1fca9525c5854dce2ad8ec839b8ce78442c16367efc07778a337d3ca2cdf9792ac722b95d67c345f1c00976ec372f02bfcbef0262cc512a6845e71cfea0d020103a381fc3081f9301d0603551d0e0416041478a0fc4517fb70ff52210df33c8d32290a44b2bb3081c90603551d230481c13081be801478a0fc4517fb70ff52210df33c8d32290a44b2bba1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900a1573d0f45bea193300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100977302dfbf668d7c61841c9c78d2563bcda1b199e95e6275a799939981416909722713531157f3cdcfea94eea7bb79ca3ca972bd8058a36ad1919291df42d7190678d4ea47a4b9552c9dfb260e6d0d9129b44615cd641c1080580e8a990dd768c6ab500c3b964e185874e4105109d94c5bd8c405deb3cf0f7960a563bfab58169a956372167a7e2674a04c4f80015d8f7869a7a4139aecbbdca2abc294144ee01e4109f0e47a518363cf6e9bf41f7560e94bdd4a5d085234796b05c7a1389adfd489feec2a107955129d7991daa49afb3d327dc0dc4fe959789372b093a89c8dbfa41554f771c18015a6cb242a17e04d19d55d3b4664eae12caf2a11cd2b836e");
+
+ public void testExactlyEqual() throws Exception {
+ assertTrue(Signature.areExactMatch(asArray(A), asArray(A)));
+ assertTrue(Signature.areExactMatch(asArray(M), asArray(M)));
+
+ assertFalse(Signature.areExactMatch(asArray(A), asArray(B)));
+ assertFalse(Signature.areExactMatch(asArray(A), asArray(M)));
+ assertFalse(Signature.areExactMatch(asArray(M), asArray(A)));
+
+ assertTrue(Signature.areExactMatch(asArray(A, M), asArray(M, A)));
+ }
+
+ public void testEffectiveMatch() throws Exception {
+ assertTrue(Signature.areEffectiveMatch(asArray(A), asArray(A)));
+ assertTrue(Signature.areEffectiveMatch(asArray(M), asArray(M)));
+
+ assertFalse(Signature.areEffectiveMatch(asArray(A), asArray(B)));
+ assertTrue(Signature.areEffectiveMatch(asArray(A), asArray(M)));
+ assertTrue(Signature.areEffectiveMatch(asArray(M), asArray(A)));
+
+ assertTrue(Signature.areEffectiveMatch(asArray(A, M), asArray(M, A)));
+ assertTrue(Signature.areEffectiveMatch(asArray(A, B), asArray(M, B)));
+ assertFalse(Signature.areEffectiveMatch(asArray(A, M), asArray(A, B)));
+ }
+
+ private static Signature[] asArray(Signature... s) {
+ return s;
+ }
+}
diff --git a/docs/html/google/gcm/ccs.jd b/docs/html/google/gcm/ccs.jd
index 7db7a74..6332b8d 100644
--- a/docs/html/google/gcm/ccs.jd
+++ b/docs/html/google/gcm/ccs.jd
@@ -263,6 +263,21 @@
</message>
</pre>
+<p>Device Message Rate Exceeded:</p>
+
+<pre><message id="...">
+ <gcm xmlns="google:mobile:data">
+ {
+ "message_type":"nack",
+ "message_id":"msgId1",
+ "from":"REGID",
+ "error":"DEVICE_MESSAGE_RATE_EXCEEDED",
+ "error_description":"Downstream message rate exceeded for this registration id"
+ }
+ </gcm>
+</message>
+</pre>
+
<p>The following table lists NACK error codes. Unless otherwise
indicated, a NACKed message should not be retried. Unexpected NACK error codes
should be treated the same as {@code INTERNAL_SERVER_ERROR}.</p>
@@ -303,8 +318,7 @@
<td>{@code DEVICE_MESSAGE_RATE_EXCEEDED}</td>
<td>The rate of messages to a particular device is too high. You should reduce
the number of messages sent to this device and should not immediately retry
-sending to this device. This error code replaces {@code QUOTA_EXCEEDED},
-which has been deprecated.</td>
+sending to this device. This error code is replacing {@code QUOTA_EXCEEDED}.</td>
</tr>
<tr>
<td>{@code SERVICE_UNAVAILABLE}</td>
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
index 70109c6..d44ee3c 100644
--- a/docs/html/google/gcm/client.jd
+++ b/docs/html/google/gcm/client.jd
@@ -452,6 +452,21 @@
editor.commit();
}</pre>
+<h4 id="reg-errors">Handle registration errors</h4>
+
+<p>As stated above, an Android app must register with GCM servers and get a registration ID
+(regID) before it can receive messages. A given regID is not guaranteed to last indefinitely,
+so the first thing your app should always do is check to make sure it has a valid regID
+(as shown in the code snippets above).</p>
+
+<p>In addition to confirming that it has a valid regID, your app should be prepared to handle
+the registration error {@code TOO_MANY_REGISTRATIONS}. This error indicates that the device
+has too many apps registered with GCM. The error only occurs in cases where there are
+extreme numbers of apps, so it should not affect the average user. The remedy is to prompt
+the user to delete some of the other GCM-enabled apps from the device to make
+room for the new one.</p>
+
+
<h3 id="sample-send">Send a message</h3>
<p>When the user clicks the app's <strong>Send</strong> button, the app sends an
upstream message using the
diff --git a/docs/html/guide/components/intents-filters.jd b/docs/html/guide/components/intents-filters.jd
index 2f8c407..3dec216 100644
--- a/docs/html/guide/components/intents-filters.jd
+++ b/docs/html/guide/components/intents-filters.jd
@@ -139,7 +139,9 @@
intent when starting a {@link android.app.Service} and do not
declare intent filters for your services. Using an implicit intent to start a service is a
security hazard because you cannot be certain what service will respond to the intent,
-and the user cannot see which service starts.</p>
+and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system
+throws an exception if you call {@link android.content.Context#bindService bindService()}
+with an implicit intent.</p>
@@ -424,18 +426,18 @@
android.app.Activity#startActivity startActivity()}. For example:</p>
<pre>
-Intent intent = new Intent(Intent.ACTION_SEND);
+Intent sendIntent = new Intent(Intent.ACTION_SEND);
...
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
-// Create intent to show chooser
-Intent chooser = Intent.createChooser(intent, title);
+// Create intent to show the chooser dialog
+Intent chooser = Intent.createChooser(sendIntent, title);
-// Verify the intent will resolve to at least one activity
+// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
- startActivity(sendIntent);
+ startActivity(chooser);
}
</pre>
diff --git a/docs/html/samples/new/index.jd b/docs/html/samples/new/index.jd
index 330caa3..ba75072 100644
--- a/docs/html/samples/new/index.jd
+++ b/docs/html/samples/new/index.jd
@@ -12,99 +12,229 @@
</p>
-<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
-<div class="figure" style="width:220px">
- <img src="{@docRoot}samples/images/BasicManagedProfile.png"
- srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
- alt="" height="375" />
- <p class="img-caption">
- <strong>Figure 1.</strong> The BasicManagedProfile sample app.
- </p>
-</div>
+<!-- NOTE TO EDITORS: add most recent samples first -->
-<p>This sample demonstrates how to create a managed profile. You can also:</p>
-<ul>
- <li>Enable or disable other apps, and set restrictions on them.</li>
- <li>Configure intents to be forwarded between the primary account and the
- managed profile.</li>
- <li>Wipe all the data associated with the managed profile.</li>
-</ul>
+<h3 id="MediaBrowserService">Media Browser Service</h3>
-<p class="note"><strong>Note:</strong> There can be only one managed profile on
- a device at a time.</p>
+<p>
+This sample is a simple audio media app that exposes its media
+library and provides metadata and playback controls through the new
+MediaBrowserService and MediaSession APIs from API 21.
+The sample is compatible with Android Auto and also provides a basic UI
+when not connected to a car.
+</p>
-<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
+<p class="note">
+ <strong>Note:</strong> This sample is compatible with <a
+ href="http://android.com/auto">Android Auto</a>.
+</p>
-<h3 id="Camera2Basic">Camera2Basic</h3>
+<p><a href="http://github.com/googlesamples/android-MediaBrowserService">Get it on GitHub</a></p>
+
+
+<h3 id="MessagingService">Messaging Service</h3>
+
+<p>
+This sample shows a simple service that sends notifications using
+NotificationCompat. In addition to sending a notification, it also extends
+the notification with a CarExtender to make it compatible with Android Auto.
+Each unread conversation from a user is sent as a distinct notification.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> This sample is compatible with <a
+ href="http://android.com/auto">Android Auto</a>.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-MessagingService">Get it on GitHub</a></p>
+
+
+<h3 id="SpeedTracker">Speed Tracker (Wear)</h3>
+
+<p>
+This sample uses the FusedLocation APIs of Google Play Services on Android Wear
+devices that have a hardware GPS built in. In those cases, this sample provides
+a simple screen that shows the current speed of the wearable device. User can
+set a speed limit and if the speed approaches that limit, it changes the color
+to yellow and if it exceeds the limit, it turns red. User can also enable
+recording of coordinates and when it pairs back with the phone, this data
+is synced with the phone component of the app and user can see a track
+made of those coordinates on a map on the phone.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p>
+
+
+<h3 id="AppRestrictionSchema">AppRestrictionSchema</h3>
+
+<p>
+This sample shows how to use app restrictions. This application has one boolean
+restriction with a key "can_say_hello" that defines whether the only feature of this
+app (press the button to show "Hello" message) is enabled or disabled. Use
+AppRestrictionEnforcer sample to toggle the restriction.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p>
+
+
+<h3 id="AppRestrictionEnforcer">AppRestrictionEnforcer</h3>
+
+<p>
+This sample demonstrates how to set restrictions to other apps as a profile owner.
+Use AppRestrictionSchema sample as a app with available restrictions.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-AppRestrictionEnforcer">Get it on GitHub</a></p>
+
+
+<h3 id="DocumentCentricRelinquishIdentity">DocumentCentricRelinquishIdentity</h3>
+
+<p>
+This sample shows how to relinquish identity to activities above it in the task stack.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-DocumentCentricRelinquishIdentity">Get it on GitHub</a></p>
+
+
+<h3 id="DocumentCentricApps">DocumentCentricApps</h3>
+
+<p>
+This sample shows the basic usage of the new "Document Centric Apps" API.
+It let's you create new documents in the system overview menu and persists its
+state through reboots. If "Task per document" is checked a new task will be
+created for every new document in the overview menu.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-DocumentCentricApps">Get it on GitHub</a></p>
+
+
+<h3 id="HdrViewfinder">HdrViewfinder</h3>
+
+<p>
+This demo implements a real-time high-dynamic-range camera viewfinder, by alternating
+the sensor's exposure time between two exposure values on even and odd frames, and then
+compositing together the latest two frames whenever a new frame is captured.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-HdrViewfinder">Get it on GitHub</a></p>
+
+
+<h3 id="Interpolator">Interpolator</h3>
+
+<p>
+This sample demonstrates the use of animation interpolators and path animations for
+Material Design. It shows how an ObjectAnimator is used to animate two properties of a
+view (scale X and Y) along a path.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-Interpolator">Get it on GitHub</a></p>
+
+
+<h3 id="DrawableTinting">DrawableTinting</h3>
+
+<p>Sample that shows applying tinting and color filters to Drawables both programmatically
+and as Drawable resources in XML.</p>
+<p>Tinting is set on a nine-patch drawable through the "tint" and "tintMode" parameters.
+A color state list is referenced as the tint color, which defines colors for different
+states of a View (for example disabled/enabled, focused, pressed or selected).</p>
+<p>Programmatically, tinting is applied to a Drawable through its "setColorFilter" method,
+with a reference to a color and a PorterDuff blend mode. The color and blend mode can be
+changed from the UI to see the effect of different options.</p>
+
+<p><a href="http://github.com/googlesamples/android-DrawableTinting">Get it on GitHub</a></p>
+
+
+<h3 id="LNotifications">LNotifications</h3>
+
+<p>
+This sample demonstrates how new features for notifications introduced in Android 5.0
+are used such as Heads-Up notifications, visibility, people, category and priority
+metadata. </p>
+<p><a href="http://github.com/googlesamples/android-LNotifications">Get it on GitHub</a></p>
+
+
+<h3 id="CardView">CardView</h3>
+
+<p>
+This sample demonstrates how to use the CardView UI widget introduced in Android 5.0, using the support library for backward compatibility.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-CardView">Get it on GitHub</a></p>
+
+
+<h3 id="RecyclerView">RecyclerView</h3>
+
+<p>
+Demonstration of using RecyclerView with a LayoutManager to create a vertical ListView.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-RecyclerView">Get it on GitHub</a></p>
+
+
+<h3 id="RevealEffectBasic">RevealEffectBasic</h3>
+
+<p>
+A sample demonstrating how to perform a reveal effect for UI elements within the Material Design framework.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-RevealEffectBasic">Get it on GitHub</a></p>
+
+
+<h3 id="FloatingActionButtonBasic">FloatingActionButtonBasic</h3>
+
+<p>
+This sample shows the two sizes of Floating Action Buttons and how to interact with
+them.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-FloatingActionButtonBasic">Get it on GitHub</a></p>
+
<!--
+<h3 id="">SampleName</h3>
+
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
<p class="img-caption">
<strong>Figure n.</strong> Single sentence summarizing the figure.
</p>
</div>
+
+<p>
+**description**
+</p>
-->
-<p>This sample demonstrates the basic use of the Camera2 API. The sample code
-demonstrates how you can display camera preview and take pictures.</p>
-<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
-
-
-<h3 id="Camera2Video">Camera2Video</h3>
+<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
<!--
<div class="figure" style="width:220px">
-<img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>This sample demonstrates how to record video using the Camera2 API.</p>
-
-<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
-
-<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
-<div class="figure" style="width:220px">
- <img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
- srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
- alt="" height="375" />
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
<p class="img-caption">
- <strong>Figure 2.</strong> The ActivitySceneTransitionBasic sample app.
- </p>
- </div>
-
-<p> This sample demonstrates how to the use {@link android.app.Activity} scene
-transitions when transitioning from one activity to another. Uses a combination
-of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
-from a grid of images to an activity with a large image and detail text. </p>
-
-<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
-
-<h3 id="ElevationBasic">ElevationBasic</h3>
-<!--
-<div class="figure" style="width:220px">
-<img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
<strong>Figure n.</strong> Single sentence summarizing the figure.
</p>
</div>
-->
<p>
-This sample demonstrates two alternative ways to move a view in the z-axis:</p>
+This sample illustrates a common usage of the Android support library's
+{@link android.support.v4.widget.DrawerLayout} widget.
+</p>
-<ul>
- <li>With a fixed elevation, using XML.</li>
- <li>Raising the elevation when the user taps on it, using
- <code>setTranslationZ()</code>.</li>
-</ul>
+<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
-<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
-<h3 id="ElevationDrag">ElevationDrag</h3>
+<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
+
+<p>
+This sample app allows the user to schedule jobs through the UI, and shows
+visual cues when the jobs are executed.
+</p>
+
+<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
+
+
+<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -114,11 +244,46 @@
</div>
-->
-<p>This sample demonstrates a drag and drop action on different shapes.
-Elevation and z-translation are used to render the shadows. The views are
-clipped using different outlines.</p>
+<p>
+This sample demonstrates use of the Android TV Leanback Support Library.
+</p>
-<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
+<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
+
+
+<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample displays events received from a game controller shown on the screen.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
+
+
+<h3 id="GameControllerSample">GameControllerSample</h3>
+<!--
+<div class="figure" style="width:220px">
+ <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>
+This sample implements a multi-player game, demonstrating game controller input
+handling.
+</p>
+
+<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
<h3 id="ClippingBasic">ClippingBasic</h3>
@@ -146,7 +311,8 @@
</p>
</div>
-<h3 id="GameControllerSample">GameControllerSample</h3>
+
+<h3 id="ElevationDrag">ElevationDrag</h3>
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -156,15 +322,70 @@
</div>
-->
+<p>This sample demonstrates a drag and drop action on different shapes.
+Elevation and z-translation are used to render the shadows. The views are
+clipped using different outlines.</p>
+
+<p><a href="http://github.com/googlesamples/android-ElevationDrag">Get it on GitHub</a></p>
+
+
+<h3 id="ElevationBasic">ElevationBasic</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
<p>
-This sample implements a multi-player game, demonstrating game controller input
-handling.
-</p>
+This sample demonstrates two alternative ways to move a view in the z-axis:</p>
-<p><a href="http://github.com/googlesamples/androidtv-GameController">Get it on GitHub</a></p>
+<ul>
+ <li>With a fixed elevation, using XML.</li>
+ <li>Raising the elevation when the user taps on it, using
+ <code>setTranslationZ()</code>.</li>
+</ul>
+
+<p><a href="http://github.com/googlesamples/android-ElevationBasic">Get it on GitHub</a></p>
-<h3 id="Visual-Game-Controller">Visual-Game-Controller</h3>
+<h3 id="ActivitySceneTransitionBasic">ActivitySceneTransitionBasic</h3>
+<div class="figure" style="width:220px">
+ <img src="{@docRoot}samples/images/ActivitySceneTransitionBasic.png"
+ srcset="{@docRoot}samples/images/ActivitySceneTransitionBasic@2x.png 2x"
+ alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure 2.</strong> The ActivitySceneTransitionBasic sample app.
+ </p>
+ </div>
+
+<p> This sample demonstrates how to the use {@link android.app.Activity} scene
+transitions when transitioning from one activity to another. Uses a combination
+of <code>moveImage</code> and <code>changeBounds</code> to nicely transition
+from a grid of images to an activity with a large image and detail text. </p>
+
+<p><a href="http://github.com/googlesamples/android-ActivitySceneTransition">Get it on GitHub</a></p>
+
+
+<h3 id="Camera2Video">Camera2Video</h3>
+<!--
+<div class="figure" style="width:220px">
+<img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <p class="img-caption">
+ <strong>Figure n.</strong> Single sentence summarizing the figure.
+ </p>
+</div>
+-->
+
+<p>This sample demonstrates how to record video using the Camera2 API.</p>
+
+<p><a href="http://github.com/googlesamples/android-Camera2Video">Get it on GitHub</a></p>
+
+
+<h3 id="Camera2Basic">Camera2Basic</h3>
+
<!--
<div class="figure" style="width:220px">
<img src="" srcset="@2x.png 2x" alt="" height="375" />
@@ -174,192 +395,32 @@
</div>
-->
-<p>
-This sample displays events received from a game controller shown on the screen.
-</p>
+<p>This sample demonstrates the basic use of the Camera2 API. The sample code
+demonstrates how you can display camera preview and take pictures.</p>
-<p><a href="http://github.com/googlesamples/androidtv-VisualGameController">Get it on GitHub</a></p>
+<p><a href="http://github.com/googlesamples/android-Camera2Basic">Get it on GitHub</a></p>
-<h3 id="AndroidTVLeanbackSample">AndroidTVLeanbackSample</h3>
-<!--
+
+<h3 id="BasicManagedProfile">BasicManagedProfile</h3>
<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
+ <img src="{@docRoot}samples/images/BasicManagedProfile.png"
+ srcset="{@docRoot}samples/images/BasicManagedProfile@2x.png 2x"
+ alt="" height="375" />
<p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>
-This sample demonstrates use of the Android TV Leanback Support Library.
-</p>
-
-<p><a href="http://github.com/googlesamples/androidtv-Leanback">Get it on GitHub</a></p>
-
-<h3 id="JobSchedulerSample">JobSchedulerSample</h3>
-
-<p>
-This sample app allows the user to schedule jobs through the UI, and shows
-visual cues when the jobs are executed.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-JobScheduler">Get it on GitHub</a></p>
-
-<h3 id="NavigationDrawerSample">NavigationDrawerSample</h3>
-<!--
-<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
- </p>
-</div>
--->
-
-<p>
-This sample illustrates a common usage of the Android support library's
-{@link android.support.v4.widget.DrawerLayout} widget.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-NavigationDrawer">Get it on GitHub</a></p>
-<!--
-<h3 id="">SampleName</h3>
-
-<div class="figure" style="width:220px">
- <img src="" srcset="@2x.png 2x" alt="" height="375" />
- <p class="img-caption">
- <strong>Figure n.</strong> Single sentence summarizing the figure.
+ <strong>Figure 1.</strong> The BasicManagedProfile sample app.
</p>
</div>
-<p>
-**description**
-</p>
--->
+<p>This sample demonstrates how to create a managed profile. You can also:</p>
+<ul>
+ <li>Enable or disable other apps, and set restrictions on them.</li>
+ <li>Configure intents to be forwarded between the primary account and the
+ managed profile.</li>
+ <li>Wipe all the data associated with the managed profile.</li>
+</ul>
-<h3 id="FloatingActionButtonBasic">FloatingActionButtonBasic</h3>
+<p class="note"><strong>Note:</strong> There can be only one managed profile on
+ a device at a time.</p>
-<p>
-This sample shows the two sizes of Floating Action Buttons and how to interact with
-them.
-</p>
+<p><a href="http://github.com/googlesamples/android-BasicManagedProfile">Get it on GitHub</a></p>
-<p><a href="http://github.com/googlesamples/android-FloatingActionButtonBasic">Get it on GitHub</a></p>
-
-<h3 id="RevealEffectBasic">RevealEffectBasic</h3>
-
-<p>
-A sample demonstrating how to perform a reveal effect for UI elements within the Material Design framework.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-RevealEffectBasic">Get it on GitHub</a></p>
-
-<h3 id="RecyclerView">RecyclerView</h3>
-
-<p>
-Demonstration of using RecyclerView with a LayoutManager to create a vertical ListView.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-RecyclerView">Get it on GitHub</a></p>
-
-<h3 id="CardView">CardView</h3>
-
-<p>
-This sample demonstrates how to use the CardView UI widget introduced in Android 5.0, using the support library for backward compatibility.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-CardView">Get it on GitHub</a></p>
-
-<h3 id="LNotifications">LNotifications</h3>
-
-<p>
-This sample demonstrates how new features for notifications introduced in Android 5.0
-are used such as Heads-Up notifications, visibility, people, category and priority
-metadata. </p>
-<p><a href="http://github.com/googlesamples/android-LNotifications">Get it on GitHub</a></p>
-
-<h3 id="DrawableTinting">DrawableTinting</h3>
-
-<p>Sample that shows applying tinting and color filters to Drawables both programmatically
-and as Drawable resources in XML.</p>
-<p>Tinting is set on a nine-patch drawable through the "tint" and "tintMode" parameters.
-A color state list is referenced as the tint color, which defines colors for different
-states of a View (for example disabled/enabled, focused, pressed or selected).</p>
-<p>Programmatically, tinting is applied to a Drawable through its "setColorFilter" method,
-with a reference to a color and a PorterDuff blend mode. The color and blend mode can be
-changed from the UI to see the effect of different options.</p>
-
-<p><a href="http://github.com/googlesamples/android-DrawableTinting">Get it on GitHub</a></p>
-
-<h3 id="Interpolator">Interpolator</h3>
-
-<p>
-This sample demonstrates the use of animation interpolators and path animations for
-Material Design. It shows how an ObjectAnimator is used to animate two properties of a
-view (scale X and Y) along a path.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-Interpolator">Get it on GitHub</a></p>
-
-<h3 id="HdrViewfinder">HdrViewfinder</h3>
-
-<p>
-This demo implements a real-time high-dynamic-range camera viewfinder, by alternating
-the sensor's exposure time between two exposure values on even and odd frames, and then
-compositing together the latest two frames whenever a new frame is captured.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-HdrViewfinder">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricApps">DocumentCentricApps</h3>
-
-<p>
-This sample shows the basic usage of the new "Document Centric Apps" API.
-It let's you create new documents in the system overview menu and persists its
-state through reboots. If "Task per document" is checked a new task will be
-created for every new document in the overview menu.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-DocumentCentricApps">Get it on GitHub</a></p>
-
-<h3 id="DocumentCentricRelinquishIdentity">DocumentCentricRelinquishIdentity</h3>
-
-<p>
-This sample shows how to relinquish identity to activities above it in the task stack.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-DocumentCentricRelinquishIdentity">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionEnforcer">AppRestrictionEnforcer</h3>
-
-<p>
-This sample demonstrates how to set restrictions to other apps as a profile owner.
-Use AppRestrictionSchema sample as a app with available restrictions.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-AppRestrictionEnforcer">Get it on GitHub</a></p>
-
-<h3 id="AppRestrictionSchema">AppRestrictionSchema</h3>
-
-<p>
-This sample shows how to use app restrictions. This application has one boolean
-restriction with a key "can_say_hello" that defines whether the only feature of this
-app (press the button to show "Hello" message) is enabled or disabled. Use
-AppRestrictionEnforcer sample to toggle the restriction.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p>
-
-<h3 id="SpeedTracker">Speed Tracker (Wear)</h3>
-
-<p>
-This sample uses the FusedLocation APIs of Google Play Services on Android Wear
-devices that have a hardware GPS built in. In those cases, this sample provides
-a simple screen that shows the current speed of the wearable device. User can
-set a speed limit and if the speed approaches that limit, it changes the color
-to yellow and if it exceeds the limit, it turns red. User can also enable
-recording of coordinates and when it pairs back with the phone, this data
-is synced with the phone component of the app and user can see a track
-made of those coordinates on a map on the phone.
-</p>
-
-<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p>
diff --git a/docs/html/samples/notification.jd b/docs/html/samples/notification.jd
new file mode 100644
index 0000000..bbcea93
--- /dev/null
+++ b/docs/html/samples/notification.jd
@@ -0,0 +1,11 @@
+page.title=Notification
+@jd:body
+
+
+<div id="samples" class="notification">
+</div>
+
+
+<script>
+ $(document).ready(showSamples);
+</script>
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
index 249c42d..f0024e2 100644
--- a/docs/html/training/location/index.jd
+++ b/docs/html/training/location/index.jd
@@ -21,7 +21,8 @@
<h2>You should also read</h2>
<ul>
<li>
- <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
+ <a href="{@docRoot}google/play-services/setup.html">Set Up Google Play
+ Services SDK</a>
</li>
</ul>
@@ -29,68 +30,75 @@
</div>
<p>
- One of the unique features of mobile applications is location awareness. Mobile users bring
- their devices with them everywhere, and adding location awareness to your app offers users a
- more contextual experience. The new Location Services API available in Google Play services
- facilitates adding location awareness to your app with automated location tracking,
- geofencing, and activity recognition. This API adds significant advantages over the plaform's
- location API.
+ One of the unique features of mobile applications is location awareness.
+ Mobile users take their devices with them everywhere, and adding location
+ awareness to your app offers users a more contextual experience. The location
+ APIs available in Google Play services facilitate adding location awareness to
+ your app with automated location tracking, geofencing, and activity
+ recognition.
</p>
+
+<p>The
+ <a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">Google
+ Play services location APIs</a> are preferred over the Android framework
+ location APIs
+ (<a href="{@docRoot}reference/android/location/package-summary.html">android.location</a>)
+ as a way of adding location awareness to your app. If you are currently using
+ the Android framework location APIs, you are strongly encouraged to switch to
+ the Google Play services location APIs as soon as possible.
+</p>
+
<p>
- This class shows you how to use Location Services in your app to get the current location,
- get periodic location updates, look up addresses, create and monitor geofences, and
- detect user activities. The class includes sample apps and code snippets that you can use as a
- starting point for adding location awareness to your own app.
+ This class shows you how to use the Google Play services location APIs in your
+ app to get the current location, get periodic location updates, look up
+ addresses, create and monitor geofences, and detect user activities. The class
+ includes sample apps and code snippets that you can use as a starting point
+ for adding location awareness to your app.
</p>
+
<p class="note">
- <strong>Note:</strong> Since this class is based on the Google Play services client library,
- make sure you install the latest version before using the sample apps or code snippets. To learn
- how to set up the client library with the latest version, see
- <a href="{@docRoot}google/play-services/setup.html">Setup</a> in the Google Play services guide.
+ <strong>Note:</strong> Since this class is based on the Google Play services
+ client library, make sure you install the latest version before using the
+ sample apps or code snippets. To learn how to set up the client library with
+ the latest version, see
+ <a href="{@docRoot}google/play-services/setup.html">Setup</a> in the Google
+ Play services guide.
</p>
<h2>Lessons</h2>
<dl>
- <dt>
- <b><a href="retrieve-current.html">Retrieving the Current Location</a></b>
- </dt>
- <dd>
- Learn how to retrieve the user's current location.
- </dd>
- <dt>
- <b><a href="receive-location-updates.html">Receiving Location Updates</a></b>
- </dt>
- <dd>
- Learn how to request and receive periodic location updates.
- </dd>
- <dt>
- <b><a href="display-address.html">Displaying a Location Address</a></b>
- </dt>
- <dd>
- Learn how to convert a location's latitude and longitude into an address (reverse
- geocoding).
- </dd>
- <dt>
- <b>
- <a href="geofencing.html">Creating and Monitoring Geofences</a>
- </b>
- </dt>
- <dd>
- Learn how to define one or more geographic areas as locations of interest, called geofences,
- and detect when the user is close to or inside a geofence.
- </dd>
- <dt>
- <b><a href="activity-recognition.html">Recognizing the User's Current Activity</a></b>
- </dt>
- <dd>
- Learn how to recognize the user's current activity, such as walking, bicycling,
- or driving a car, and how to use this information to modify your app's location strategy.
- </dd>
- <dt>
- <b><a href="location-testing.html">Testing Using Mock Locations</a></b>
- </dt>
- <dd>
- Learn how to test a location-aware app by injecting mock locations into Location
- Services. In mock mode, Location Services sends out mock locations that you inject instead
- of sensor-based locations.
- </dd>
+ <dt>
+ <b><a href="retrieve-current.html">Retrieving the Current Location</a></b>
+ </dt> <dd>
+ Learn how to retrieve the user's current location.
+ </dd> <dt>
+ <b><a href="receive-location-updates.html">Receiving Location
+ Updates</a></b>
+ </dt> <dd>
+ Learn how to request and receive periodic location updates.
+ </dd> <dt>
+ <b><a href="display-address.html">Displaying a Location Address</a></b>
+ </dt> <dd>
+ Learn how to convert a location's latitude and longitude into an address
+ (reverse geocoding).
+ </dd> <dt>
+ <b>
+ <a href="geofencing.html">Creating and Monitoring Geofences</a>
+ </b>
+ </dt> <dd>
+ Learn how to define one or more geographic areas as locations of interest,
+ called geofences, and detect when the user is close to or inside a geofence.
+ </dd> <dt>
+ <b><a href="activity-recognition.html">Recognizing the User's Current
+ Activity</a></b>
+ </dt> <dd>
+ Learn how to recognize the user's current activity, such as walking,
+ bicycling, or driving a car, and how to use this information to modify your
+ app's location strategy.
+ </dd> <dt>
+ <b><a href="location-testing.html">Testing Using Mock Locations</a></b>
+ </dt> <dd>
+ Learn how to test a location-aware app by injecting mock locations into
+ Location Services. In mock mode, Location Services sends out mock locations
+ that you inject instead of sensor-based locations.
+ </dd>
</dl>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index f45c0cb..8279a51 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -250,6 +250,15 @@
public void insertInorderBarrier() {}
/**
+ * Set a transfer mode that overrides any transfer modes
+ * in paints used for drawing. Pass null to disable this
+ * override. Only implemented in GLES20Canvas.
+ *
+ * @hide
+ */
+ public void setOverrideXfermode(@Nullable PorterDuff.Mode xfermode) {}
+
+ /**
* Return true if the device that the current layer draws into is opaque
* (i.e. does not support per-pixel alpha).
*
@@ -353,25 +362,51 @@
@Retention(RetentionPolicy.SOURCE)
public @interface Saveflags {}
- /** restore the current matrix when restore() is called */
+ /**
+ * Restore the current matrix when restore() is called.
+ */
public static final int MATRIX_SAVE_FLAG = 0x01;
- /** restore the current clip when restore() is called */
+
+ /**
+ * Restore the current clip when restore() is called.
+ */
public static final int CLIP_SAVE_FLAG = 0x02;
- /** the layer needs to per-pixel alpha */
+
+ /**
+ * The layer requires a per-pixel alpha channel.
+ */
public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
- /** the layer needs to 8-bits per color component */
+
+ /**
+ * The layer requires full 8-bit precision for each color channel.
+ */
public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
- /** clip against the layer's bounds */
+
+ /**
+ * Clip drawing to the bounds of the offscreen layer, omit at your own peril.
+ * <p class="note"><strong>Note:</strong> it is strongly recommended to not
+ * omit this flag for any call to <code>saveLayer()</code> and
+ * <code>saveLayerAlpha()</code> variants. Not passing this flag generally
+ * triggers extremely poor performance with hardware accelerated rendering.
+ */
public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
- /** restore everything when restore() is called */
+
+ /**
+ * Restore everything when restore() is called (standard save flags).
+ * <p class="note"><strong>Note:</strong> for performance reasons, it is
+ * strongly recommended to pass this - the complete set of flags - to any
+ * call to <code>saveLayer()</code> and <code>saveLayerAlpha()</code>
+ * variants.
+ */
public static final int ALL_SAVE_FLAG = 0x1F;
/**
- * Saves the current matrix and clip onto a private stack. Subsequent
- * calls to translate,scale,rotate,skew,concat or clipRect,clipPath
- * will all operate as usual, but when the balancing call to restore()
- * is made, those calls will be forgotten, and the settings that existed
- * before the save() will be reinstated.
+ * Saves the current matrix and clip onto a private stack.
+ * <p>
+ * Subsequent calls to translate,scale,rotate,skew,concat or clipRect,
+ * clipPath will all operate as usual, but when the balancing call to
+ * restore() is made, those calls will be forgotten, and the settings that
+ * existed before the save() will be reinstated.
*
* @return The value to pass to restoreToCount() to balance this save()
*/
@@ -381,10 +416,15 @@
/**
* Based on saveFlags, can save the current matrix and clip onto a private
- * stack. Subsequent calls to translate,scale,rotate,skew,concat or
- * clipRect,clipPath will all operate as usual, but when the balancing
- * call to restore() is made, those calls will be forgotten, and the
- * settings that existed before the save() will be reinstated.
+ * stack.
+ * <p class="note"><strong>Note:</strong> if possible, use the
+ * parameter-less save(). It is simpler and faster than individually
+ * disabling the saving of matrix or clip with this method.
+ * <p>
+ * Subsequent calls to translate,scale,rotate,skew,concat or clipRect,
+ * clipPath will all operate as usual, but when the balancing call to
+ * restore() is made, those calls will be forgotten, and the settings that
+ * existed before the save() will be reinstated.
*
* @param saveFlags flag bits that specify which parts of the Canvas state
* to save/restore
@@ -395,19 +435,33 @@
}
/**
- * This behaves the same as save(), but in addition it allocates an
- * offscreen bitmap. All drawing calls are directed there, and only when
- * the balancing call to restore() is made is that offscreen transfered to
- * the canvas (or the previous layer). Subsequent calls to translate,
- * scale, rotate, skew, concat or clipRect, clipPath all operate on this
- * copy. When the balancing call to restore() is made, this copy is
- * deleted and the previous matrix/clip state is restored.
+ * This behaves the same as save(), but in addition it allocates and
+ * redirects drawing to an offscreen bitmap.
+ * <p class="note"><strong>Note:</strong> this method is very expensive,
+ * incurring more than double rendering cost for contained content. Avoid
+ * using this method, especially if the bounds provided are large, or if
+ * the {@link #CLIP_TO_LAYER_SAVE_FLAG} is omitted from the
+ * {@code saveFlags} parameter. It is recommended to use a
+ * {@link android.view.View#LAYER_TYPE_HARDWARE hardware layer} on a View
+ * to apply an xfermode, color filter, or alpha, as it will perform much
+ * better than this method.
+ * <p>
+ * All drawing calls are directed to a newly allocated offscreen bitmap.
+ * Only when the balancing call to restore() is made, is that offscreen
+ * buffer drawn back to the current target of the Canvas (either the
+ * screen, it's target Bitmap, or the previous layer).
+ * <p>
+ * Attributes of the Paint - {@link Paint#getAlpha() alpha},
+ * {@link Paint#getXfermode() Xfermode}, and
+ * {@link Paint#getColorFilter() ColorFilter} are applied when the
+ * offscreen bitmap is drawn back when restore() is called.
*
* @param bounds May be null. The maximum size the offscreen bitmap
* needs to be (in local coordinates)
* @param paint This is copied, and is applied to the offscreen when
* restore() is called.
- * @param saveFlags see _SAVE_FLAG constants
+ * @param saveFlags see _SAVE_FLAG constants, generally {@link #ALL_SAVE_FLAG} is recommended
+ * for performance reasons.
* @return value to pass to restoreToCount() to balance this save()
*/
public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags) {
@@ -442,19 +496,31 @@
}
/**
- * This behaves the same as save(), but in addition it allocates an
- * offscreen bitmap. All drawing calls are directed there, and only when
- * the balancing call to restore() is made is that offscreen transfered to
- * the canvas (or the previous layer). Subsequent calls to translate,
- * scale, rotate, skew, concat or clipRect, clipPath all operate on this
- * copy. When the balancing call to restore() is made, this copy is
- * deleted and the previous matrix/clip state is restored.
+ * This behaves the same as save(), but in addition it allocates and
+ * redirects drawing to an offscreen bitmap.
+ * <p class="note"><strong>Note:</strong> this method is very expensive,
+ * incurring more than double rendering cost for contained content. Avoid
+ * using this method, especially if the bounds provided are large, or if
+ * the {@link #CLIP_TO_LAYER_SAVE_FLAG} is omitted from the
+ * {@code saveFlags} parameter. It is recommended to use a
+ * {@link android.view.View#LAYER_TYPE_HARDWARE hardware layer} on a View
+ * to apply an xfermode, color filter, or alpha, as it will perform much
+ * better than this method.
+ * <p>
+ * All drawing calls are directed to a newly allocated offscreen bitmap.
+ * Only when the balancing call to restore() is made, is that offscreen
+ * buffer drawn back to the current target of the Canvas (either the
+ * screen, it's target Bitmap, or the previous layer).
+ * <p>
+ * The {@code alpha} parameter is applied when the offscreen bitmap is
+ * drawn back when restore() is called.
*
* @param bounds The maximum size the offscreen bitmap needs to be
* (in local coordinates)
* @param alpha The alpha to apply to the offscreen when when it is
drawn during restore()
- * @param saveFlags see _SAVE_FLAG constants
+ * @param saveFlags see _SAVE_FLAG constants, generally {@link #ALL_SAVE_FLAG} is recommended
+ * for performance reasons.
* @return value to pass to restoreToCount() to balance this call
*/
public int saveLayerAlpha(@Nullable RectF bounds, int alpha, @Saveflags int saveFlags) {
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 4bf0b71..f76184f 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -221,4 +221,15 @@
mRect = null;
mRadius = -1.0f;
}
+
+ /**
+ * Offsets the Outline by (dx,dy)
+ */
+ public void offset(int dx, int dy) {
+ if (mRect != null) {
+ mRect.offset(dx, dy);
+ } else if (mPath != null) {
+ mPath.offset(dx, dy);
+ }
+ }
}
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index c40a66d..0e9823d 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -678,7 +678,7 @@
}
/**
- * Offset the path by (dx,dy), returning true on success
+ * Offset the path by (dx,dy)
*
* @param dx The amount in the X direction to offset the entire path
* @param dy The amount in the Y direction to offset the entire path
@@ -695,7 +695,7 @@
}
/**
- * Offset the path by (dx,dy), returning true on success
+ * Offset the path by (dx,dy)
*
* @param dx The amount in the X direction to offset the entire path
* @param dy The amount in the Y direction to offset the entire path
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 84555c6..6d23634 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -142,12 +142,18 @@
// If we're not already at the target index, either attempt to find a
// valid transition to it or jump directly there.
final int targetIndex = mState.indexOfKeyframe(stateSet);
- final boolean changedIndex = targetIndex != getCurrentIndex()
+ boolean changed = targetIndex != getCurrentIndex()
&& (selectTransition(targetIndex) || selectDrawable(targetIndex));
- // Always call super.onStateChanged() to propagate the state change to
- // the current drawable.
- return super.onStateChange(stateSet) || changedIndex;
+ // We need to propagate the state change to the current drawable, but
+ // we can't call StateListDrawable.onStateChange() without changing the
+ // current drawable.
+ final Drawable current = getCurrent();
+ if (current != null) {
+ changed |= current.setState(stateSet);
+ }
+
+ return changed;
}
private boolean selectTransition(int toIndex) {
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index e65dbaf..d0edeba 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -435,13 +435,16 @@
@Override
public void start() {
+ // If any one of the animator has not ended, do nothing.
+ if (isStarted()) {
+ return;
+ }
+ // Otherwise, kick off every animator.
final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
final int size = animators.size();
for (int i = 0; i < size; i++) {
final Animator animator = animators.get(i);
- if (!animator.isStarted()) {
- animator.start();
- }
+ animator.start();
}
invalidateSelf();
}
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index a8b6c94..2ddf9df 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -285,7 +285,6 @@
private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
Theme theme) throws XmlPullParserException, IOException {
- TypedArray a;
int type;
final int innerDepth = parser.getDepth()+1;
@@ -300,7 +299,8 @@
continue;
}
- a = obtainAttributes(r, theme, attrs, R.styleable.AnimationDrawableItem);
+ final TypedArray a = obtainAttributes(r, theme, attrs,
+ R.styleable.AnimationDrawableItem);
final int duration = a.getInt(R.styleable.AnimationDrawableItem_duration, -1);
if (duration < 0) {
@@ -308,14 +308,11 @@
+ ": <item> tag requires a 'duration' attribute");
}
- final int drawableRes = a.getResourceId(R.styleable.AnimationDrawableItem_drawable, 0);
+ Drawable dr = a.getDrawable(R.styleable.AnimationDrawableItem_drawable);
a.recycle();
- Drawable dr;
- if (drawableRes != 0) {
- dr = r.getDrawable(drawableRes, theme);
- } else {
+ if (dr == null) {
while ((type=parser.next()) == XmlPullParser.TEXT) {
// Empty
}
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 3304b33..1ee44fb 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -497,6 +497,7 @@
state.mFromDegrees = a.getFloat(R.styleable.RotateDrawable_fromDegrees, state.mFromDegrees);
state.mToDegrees = a.getFloat(R.styleable.RotateDrawable_toDegrees, state.mToDegrees);
+ state.mCurrentDegrees = state.mFromDegrees;
final Drawable dr = a.getDrawable(R.styleable.RotateDrawable_drawable);
if (dr != null) {
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 35ef76f..d6d4cb8 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -173,9 +173,9 @@
a, R.styleable.ScaleDrawable_scaleWidth, state.mScaleWidth);
state.mScaleHeight = getPercent(
a, R.styleable.ScaleDrawable_scaleHeight, state.mScaleHeight);
- state.mGravity = a.getInt(R.styleable.ScaleDrawable_scaleGravity, Gravity.LEFT);
+ state.mGravity = a.getInt(R.styleable.ScaleDrawable_scaleGravity, state.mGravity);
state.mUseIntrinsicSizeAsMin = a.getBoolean(
- R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, false);
+ R.styleable.ScaleDrawable_useIntrinsicSizeAsMinimum, state.mUseIntrinsicSizeAsMin);
final Drawable dr = a.getDrawable(R.styleable.ScaleDrawable_drawable);
if (dr != null) {
@@ -347,13 +347,16 @@
}
final static class ScaleState extends ConstantState {
+ /** Constant used to disable scaling for a particular dimension. */
+ private static final float DO_NOT_SCALE = -1.0f;
+
int[] mThemeAttrs;
int mChangingConfigurations;
Drawable mDrawable;
- float mScaleWidth = 1.0f;
- float mScaleHeight = 1.0f;
+ float mScaleWidth = DO_NOT_SCALE;
+ float mScaleHeight = DO_NOT_SCALE;
int mGravity = Gravity.LEFT;
boolean mUseIntrinsicSizeAsMin = false;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index c2cb76e..3ec5e40 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -39,6 +39,7 @@
, mTranslateY(0.0f)
, mDeferredBarrierType(kBarrier_None)
, mHighContrastText(false)
+ , mOverrideXfermode(-1)
, mRestoreSaveCount(-1) {
}
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 2cc2be3..f93a798 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -20,6 +20,7 @@
#include <SkMatrix.h>
#include <SkPaint.h>
#include <SkPath.h>
+#include <SkPorterDuff.h>
#include <cutils/compiler.h>
#include "DisplayListLogBuffer.h"
@@ -161,6 +162,15 @@
void setHighContrastText(bool highContrastText) {
mHighContrastText = highContrastText;
}
+
+ void setOverrideXfermode(int xfermode) {
+ if (xfermode != -1) {
+ SkPorterDuff::Mode porterDuffMode = static_cast<SkPorterDuff::Mode>(xfermode);
+ xfermode = SkPorterDuff::ToXfermodeMode(porterDuffMode);
+ }
+ mOverrideXfermode = xfermode;
+ };
+
private:
enum DeferredBarrierType {
kBarrier_None,
@@ -220,18 +230,26 @@
inline const SkPaint* refPaint(const SkPaint* paint) {
if (!paint) return NULL;
- const SkPaint* paintCopy = mPaintMap.valueFor(paint);
- if (paintCopy == NULL
- || paintCopy->getGenerationID() != paint->getGenerationID()
- // We can't compare shader pointers because that will always
- // change as we do partial copying via wrapping. However, if the
- // shader changes the paint generationID will have changed and
- // so we don't hit this comparison anyway
- || !(paint->getShader() && paintCopy->getShader()
- && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) {
- paintCopy = copyPaint(paint);
- // replaceValueFor() performs an add if the entry doesn't exist
- mPaintMap.replaceValueFor(paint, paintCopy);
+ const SkPaint* paintCopy;
+
+ if (mOverrideXfermode != -1) {
+ SkPaint* overriddenPaint = copyPaint(paint);
+ overriddenPaint->setXfermodeMode(static_cast<SkXfermode::Mode>(mOverrideXfermode));
+ paintCopy = overriddenPaint;
+ } else {
+ paintCopy = mPaintMap.valueFor(paint);
+ if (paintCopy == NULL
+ || paintCopy->getGenerationID() != paint->getGenerationID()
+ // We can't compare shader pointers because that will always
+ // change as we do partial copying via wrapping. However, if the
+ // shader changes the paint generationID will have changed and
+ // so we don't hit this comparison anyway
+ || !(paint->getShader() && paintCopy->getShader()
+ && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) {
+ paintCopy = copyPaint(paint);
+ // replaceValueFor() performs an add if the entry doesn't exist
+ mPaintMap.replaceValueFor(paint, paintCopy);
+ }
}
return paintCopy;
@@ -304,6 +322,9 @@
DeferredBarrierType mDeferredBarrierType;
bool mHighContrastText;
+ // -1 if unset, or SkXfermode::Mode value if set
+ int mOverrideXfermode;
+
int mRestoreSaveCount;
friend class RenderNode;
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index e8f1b9a..b2dd899 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -677,11 +677,13 @@
return resultIndex;
}
+// Allow some epsilon here since the later ray intersection did allow for some small
+// floating point error, when the intersection point is slightly outside the segment.
inline bool sameDirections(bool isPositiveCross, float a, float b) {
if (isPositiveCross) {
- return a >= 0 && b >= 0;
+ return a >= -EPSILON && b >= -EPSILON;
} else {
- return a <= 0 && b <= 0;
+ return a <= EPSILON && b <= EPSILON;
}
}
@@ -721,22 +723,23 @@
// For current penumbra vertex, starting from previousClosestUmbraIndex,
// then check the next one until the distance increase.
// The last one before the increase is the umbra vertex we need to pair with.
- int currentUmbraIndex = previousClosestUmbraIndex;
- float currentLengthSquared = (currentPenumbraVertex - umbra[currentUmbraIndex]).lengthSquared();
- int currentClosestUmbraIndex = -1;
+ float currentLengthSquared =
+ (currentPenumbraVertex - umbra[previousClosestUmbraIndex]).lengthSquared();
+ int currentClosestUmbraIndex = previousClosestUmbraIndex;
int indexDelta = 0;
for (int j = 1; j < umbraLength; j++) {
int newUmbraIndex = (previousClosestUmbraIndex + j) % umbraLength;
float newLengthSquared = (currentPenumbraVertex - umbra[newUmbraIndex]).lengthSquared();
if (newLengthSquared > currentLengthSquared) {
- currentClosestUmbraIndex = (previousClosestUmbraIndex + j - 1) % umbraLength;
+ // currentClosestUmbraIndex is the umbra vertex's index which has
+ // currently found smallest distance, so we can simply break here.
break;
} else {
currentLengthSquared = newLengthSquared;
indexDelta++;
+ currentClosestUmbraIndex = newUmbraIndex;
}
}
- LOG_ALWAYS_FATAL_IF(currentClosestUmbraIndex == -1, "Can't find a closet umbra vertext at all");
if (indexDelta > 1) {
// For those umbra don't have penumbra, generate new penumbra vertices by interpolation.
@@ -810,6 +813,9 @@
const Vector2& centroid, Vector2* polyToCentroid) {
for (int j = 0; j < polyLength; j++) {
polyToCentroid[j] = poly2d[j] - centroid;
+ // Normalize these vectors such that we can use epsilon comparison after
+ // computing their cross products with another normalized vector.
+ polyToCentroid[j].normalize();
}
float refCrossProduct = 0;
for (int j = 0; j < polyLength; j++) {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 8fc0b8e..645681a 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2201,6 +2201,8 @@
listener = findFocusListener((String)msg.obj);
}
if (listener != null) {
+ Log.d(TAG, "AudioManager dispatching onAudioFocusChange("
+ + msg.what + ") for " + msg.obj);
listener.onAudioFocusChange(msg.what);
}
}
@@ -2270,6 +2272,14 @@
* A successful focus change request.
*/
public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;
+ /**
+ * @hide
+ * A focus change request whose granting is delayed: the request was successful, but the
+ * requester will only be granted audio focus once the condition that prevented immediate
+ * granting has ended.
+ * See {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
+ */
+ public static final int AUDIOFOCUS_REQUEST_DELAYED = 2;
/**
@@ -2291,18 +2301,87 @@
*/
public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) {
int status = AUDIOFOCUS_REQUEST_FAILED;
+
+ try {
+ // status is guaranteed to be either AUDIOFOCUS_REQUEST_FAILED or
+ // AUDIOFOCUS_REQUEST_GRANTED as focus is requested without the
+ // AUDIOFOCUS_FLAG_DELAY_OK flag
+ status = requestAudioFocus(l,
+ new AudioAttributes.Builder()
+ .setInternalLegacyStreamType(streamType).build(),
+ durationHint,
+ 0 /* flags, legacy behavior */);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Audio focus request denied due to ", e);
+ }
+
+ return status;
+ }
+
+ // when adding new flags, add them to AUDIOFOCUS_FLAGS_ALL
+ /** @hide */
+ public static final int AUDIOFOCUS_FLAG_DELAY_OK = 0x1 << 0;
+ /** @hide */
+ public static final int AUDIOFOCUS_FLAGS_ALL = AUDIOFOCUS_FLAG_DELAY_OK;
+
+ /**
+ * @hide
+ * @param l the listener to be notified of audio focus changes. It is not allowed to be null
+ * when the request is flagged with {@link #AUDIOFOCUS_FLAG_DELAY_OK}.
+ * @param requestAttributes non null {@link AudioAttributes} describing the main reason for
+ * requesting audio focus.
+ * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
+ * is temporary, and focus will be abandonned shortly. Examples of transient requests are
+ * for the playback of driving directions, or notifications sounds.
+ * Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
+ * the previous focus owner to keep playing if it ducks its audio output.
+ * Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
+ * that benefits from the system not playing disruptive sounds like notifications, for
+ * usecases such as voice memo recording, or speech recognition.
+ * Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
+ * as the playback of a song or a video.
+ * @param flags use 0 when not using any flags for the request, which behaves like
+ * {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, where either audio
+ * focus is granted immediately, or the grant request fails because the system is in a
+ * state where focus cannot change (e.g. a phone call).
+ * Use {link #AUDIOFOCUS_FLAG_DELAY_OK} if it is ok for the requester to not be granted
+ * audio focus immediately (as indicated by {@link #AUDIOFOCUS_REQUEST_DELAYED}) when
+ * the system is in a state where focus cannot change, but be granted focus later when
+ * this condition ends.
+ * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
+ * or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
+ * The return value is never {@link #AUDIOFOCUS_REQUEST_DELAYED} when focus is requested
+ * without the {@link #AUDIOFOCUS_FLAG_DELAY_OK} flag.
+ * @throws IllegalArgumentException
+ */
+ public int requestAudioFocus(OnAudioFocusChangeListener l,
+ AudioAttributes requestAttributes,
+ int durationHint,
+ int flags) throws IllegalArgumentException {
+ // parameter checking
+ if (requestAttributes == null) {
+ throw new IllegalArgumentException("Illegal null AudioAttributes argument");
+ }
if ((durationHint < AUDIOFOCUS_GAIN) ||
(durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
- Log.e(TAG, "Invalid duration hint, audio focus request denied");
- return status;
+ throw new IllegalArgumentException("Invalid duration hint");
}
+ if (flags != (flags & AUDIOFOCUS_FLAGS_ALL)) {
+ throw new IllegalArgumentException("Illegal flags 0x"
+ + Integer.toHexString(flags).toUpperCase());
+ }
+ if (((flags & AUDIOFOCUS_FLAG_DELAY_OK) == AUDIOFOCUS_FLAG_DELAY_OK) && (l == null)) {
+ throw new IllegalArgumentException(
+ "Illegal null focus listener when flagged as accepting delayed focus grant");
+ }
+
+ int status = AUDIOFOCUS_REQUEST_FAILED;
registerAudioFocusListener(l);
- //TODO protect request by permission check?
IAudioService service = getService();
try {
- status = service.requestAudioFocus(streamType, durationHint, mICallBack,
+ status = service.requestAudioFocus(requestAttributes, durationHint, mICallBack,
mAudioFocusDispatcher, getIdForAudioFocusListener(l),
- mContext.getOpPackageName() /* package name */);
+ mContext.getOpPackageName() /* package name */, flags);
} catch (RemoteException e) {
Log.e(TAG, "Can't call requestAudioFocus() on AudioService due to "+e);
}
@@ -2322,9 +2401,11 @@
public void requestAudioFocusForCall(int streamType, int durationHint) {
IAudioService service = getService();
try {
- service.requestAudioFocus(streamType, durationHint, mICallBack, null,
+ service.requestAudioFocus(new AudioAttributes.Builder()
+ .setInternalLegacyStreamType(streamType).build(),
+ durationHint, mICallBack, null,
MediaFocusControl.IN_VOICE_COMM_FOCUS_ID,
- mContext.getOpPackageName());
+ mContext.getOpPackageName(), 0 /* flags, legacy behavior*/ );
} catch (RemoteException e) {
Log.e(TAG, "Can't call requestAudioFocusForCall() on AudioService due to "+e);
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 29d4930..a80b356 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -5011,10 +5011,10 @@
//==========================================================================================
// Audio Focus
//==========================================================================================
- public int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb,
- IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
- return mMediaFocusControl.requestAudioFocus(mainStreamType, durationHint, cb, fd,
- clientId, callingPackageName);
+ public int requestAudioFocus(AudioAttributes aa, int durationHint, IBinder cb,
+ IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags) {
+ return mMediaFocusControl.requestAudioFocus(aa, durationHint, cb, fd,
+ clientId, callingPackageName, flags);
}
public int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId) {
diff --git a/media/java/android/media/FocusRequester.java b/media/java/android/media/FocusRequester.java
index 9a39994..682d54c 100644
--- a/media/java/android/media/FocusRequester.java
+++ b/media/java/android/media/FocusRequester.java
@@ -45,19 +45,24 @@
*/
private final int mFocusGainRequest;
/**
+ * the flags associated with the gain request that qualify the type of grant (e.g. accepting
+ * delay vs grant must be immediate)
+ */
+ private final int mGrantFlags;
+ /**
* the audio focus loss received my mFocusDispatcher, is AudioManager.AUDIOFOCUS_NONE if
* it never lost focus.
*/
private int mFocusLossReceived;
/**
- * the stream type associated with the focus request
+ * the audio attributes associated with the focus request
*/
- private final int mStreamType;
+ private final AudioAttributes mAttributes;
- FocusRequester(int streamType, int focusRequest,
+ FocusRequester(AudioAttributes aa, int focusRequest, int grantFlags,
IAudioFocusDispatcher afl, IBinder source, String id, AudioFocusDeathHandler hdlr,
String pn, int uid) {
- mStreamType = streamType;
+ mAttributes = aa;
mFocusDispatcher = afl;
mSourceRef = source;
mClientId = id;
@@ -65,6 +70,7 @@
mPackageName = pn;
mCallingUid = uid;
mFocusGainRequest = focusRequest;
+ mGrantFlags = grantFlags;
mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
}
@@ -98,8 +104,12 @@
return mFocusGainRequest;
}
- int getStreamType() {
- return mStreamType;
+ int getGrantFlags() {
+ return mGrantFlags;
+ }
+
+ AudioAttributes getAudioAttributes() {
+ return mAttributes;
}
@@ -139,9 +149,10 @@
+ " -- pack: " + mPackageName
+ " -- client: " + mClientId
+ " -- gain: " + focusGainToString()
+ + " -- grant: " + mGrantFlags
+ " -- loss: " + focusLossToString()
+ " -- uid: " + mCallingUid
- + " -- stream: " + mStreamType);
+ + " -- attr: " + mAttributes);
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 317cc21..47a5291 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -19,6 +19,7 @@
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
+import android.media.AudioAttributes;
import android.media.AudioRoutesInfo;
import android.media.IAudioFocusDispatcher;
import android.media.IAudioRoutesObserver;
@@ -116,8 +117,8 @@
boolean isBluetoothA2dpOn();
- int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb,
- IAudioFocusDispatcher fd, String clientId, String callingPackageName);
+ int requestAudioFocus(in AudioAttributes aa, int durationHint, IBinder cb,
+ IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags);
int abandonAudioFocus(IAudioFocusDispatcher fd, String clientId);
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index c67e397..c495106 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -538,16 +538,54 @@
/**
* Helper function:
* Returns true if the system is in a state where the focus can be reevaluated, false otherwise.
+ * The implementation guarantees that a state where focus cannot be immediately reassigned
+ * implies that an "exclusive" focus owner is at the top of the focus stack.
+ * Modifications to the implementation that break this assumption will cause focus requests to
+ * misbehave when honoring the AudioManager.AUDIOFOCUS_FLAG_DELAY_OK flag.
*/
private boolean canReassignAudioFocus() {
// focus requests are rejected during a phone call or when the phone is ringing
// this is equivalent to IN_VOICE_COMM_FOCUS_ID having the focus
- if (!mFocusStack.isEmpty() && mFocusStack.peek().hasSameClient(IN_VOICE_COMM_FOCUS_ID)) {
+ if (!mFocusStack.isEmpty() && isExclusiveFocusOwner(mFocusStack.peek())) {
return false;
}
return true;
}
+ private boolean isExclusiveFocusOwner(FocusRequester fr) {
+ return fr.hasSameClient(IN_VOICE_COMM_FOCUS_ID);
+ }
+
+ /**
+ * Helper function
+ * Pre-conditions: focus stack is not empty, there is one or more exclusive focus owner
+ * at the top of the focus stack
+ * Push the focus requester onto the audio focus stack at the first position immediately
+ * following the exclusive focus owners.
+ * @return {@link AudioManager#AUDIOFOCUS_REQUEST_GRANTED} or
+ * {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}
+ */
+ private int pushBelowExclusiveFocusOwners(FocusRequester nfr) {
+ int lastExclusiveFocusOwnerIndex = mFocusStack.size();
+ for (int index = mFocusStack.size()-1; index >= 0; index--) {
+ if (isExclusiveFocusOwner(mFocusStack.elementAt(index))) {
+ lastExclusiveFocusOwnerIndex = index;
+ }
+ }
+ if (lastExclusiveFocusOwnerIndex == mFocusStack.size()) {
+ // this should not happen, but handle it and log an error
+ Log.e(TAG, "No exclusive focus owner found in propagateFocusLossFromGain_syncAf()",
+ new Exception());
+ // no exclusive owner, push at top of stack, focus is granted, propagate change
+ propagateFocusLossFromGain_syncAf(nfr.getGainRequest());
+ mFocusStack.push(nfr);
+ return AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+ } else {
+ mFocusStack.insertElementAt(nfr, lastExclusiveFocusOwnerIndex);
+ return AudioManager.AUDIOFOCUS_REQUEST_DELAYED;
+ }
+ }
+
/**
* Inner class to monitor audio focus client deaths, and remove them from the audio focus
* stack if necessary.
@@ -581,10 +619,11 @@
}
}
- /** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int) */
- protected int requestAudioFocus(int mainStreamType, int focusChangeHint, IBinder cb,
- IAudioFocusDispatcher fd, String clientId, String callingPackageName) {
- Log.i(TAG, " AudioFocus requestAudioFocus() from " + clientId);
+ /** @see AudioManager#requestAudioFocus(AudioManager.OnAudioFocusChangeListener, int, int, int) */
+ protected int requestAudioFocus(AudioAttributes aa, int focusChangeHint, IBinder cb,
+ IAudioFocusDispatcher fd, String clientId, String callingPackageName, int flags) {
+ Log.i(TAG, " AudioFocus requestAudioFocus() from " + clientId + " req=" + focusChangeHint +
+ "flags=0x" + Integer.toHexString(flags));
// we need a valid binder callback for clients
if (!cb.pingBinder()) {
Log.e(TAG, " AudioFocus DOA client for requestAudioFocus(), aborting.");
@@ -597,8 +636,16 @@
}
synchronized(mAudioFocusLock) {
+ boolean focusGrantDelayed = false;
if (!canReassignAudioFocus()) {
- return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+ if ((flags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK) == 0) {
+ return AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+ } else {
+ // request has AUDIOFOCUS_FLAG_DELAY_OK: focus can't be
+ // granted right now, so the requester will be inserted in the focus stack
+ // to receive focus later
+ focusGrantDelayed = true;
+ }
}
// handle the potential premature death of the new holder of the focus
@@ -616,7 +663,8 @@
if (!mFocusStack.empty() && mFocusStack.peek().hasSameClient(clientId)) {
// if focus is already owned by this client and the reason for acquiring the focus
// hasn't changed, don't do anything
- if (mFocusStack.peek().getGainRequest() == focusChangeHint) {
+ final FocusRequester fr = mFocusStack.peek();
+ if (fr.getGainRequest() == focusChangeHint && fr.getGrantFlags() == flags) {
// unlink death handler so it can be gc'ed.
// linkToDeath() creates a JNI global reference preventing collection.
cb.unlinkToDeath(afdh, 0);
@@ -624,21 +672,31 @@
}
// the reason for the audio focus request has changed: remove the current top of
// stack and respond as if we had a new focus owner
- FocusRequester fr = mFocusStack.pop();
- fr.release();
+ if (!focusGrantDelayed) {
+ mFocusStack.pop();
+ // the entry that was "popped" is the same that was "peeked" above
+ fr.release();
+ }
}
// focus requester might already be somewhere below in the stack, remove it
removeFocusStackEntry(clientId, false /* signal */);
- // propagate the focus change through the stack
- if (!mFocusStack.empty()) {
- propagateFocusLossFromGain_syncAf(focusChangeHint);
- }
+ final FocusRequester nfr = new FocusRequester(aa, focusChangeHint, flags, fd, cb,
+ clientId, afdh, callingPackageName, Binder.getCallingUid());
+ if (focusGrantDelayed) {
+ // focusGrantDelayed being true implies we can't reassign focus right now
+ // which implies the focus stack is not empty.
+ return pushBelowExclusiveFocusOwners(nfr);
+ } else {
+ // propagate the focus change through the stack
+ if (!mFocusStack.empty()) {
+ propagateFocusLossFromGain_syncAf(focusChangeHint);
+ }
- // push focus requester at the top of the audio focus stack
- mFocusStack.push(new FocusRequester(mainStreamType, focusChangeHint, fd, cb,
- clientId, afdh, callingPackageName, Binder.getCallingUid()));
+ // push focus requester at the top of the audio focus stack
+ mFocusStack.push(nfr);
+ }
}//synchronized(mAudioFocusLock)
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index afa0b6e..91b1018 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -37,6 +37,7 @@
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.provider.Settings;
import android.system.ErrnoException;
import android.system.OsConstants;
import android.util.Log;
@@ -968,11 +969,16 @@
* @throws IllegalStateException if it is called in an invalid state
*/
public void setDataSource(Context context, Uri uri, Map<String, String> headers)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
- String scheme = uri.getScheme();
- if(scheme == null || scheme.equals("file")) {
+ throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ final String scheme = uri.getScheme();
+ if (ContentResolver.SCHEME_FILE.equals(scheme)) {
setDataSource(uri.getPath());
return;
+ } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+ && Settings.AUTHORITY.equals(uri.getAuthority())) {
+ // Redirect ringtones to go directly to underlying provider
+ uri = RingtoneManager.getActualDefaultRingtoneUri(context,
+ RingtoneManager.getDefaultType(uri));
}
AssetFileDescriptor fd = null;
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 62b4a36..b8e850a 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -469,6 +469,63 @@
return result;
}
+static bool readLongValue(int type, MtpDataPacket& packet, jlong& longValue) {
+ switch (type) {
+ case MTP_TYPE_INT8: {
+ int8_t temp;
+ if (!packet.getInt8(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_UINT8: {
+ uint8_t temp;
+ if (!packet.getUInt8(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_INT16: {
+ int16_t temp;
+ if (!packet.getInt16(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_UINT16: {
+ uint16_t temp;
+ if (!packet.getUInt16(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_INT32: {
+ int32_t temp;
+ if (!packet.getInt32(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_UINT32: {
+ uint32_t temp;
+ if (!packet.getUInt32(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_INT64: {
+ int64_t temp;
+ if (!packet.getInt64(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ case MTP_TYPE_UINT64: {
+ uint64_t temp;
+ if (!packet.getUInt64(temp)) return false;
+ longValue = temp;
+ break;
+ }
+ default:
+ ALOGE("unsupported type in readLongValue");
+ return false;
+ }
+ return true;
+}
+
MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) {
@@ -480,49 +537,22 @@
JNIEnv* env = AndroidRuntime::getJNIEnv();
jlong longValue = 0;
jstring stringValue = NULL;
+ MtpResponseCode result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
- switch (type) {
- case MTP_TYPE_INT8:
- longValue = packet.getInt8();
- break;
- case MTP_TYPE_UINT8:
- longValue = packet.getUInt8();
- break;
- case MTP_TYPE_INT16:
- longValue = packet.getInt16();
- break;
- case MTP_TYPE_UINT16:
- longValue = packet.getUInt16();
- break;
- case MTP_TYPE_INT32:
- longValue = packet.getInt32();
- break;
- case MTP_TYPE_UINT32:
- longValue = packet.getUInt32();
- break;
- case MTP_TYPE_INT64:
- longValue = packet.getInt64();
- break;
- case MTP_TYPE_UINT64:
- longValue = packet.getUInt64();
- break;
- case MTP_TYPE_STR:
- {
- MtpStringBuffer buffer;
- packet.getString(buffer);
- stringValue = env->NewStringUTF((const char *)buffer);
- break;
- }
- default:
- ALOGE("unsupported type in setObjectPropertyValue\n");
- return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+ if (type == MTP_TYPE_STR) {
+ MtpStringBuffer buffer;
+ if (!packet.getString(buffer)) goto fail;
+ stringValue = env->NewStringUTF((const char *)buffer);
+ } else {
+ if (!readLongValue(type, packet, longValue)) goto fail;
}
- jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
+ result = env->CallIntMethod(mDatabase, method_setObjectProperty,
(jint)handle, (jint)property, longValue, stringValue);
if (stringValue)
env->DeleteLocalRef(stringValue);
+fail:
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return result;
}
@@ -610,49 +640,22 @@
JNIEnv* env = AndroidRuntime::getJNIEnv();
jlong longValue = 0;
jstring stringValue = NULL;
+ MtpResponseCode result = MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
- switch (type) {
- case MTP_TYPE_INT8:
- longValue = packet.getInt8();
- break;
- case MTP_TYPE_UINT8:
- longValue = packet.getUInt8();
- break;
- case MTP_TYPE_INT16:
- longValue = packet.getInt16();
- break;
- case MTP_TYPE_UINT16:
- longValue = packet.getUInt16();
- break;
- case MTP_TYPE_INT32:
- longValue = packet.getInt32();
- break;
- case MTP_TYPE_UINT32:
- longValue = packet.getUInt32();
- break;
- case MTP_TYPE_INT64:
- longValue = packet.getInt64();
- break;
- case MTP_TYPE_UINT64:
- longValue = packet.getUInt64();
- break;
- case MTP_TYPE_STR:
- {
- MtpStringBuffer buffer;
- packet.getString(buffer);
- stringValue = env->NewStringUTF((const char *)buffer);
- break;
- }
- default:
- ALOGE("unsupported type in setDevicePropertyValue\n");
- return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
+ if (type == MTP_TYPE_STR) {
+ MtpStringBuffer buffer;
+ if (!packet.getString(buffer)) goto fail;
+ stringValue = env->NewStringUTF((const char *)buffer);
+ } else {
+ if (!readLongValue(type, packet, longValue)) goto fail;
}
- jint result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
+ result = env->CallIntMethod(mDatabase, method_setDeviceProperty,
(jint)property, longValue, stringValue);
if (stringValue)
env->DeleteLocalRef(stringValue);
+fail:
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return result;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 34e57bc..6828301 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -37,13 +37,11 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
-import android.content.res.AssetFileDescriptor;
import android.database.AbstractCursor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteQueryBuilder;
-import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -54,7 +52,6 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.TextUtils;
@@ -1228,77 +1225,8 @@
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
-
- /*
- * When a client attempts to openFile the default ringtone or
- * notification setting Uri, we will proxy the call to the current
- * default ringtone's Uri (if it is in the media provider).
- */
- int ringtoneType = RingtoneManager.getDefaultType(uri);
- // Above call returns -1 if the Uri doesn't match a default type
- if (ringtoneType != -1) {
- Context context = getContext();
-
- // Get the current value for the default sound
- Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
-
- if (soundUri != null) {
- // Proxy the openFile call to media provider
- String authority = soundUri.getAuthority();
- if (authority.equals(MediaStore.AUTHORITY)) {
- return context.getContentResolver().openFileDescriptor(soundUri, mode);
- }
- }
- }
-
- return super.openFile(uri, mode);
- }
-
- @Override
- public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
-
- /*
- * When a client attempts to openFile the default ringtone or
- * notification setting Uri, we will proxy the call to the current
- * default ringtone's Uri (if it is in the media provider).
- */
- int ringtoneType = RingtoneManager.getDefaultType(uri);
- // Above call returns -1 if the Uri doesn't match a default type
- if (ringtoneType != -1) {
- Context context = getContext();
-
- // Get the current value for the default sound
- Uri soundUri = RingtoneManager.getActualDefaultRingtoneUri(context, ringtoneType);
-
- if (soundUri != null) {
- // Proxy the openFile call to media provider
- String authority = soundUri.getAuthority();
- if (authority.equals(MediaStore.AUTHORITY)) {
- ParcelFileDescriptor pfd = null;
- try {
- pfd = context.getContentResolver().openFileDescriptor(soundUri, mode);
- return new AssetFileDescriptor(pfd, 0, -1);
- } catch (FileNotFoundException ex) {
- // fall through and open the fallback ringtone below
- }
- }
-
- try {
- return super.openAssetFile(soundUri, mode);
- } catch (FileNotFoundException ex) {
- // Since a non-null Uri was specified, but couldn't be opened,
- // fall back to the built-in ringtone.
- return context.getResources().openRawResourceFd(
- com.android.internal.R.raw.fallbackring);
- }
- }
- // no need to fall through and have openFile() try again, since we
- // already know that will fail.
- throw new FileNotFoundException(); // or return null ?
- }
-
- // Note that this will end up calling openFile() above.
- return super.openAssetFile(uri, mode);
+ throw new FileNotFoundException("Direct file access no longer supported; "
+ + "ringtone playback is available through android.media.Ringtone");
}
/**
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9f9f721..510c84d 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Stel op"</string>
<string name="muted_by" msgid="6147073845094180001">"Gedemp deur <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Skerm is vasgespeld"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Oorsig op dieselfde tyd om te ontspeld."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Dit hou dit in sig totdat jy ontspeld. Raak en hou Oorsig om te ontspeld."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Het dit"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Nee, dankie"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Versteek <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Dit sal verskyn die volgende keer wanneer jy dit in instellings aanskakel."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Versteek"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 800c273..a99e0ed 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"አዋቅር"</string>
<string name="muted_by" msgid="6147073845094180001">"ድምጽ በ<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ተዘግቷል"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"ማያ ገጽ ተሰክቷል"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"ይህ እስከሚነቅሉት ድረስ ድረስ በዕይታ ውስጥ እንዲቆይ ያደርገዋል። ለመንቀል በተመሳሳይ ጊዜ ተመለስን እና አጠቃላይ ዕይታን አንድ ላይ ነክተው ይያዙ።"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ይህ እስከሚነቅሉት ድረስ በዕይታ ውስጥ ያቆየዋል። እንዲነቀል ለማድረግ አጠቃላይ ዕይታን ነካ አድርገው ይያዙት።"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"ገባኝ"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"አይ፣ አመሰግናለሁ"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ይደበቅ?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"በቅንብሮች ውስጥ በሚቀጥለው ጊዜ እንዲበራ በሚያደርጉበት ጊዜ ዳግመኛ ብቅ ይላል።"</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ደብቅ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 380df14..122abbf 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -356,20 +356,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Einrichten"</string>
<string name="muted_by" msgid="6147073845094180001">"Stummgeschaltet durch <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Hiermit wird sie angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Zurück\" und \"Übersicht\" gleichzeitig, um die Fixierung aufzuheben."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Hiermit wird sie angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Übersicht\", um die Fixierung aufzuheben."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Nein danke"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ausblenden?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Sie wird wieder eingeblendet, wenn Sie sie in den Einstellungen erneut aktivieren."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ausblenden"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 456733c..9756ca1 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -356,20 +356,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Ρύθμιση"</string>
<string name="muted_by" msgid="6147073845094180001">"Σίγαση από <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Η οθόνη καρφιτσώθηκε"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Με αυτόν τον τρόπο παραμένει σε προβολή έως ότου την ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα \"Επιστροφή\" και \"Επισκόπηση\" ταυτόχρονα για ξεκαρφίτσωμα."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Με αυτόν τον τρόπο παραμένει σε προβολή έως ότου την ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα \"Επισκόπηση\" για ξεκαρφίτσωμα."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Το κατάλαβα"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Όχι"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Απόκρυψη <xliff:g id="TILE_LABEL">%1$s</xliff:g>;"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Θα εμφανιστεί ξανά την επόμενη φορά που θα το ενεργοποιήσετε στις ρυθμίσεις."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Απόκρυψη"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 24214cf..0fe04fe 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -356,20 +356,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciados por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fija"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Esta función mantiene fija la vista de la pantalla hasta que la desactivas. Mantén presionados los botones Atrás y Recientes al mismo tiempo para anular la fijación."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Esta función mantiene fija la vista de la pantalla hasta que la desactivas. Mantén presionado el botón Recientes para anular la fijación."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"¿Ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Volverá a aparecer la próxima vez que se active en la configuración."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 26f9930..ff47a83e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Configurar"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fijada"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"La pantalla se mantendrá visible hasta que dejes de fijarla. Para ello, mantén pulsados los botones de retroceso e información general."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"La pantalla se mantendrá visible hasta que dejes de fijarla. Para ello, mantén pulsado el botón de información general."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Entendido"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"No, gracias"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"¿Ocultar <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Volverá a aparecer la próxima vez que actives esta opción en Ajustes."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ocultar"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0f99deb..72187ba 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"راهاندازی"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> آن را بیصدا کرد"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"صفحه نمایش پین شد"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، برگشت و نمای کلی را به صورت همزمان لمس کنید و نگهدارید."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، نمای کلی را لمس کنید و نگهدارید."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"متوجه شدم"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"خیر متشکرم"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> مخفی شود؟"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"دفعه بعد که آن را روشن کنید، در تنظیمات نشان داده میشود."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"پنهان کردن"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 2672c54..0de2aa6 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -356,20 +356,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Configura"</string>
<string name="muted_by" msgid="6147073845094180001">"Audio disattivato da <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"La schermata è bloccata"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"La schermata rimane visibile finché la sblocchi. Tocca e tieni premuti contemporaneamente Indietro e Panoramica per sbloccare."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"La schermata rimane visibile finché la sblocchi. Tocca Panoramica e tieni premuto per sbloccare."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"No, grazie"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Nascondere <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Verranno visualizzate di nuovo quando le riattiverai nelle impostazioni."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Nascondi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index 0314ede..34c819c 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Реттеу"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> үнін өшірген"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Экран түйрелді"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Бұл сіз оны босатқанша оны көрсетіп тұрады. Босату үшін «Кері» және «Шолу» түймелерін бір уақытта басып тұрыңыз."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Бұл сіз оны босатқанша оны көрсетіп тұрады. Босату үшін «Шолу» түймесін бір уақытта басып тұрыңыз."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Түсіндім"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Жоқ, рақмет"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> жасыру керек пе?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Ол сіз оны параметрлерде келесі қосқанда қайта пайда болады."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Жасыру"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 9e49a05..0168077 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -69,7 +69,7 @@
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"កំពុងរក្សាទុករូបថតអេក្រង់…"</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"កំពុងរក្សាទុករូបថតអេក្រង់..."</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"រូបថតអេក្រង់កំពុងត្រូវបានរក្សាទុក។"</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_saved_text" msgid="1152839647677558815">"ប៉ះ ដើម្បីមើលរូបថតអេក្រង់របស់អ្នក។"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"មិនអាចចាប់យករូបថតអេក្រង់។"</string>
<string name="screenshot_failed_text" msgid="1260203058661337274">"មិនអាចថតអេក្រង់ដោយសារតែទំហំផ្ទុកមានដែនកំណត់ ឬវាមិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី ឬស្ថាប័នរបស់អ្នក។"</string>
@@ -152,7 +152,7 @@
<string name="accessibility_remove_notification" msgid="3603099514902182350">"សម្អាតការជូនដំណឹង។"</string>
<string name="accessibility_gps_enabled" msgid="3511469499240123019">"បានបើក GPS ។"</string>
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"ទទួល GPS ។"</string>
- <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
+ <string name="accessibility_tty_enabled" msgid="4613200365379426561">"បានបើកម៉ាស៊ីនអង្គុលីលេខ"</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"កម្មវិធីរោទ៍ញ័រ។"</string>
<string name="accessibility_ringer_silent" msgid="9061243307939135383">"កម្មវិធីរោទ៍ស្ងាត់។"</string>
<!-- no translation found for accessibility_casting (6887382141726543668) -->
@@ -234,7 +234,7 @@
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"បញ្ឈរ"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ទេសភាព"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"វិធីសាស្ត្របញ្ចូល"</string>
- <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
+ <string name="quick_settings_location_label" msgid="5011327048748762257">"ទីតាំង"</string>
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"ទីតាំងបានបិទ"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"ឧបករណ៍មេឌៀ"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
@@ -278,11 +278,11 @@
<string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ការភ្ជាប់អេក្រង់"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"មិនអាចចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string>
- <string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string>
+ <string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"កំពុងបញ្ចូលថ្ម"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> រហូតដល់ពេញ"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"មិនកំពុងបញ្ចូលថ្ម"</string>
- <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
+ <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញអាច\nត្រូវបានត្រួតពិនិត្យ"</string>
<string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
<string name="description_direction_up" msgid="7169032478259485180">"រុញឡើងលើដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
<string name="description_direction_left" msgid="7207478719805562165">"រុញទៅឆ្វេងដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 524f0ec..97ca7f2 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -379,20 +379,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Орнотуу"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> тарабынан үнсүздөлдү"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Экран кадалган"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Бул бошотулмайынча көрүнө берет. Бошотуу үчүн, бир убакта Артка жана Карап чыгууну коё бербей басып туруңуз."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Бул бошотулмайынча көрүнө берет. Бошотуу үчүн, Карап чыгууну коё бербей басып туруңуз."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Түшүндүм"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Жок, рахмат"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> жашырылсынбы?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Бул кийинки жолу жөндөөлөрдөн күйгүзүлгөндө кайра көрүнөт."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Жашыруу"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index e7cce7a..fbff4ce 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -275,7 +275,7 @@
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"ຄຳເຕືອນ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"ຂໍ້ມູນແອັບພລິເຄຊັນ"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ການປັກໝຸດໜ້າຈໍ"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ການປັກໝຸດໜ້າຈໍ"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່ສາມາດເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"ສາກເຕັມແລ້ວ."</string>
@@ -312,7 +312,7 @@
<string name="guest_exit_guest" msgid="7187359342030096885">"ລຶບແຂກ"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"ລຶບແຂກບໍ?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"ແອັບຯແລະຂໍ້ມູນທັງໝົດໃນເຊດຊັນນີ້ຈະຖືກລຶບອອກ."</string>
- <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ລຶບ"</string>
+ <string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ລຶບ"</string>
<string name="guest_wipe_session_title" msgid="6419439912885956132">"ຍິນດີຕ້ອນຮັບກັບມາ, ຜູ່ຢ້ຽມຢາມ!"</string>
<string name="guest_wipe_session_message" msgid="8476238178270112811">"ທ່ານຕ້ອງການສືບຕໍ່ເຊດຊັນຂອງທ່ານບໍ່?"</string>
<string name="guest_wipe_session_wipe" msgid="5065558566939858884">"ເລີ່ມຕົ້ນໃຫມ່"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 21c74b0..7b232b8 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Тохируулах"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-с хаасан"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Дэлгэц эхэнд байрлуулагдсан"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Таныг эхэнд нээхийг болиулах хүртэл харагдана. Хүрээд, Back дээр удаан дараад хаахдаа Overview-ийг дар"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Таныг эхэнд нээхийг болиулах хүртэл харагдана. Хаахын тулд хүрээдOverview-ийг дар"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Ойлголоо"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Үгүй"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g>-ийг нуух уу?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Тохируулгын хэсэгт үүнийг асаахад энэ дахин харагдана."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Нуух"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index e397c02..f9c1f58 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Sediakan"</string>
<string name="muted_by" msgid="6147073845094180001">"Diredam oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Skrin telah disemat"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Ini akan memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh dan tahan Kembali dan Gambaran Keseluruhan pada masa yang sama untuk menyahsemat."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ini akan memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh dan tahan Gambaran Keseluruhan untuk menyahsemat."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Faham"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Tidak"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Sembunyikan <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Mesej itu akan terpapar semula pada kali seterusnya anda menghidupkan apl dalam tetapan."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Sembunyikan"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index bc337a4..68d9d5d 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -26,37 +26,37 @@
<string name="status_bar_no_recent_apps" msgid="7374907845131203189">"သင်၏ မကြာမီက မျက်နှာပြင်များ ဒီမှာ ပေါ်လာကြမည်"</string>
<string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"လတ်တလောအပ်ပလီကေးရှင်းများအား ဖယ်ထုတ်မည်"</string>
<plurals name="status_bar_accessibility_recent_apps">
- <item quantity="one" msgid="3969335317929254918">"ခြုံကြည့်မှု ထဲက မျက်နှာပြင် ၁ ခု"</item>
- <item quantity="other" msgid="5523506463832158203">"ခြုံကြည့်မှု ထဲက မျက်နှာပြင် %d ခု"</item>
+ <item quantity="one" msgid="3969335317929254918">"ခြုံကြည့်မှု ထဲက မျက်နှာပြင် ၁ ခု"</item>
+ <item quantity="other" msgid="5523506463832158203">"ခြုံကြည့်မှု ထဲက မျက်နှာပြင် %d ခု"</item>
</plurals>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"အကြောင်းကြားချက်များ မရှိ"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"လက်ရှိအသုံးပြုမှု"</string>
<string name="status_bar_latest_events_title" msgid="6594767438577593172">"အကြောင်းကြားချက်များ။"</string>
<string name="battery_low_title" msgid="6456385927409742437">"ဘက်ထရီ အားနည်းနေ"</string>
<string name="battery_low_percent_format" msgid="2900940511201380775">"<xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်ရှိနေ"</string>
- <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်ရှိနေ။ ဘက်ထရီ ချွေတာမှု ဖွင့်ထား။"</string>
+ <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"<xliff:g id="PERCENTAGE">%s</xliff:g> ကျန်ရှိနေ။ ဘက်ထရီ ချွေတာမှု ဖွင့်ထား။"</string>
<string name="invalid_charger" msgid="4549105996740522523">"လက်ရှိUSBအားသွင်းခြင်း အသုံးမပြုနိုင်ပါ \n ပေးထားသောအားသွင်းကိရိယာကိုသာ အသုံးပြုပါ"</string>
<string name="invalid_charger_title" msgid="3515740382572798460">"USB အားသွင်းမှု မပံ့ပိုးပါ။"</string>
- <string name="invalid_charger_text" msgid="5474997287953892710">"ပေးခဲ့သည့် အားသွင်းစက်ကိုသာ အသုံးပြုပါ"</string>
+ <string name="invalid_charger_text" msgid="5474997287953892710">"ပေးခဲ့သည့် အားသွင်းစက်ကိုသာ အသုံးပြုပါ"</string>
<string name="battery_low_why" msgid="4553600287639198111">"ဆက်တင်များ"</string>
- <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ဘက်ထရီ ချွေတာမှုကို ဖွင့်ရမလား?"</string>
- <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ဖွင့်ရန်"</string>
- <string name="battery_saver_start_action" msgid="5576697451677486320">"ဘက်ထရီ ချွေတာမှုကို ဖွင့်ရန်"</string>
+ <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"ဘက်ထရီ ချွေတာမှုကို ဖွင့်ရမလား?"</string>
+ <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ဖွင့်ရန်"</string>
+ <string name="battery_saver_start_action" msgid="5576697451677486320">"ဘက်ထရီ ချွေတာမှုကို ဖွင့်ရန်"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"အပြင်အဆင်များ"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ဝိုင်ဖိုင်"</string>
<string name="status_bar_settings_airplane" msgid="4879879698500955300">"လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်"</string>
- <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"မျက်နှာပြင်အလိုအလျောက်လှည့်ရန်"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"မျက်နှာပြင်အလိုအလျောက်လှည့်ရန်"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"MUTE"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"သတိပေးချက်များ"</string>
- <string name="bluetooth_tethered" msgid="7094101612161133267">"ဘလူးတုသ်မှတဆင့်ပြန်လည်ချိတ်ဆက်ခြင်း"</string>
- <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ထည့်သွင်းနည်းများ သတ်မှတ်ခြင်း"</string>
+ <string name="bluetooth_tethered" msgid="7094101612161133267">"ဘလူးတုသ်မှတဆင့်ပြန်လည်ချိတ်ဆက်ခြင်း"</string>
+ <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"ထည့်သွင်းနည်းများ သတ်မှတ်ခြင်း"</string>
<string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"ခလုတ်ပါဝင်သော ကီးဘုတ်"</string>
- <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g>အပ်ပလီကေးရှင်းအား USBပစ္စည်းကို ချိတ်ဆက်ရန်ခွင့်ပြုမည်လား"</string>
- <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> အပ်ပလီကေးရှင်းကို USB တွဲဖက်ပစ္စည်းများအား ဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုသည်"</string>
- <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> အားUSBပစ္စည်း ချိတ်ဆက်နေစဥ် ဖွင့်မည်လား"</string>
- <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> အား USBတွဲဖက်ပစ္စည်း ချိတ်ဆက်ထားစဥ် ဖွင့်မည်"</string>
- <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ဒီUSBပစ္စည်းနှင့်ဘယ်အပ်ပလီကေးရှင်းမှ အလုပ်မလုပ်ပါ။ ပိုမိုသိရန် <xliff:g id="URL">%1$s</xliff:g>တွင် လေ့လာပါ"</string>
+ <string name="usb_device_permission_prompt" msgid="834698001271562057">"<xliff:g id="APPLICATION">%1$s</xliff:g>အပ်ပလီကေးရှင်းအား USBပစ္စည်းကို ချိတ်ဆက်ရန်ခွင့်ပြုမည်လား"</string>
+ <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"<xliff:g id="APPLICATION">%1$s</xliff:g> အပ်ပလီကေးရှင်းကို USB တွဲဖက်ပစ္စည်းများအား ဝင်ရောက်ကြည့်ရှုရန်ခွင့်ပြုသည်"</string>
+ <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"<xliff:g id="ACTIVITY">%1$s</xliff:g> အားUSBပစ္စည်း ချိတ်ဆက်နေစဥ် ဖွင့်မည်လား"</string>
+ <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"<xliff:g id="ACTIVITY">%1$s</xliff:g> အား USBတွဲဖက်ပစ္စည်း ချိတ်ဆက်ထားစဥ် ဖွင့်မည်"</string>
+ <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"ဒီUSBပစ္စည်းနှင့်ဘယ်အပ်ပလီကေးရှင်းမှ အလုပ်မလုပ်ပါ။ ပိုမိုသိရန် <xliff:g id="URL">%1$s</xliff:g>တွင် လေ့လာပါ"</string>
<string name="title_usb_accessory" msgid="4966265263465181372">"USBတွဲဖက်ပစ္စည်းများ"</string>
<string name="label_view" msgid="6304565553218192990">"မြင်ကွင်း"</string>
<string name="always_use_device" msgid="1450287437017315906">"ဤUSBပစ္စည်းများအတွက် မူရင်းအတိုင်း အသုံးပြုပါ။"</string>
@@ -64,31 +64,31 @@
<string name="usb_debugging_title" msgid="4513918393387141949">"USB အမှားရှာဖွေပြင်ဆင်ခြင်း ခွင့်ပြုပါမည်လား?"</string>
<string name="usb_debugging_message" msgid="2220143855912376496">"ဒီကွန်ပျူတာရဲ့ RSA key fingerprint ကတော့:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g> ဖြစ်ပါသည်"</string>
<string name="usb_debugging_always" msgid="303335496705863070">"ဒီကွန်ပျူတာမှ အမြဲခွင့်ပြုရန်"</string>
- <string name="compat_mode_on" msgid="6623839244840638213">"ဖန်သားပြင်ပြည့် ချဲ့ခြင်း"</string>
- <string name="compat_mode_off" msgid="4434467572461327898">"ဖန်သားပြင်အပြည့်ဆန့်ခြင်း"</string>
+ <string name="compat_mode_on" msgid="6623839244840638213">"ဖန်သားပြင်ပြည့် ချဲ့ခြင်း"</string>
+ <string name="compat_mode_off" msgid="4434467572461327898">"ဖန်သားပြင်အပြည့်ဆန့်ခြင်း"</string>
<string name="screenshot_saving_ticker" msgid="7403652894056693515">"ဖန်သားပြင်ဓါတ်ပုံသိမ်းစဉ်.."</string>
<string name="screenshot_saving_title" msgid="8242282144535555697">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား သိမ်းဆည်းပါမည်"</string>
<string name="screenshot_saving_text" msgid="2419718443411738818">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား သိမ်းဆည်းပြီးပါပြီ"</string>
<string name="screenshot_saved_title" msgid="6461865960961414961">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား ဖမ်းယူပြီး"</string>
- <string name="screenshot_saved_text" msgid="1152839647677558815">"သင့်ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား ကြည့်ရှုရန် ထိပါ"</string>
+ <string name="screenshot_saved_text" msgid="1152839647677558815">"သင့်ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား ကြည့်ရှုရန် ထိပါ"</string>
<string name="screenshot_failed_title" msgid="705781116746922771">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား မဖမ်းစီးနိုင်ပါ"</string>
- <string name="screenshot_failed_text" msgid="1260203058661337274">"မျက်နှာပြင်လျှပ်တပြက်ပုံကို မရုက်နိုင်ခဲ့ပါ၊ သိုလှောင်မှု နေရာ အကန့်အသတ် ရှိနေ၍ သို့မဟုတ် app သို့မဟုတ် သင်၏ အဖွဲ့အစည်းက ခွင့်မပြု၍ ဖြစ်နိုင်သည်။"</string>
+ <string name="screenshot_failed_text" msgid="1260203058661337274">"မျက်နှာပြင်လျှပ်တပြက်ပုံကို မရုက်နိုင်ခဲ့ပါ၊ သိုလှောင်မှု နေရာ အကန့်အသတ် ရှိနေ၍ သို့မဟုတ် app သို့မဟုတ် သင်၏ အဖွဲ့အစည်းက ခွင့်မပြု၍ ဖြစ်နိုင်သည်။"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ဖိုင်ပြောင်း ရွေးမှုများ"</string>
- <string name="use_mtp_button_title" msgid="4333504413563023626">"မီဒီယာပလေရာအနေဖြင့် တပ်ဆင်ရန် (MTP)"</string>
- <string name="use_ptp_button_title" msgid="7517127540301625751">"ကင်မရာအနေဖြင့် တပ်ဆင်ရန် (PTP)"</string>
+ <string name="use_mtp_button_title" msgid="4333504413563023626">"မီဒီယာပလေရာအနေဖြင့် တပ်ဆင်ရန် (MTP)"</string>
+ <string name="use_ptp_button_title" msgid="7517127540301625751">"ကင်မရာအနေဖြင့် တပ်ဆင်ရန် (PTP)"</string>
<string name="installer_cd_button_title" msgid="2312667578562201583">"Macအတွက်Andriodဖိုင်ပြောင်းအပ်ပလီကေးရှင်းထည့်ခြင်း"</string>
<string name="accessibility_back" msgid="567011538994429120">"နောက်သို့"</string>
<string name="accessibility_home" msgid="8217216074895377641">"ပင်မစာမျက်နှာ"</string>
<string name="accessibility_menu" msgid="316839303324695949">"မီနူး"</string>
- <string name="accessibility_recent" msgid="5208608566793607626">"ခြုံကြည့်မှု။"</string>
+ <string name="accessibility_recent" msgid="5208608566793607626">"ခြုံကြည့်မှု။"</string>
<string name="accessibility_search_light" msgid="1103867596330271848">"ရှာဖွေရန်"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ကင်မရာ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ဖုန်း"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"သော့ဖွင့်ရန်"</string>
- <string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string>
- <string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string>
- <string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
- <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ထည့်သွင်းခြင်းခလုတ်အား ပြောင်းခြင်း"</string>
+ <string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string>
+ <string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string>
+ <string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
+ <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"ထည့်သွင်းခြင်းခလုတ်အား ပြောင်းခြင်း"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"အံ့ဝင်သောချုံ့ချဲ့ခလုတ်"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ဖန်သားပြင်ပေါ်တွင် အသေးမှအကြီးသို့ချဲ့ခြင်း"</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ဘလူးတုသ်ချိတ်ဆက်ထားမှု"</string>
@@ -97,17 +97,17 @@
<string name="accessibility_battery_one_bar" msgid="7774887721891057523">"ဘတ္တရီတစ်ဘား။"</string>
<string name="accessibility_battery_two_bars" msgid="8500650438735009973">"ဘတ္တရီနှစ်ဘား။"</string>
<string name="accessibility_battery_three_bars" msgid="2302983330865040446">"ဘတ္တရီသုံးဘား။"</string>
- <string name="accessibility_battery_full" msgid="8909122401720158582">"ဘတ္တရီအပြည့်။"</string>
+ <string name="accessibility_battery_full" msgid="8909122401720158582">"ဘတ္တရီအပြည့်။"</string>
<string name="accessibility_no_phone" msgid="4894708937052611281">"ဖုန်းလိုင်းမရှိပါ။"</string>
<string name="accessibility_phone_one_bar" msgid="687699278132664115">"ဖုန်းလိုင်းတစ်ဘား။"</string>
<string name="accessibility_phone_two_bars" msgid="8384905382804815201">"ဖုန်းလိုင်းနှစ်ဘား။"</string>
<string name="accessibility_phone_three_bars" msgid="8521904843919971885">"ဖုန်းလိုင်းသုံးဘား။"</string>
- <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ဖုန်းလိုင်းအပြည့်။"</string>
+ <string name="accessibility_phone_signal_full" msgid="6471834868580757898">"ဖုန်းလိုင်းအပြည့်။"</string>
<string name="accessibility_no_data" msgid="4791966295096867555">"ဒေတာမရှိပါ။"</string>
<string name="accessibility_data_one_bar" msgid="1415625833238273628">"ဒေတာတစ်ဘား။"</string>
- <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ဒေတာထုတ်လွှင့်မှု ၂ဘားဖမ်းမိခြင်း။"</string>
+ <string name="accessibility_data_two_bars" msgid="6166018492360432091">"ဒေတာထုတ်လွှင့်မှု ၂ဘားဖမ်းမိခြင်း။"</string>
<string name="accessibility_data_three_bars" msgid="9167670452395038520">"ဒေတာသုံးဘား။"</string>
- <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ဒေတာထုတ်လွှင့်မှုအပြည့်ဖမ်းမိခြင်း"</string>
+ <string name="accessibility_data_signal_full" msgid="2708384608124519369">"ဒေတာထုတ်လွှင့်မှုအပြည့်ဖမ်းမိခြင်း"</string>
<string name="accessibility_wifi_off" msgid="3177380296697933627">"ဝိုင်ဖိုင် မရှိ"</string>
<string name="accessibility_no_wifi" msgid="1425476551827924474">"ဝိုင်ဖိုင် ချိတ်ဆက်ထားမှု မရှိပါ"</string>
<string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"ဝိုင်ဖိုင် ၁ ဘားရှိ"</string>
@@ -127,7 +127,7 @@
<string name="accessibility_one_bar" msgid="1685730113192081895">"တစ်တုံး"</string>
<string name="accessibility_two_bars" msgid="6437363648385206679">"၂ ဘား"</string>
<string name="accessibility_three_bars" msgid="2648241415119396648">"၃ ဘား"</string>
- <string name="accessibility_signal_full" msgid="9122922886519676839">"ဒေတာထုတ်လွှင့်မှုအပြည့်ဖမ်းမိခြင်း"</string>
+ <string name="accessibility_signal_full" msgid="9122922886519676839">"ဒေတာထုတ်လွှင့်မှုအပြည့်ဖမ်းမိခြင်း"</string>
<string name="accessibility_desc_on" msgid="2385254693624345265">"ဖွင့်ထားသည်"</string>
<string name="accessibility_desc_off" msgid="6475508157786853157">"ပိတ်ထားသည်"</string>
<string name="accessibility_desc_connected" msgid="8366256693719499665">"ဆက်သွယ်ထားပြီး"</string>
@@ -144,7 +144,7 @@
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"EDGE"</string>
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ဝိုင်ဖိုင်"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"ဆင်းကဒ်မရှိပါ။"</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ဘလူးတုသ်မှတဆင့်ပြန်လည်ချိတ်ဆက်ခြင်း"</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"ဘလူးတုသ်မှတဆင့်ပြန်လည်ချိတ်ဆက်ခြင်း"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"လေယာဥ်ပျံပေါ်အသုံးပြုသောစနစ်။"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"ဘတ္တရီ <xliff:g id="NUMBER">%d</xliff:g> ရာခိုင်နှုန်း။"</string>
<string name="accessibility_settings_button" msgid="799583911231893380">"စနစ်အပြင်အဆင်များ"</string>
@@ -165,47 +165,47 @@
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"အမြန်လုပ် အပြင်အဆင်"</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"မျက်နှာပြင် သော့ပိတ်ရန်"</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"ဆက်တင်များ"</string>
- <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ခြုံကြည့်မှု။"</string>
+ <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ခြုံကြည့်မှု။"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"သုံးစွဲသူ <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>။"</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ကြိုးမဲ့ ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ကြိုးမဲ့ ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"ကြိုးမဲ့ ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"မိုဘိုင်းလ် <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"ဘက်ထရီ <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"လေယာဉ် မုဒ် ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"လေယာဉ် မုဒ်ကို ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"လေယာဉ် မုဒ်ကို ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"လေယာဉ် မုဒ်ကို ပိတ်ထားလိုက်ပြီ။"</string>
- <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"လေယာဉ် မုဒ်ကို ဖွင့်ထားလိုက်ပြီ။"</string>
+ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"လေယာဉ် မုဒ်ကို ဖွင့်ထားလိုက်ပြီ။"</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"ဘလူးတုသ် ပိတ်ထား."</string>
- <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ဘလူးတုသ် ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"ဘလူးတုသ် ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"ဘလူးတုသ် ချိတ်ဆက်နေ။"</string>
<string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"ဘလူးတုသ် ချိတ်ဆက်ထား။"</string>
<string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"ဘလူးတုသ် ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ဘလူးတုသ် ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"ဘလူးတုသ် ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"တည်နေရာ သတင်းပို့မှု ပိတ်ရန်။"</string>
- <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"တည်နေရာ သတင်းပို့မှု ဖွင့်ရန်။"</string>
+ <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"တည်နေရာ သတင်းပို့မှု ဖွင့်ရန်။"</string>
<string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"တည်နေရာ သတင်းပို့မှု ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"တည်နေရာ သတင်းပို့မှု ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"တည်နေရာ သတင်းပို့မှု ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"နိုးစက်ပေးထားသော အချိန် <xliff:g id="TIME">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_close" msgid="3115847794692516306">"ဘောင်ကွက် ပိတ်ရန်။"</string>
<string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"အချိန် တိုး"</string>
<string name="accessibility_quick_settings_less_time" msgid="2404728746293515623">"အချိန် လျှော့"</string>
<string name="accessibility_quick_settings_flashlight_off" msgid="4936432000069786988">"ဖလက်ရှမီး ပိတ်ထား"</string>
- <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"ဖလက်ရှမီး ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_flashlight_on" msgid="2003479320007841077">"ဖလက်ရှမီး ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_flashlight_changed_off" msgid="3303701786768224304">"ဖလက်ရှမီး ပိတ်ထားသည်။"</string>
- <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ဖလက်ရှမီး ဖွင့်ထားသည်။"</string>
+ <string name="accessibility_quick_settings_flashlight_changed_on" msgid="6531793301533894686">"ဖလက်ရှမီး ဖွင့်ထားသည်။"</string>
<string name="accessibility_quick_settings_color_inversion_changed_off" msgid="4406577213290173911">"အရောင် ပြောင်းပြန်လှန်မှု ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"အရောင် ပြောင်းပြန်လှန်မှု ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="6897462320184911126">"အရောင် ပြောင်းပြန်လှန်မှု ဖွင့်ထား။"</string>
<string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"မိုဘိုင်း ဟော့စပေါ့ ပိတ်ထား။"</string>
- <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"မိုဘိုင်း ဟော့စပေါ့ ဖွင့်ထား။"</string>
+ <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"မိုဘိုင်း ဟော့စပေါ့ ဖွင့်ထား။"</string>
<string name="accessibility_casting_turned_off" msgid="1430668982271976172">"မျက်နှာပြင် ကာစ်တင် လုပ်မှု ရပ်လိုက်ပြီ။"</string>
<string name="accessibility_brightness" msgid="8003681285547803095">"တောက်ပမှုကို ပြရန်"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G-3G ဒေတာ ပိတ်ထား"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G ဒေတာ ပိတ်ထား"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"ဆယ်လူလာ ဒေတာကို ပိတ်ထား"</string>
<string name="data_usage_disabled_dialog_title" msgid="8723412000355709802">"ဒေတာ ပိတ်ထား"</string>
- <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"သင်၏ ကိရိယာသည် သင်က သတ်မှတ်ခဲ့သည့် ကန့်သတ်ချက်ကို ပြည့်မီသွား၍ ပိတ်သွားသည်။ \n\n၎င်းကို ပြန်ပြီး ဖွင့်မှုအတွက် သင်၏ စီမံပေးသူ ထံမှ ငွေတောင်းခံ လာနိုင်ပါသည်။"</string>
- <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"ဒေတာ ဖွင့်ပေးရန်"</string>
+ <string name="data_usage_disabled_dialog" msgid="6468718338038876604">"သင်၏ ကိရိယာသည် သင်က သတ်မှတ်ခဲ့သည့် ကန့်သတ်ချက်ကို ပြည့်မီသွား၍ ပိတ်သွားသည်။ \n\n၎င်းကို ပြန်ပြီး ဖွင့်မှုအတွက် သင်၏ စီမံပေးသူ ထံမှ ငွေတောင်းခံ လာနိုင်ပါသည်။"</string>
+ <string name="data_usage_disabled_dialog_enable" msgid="5538068036107372895">"ဒေတာ ဖွင့်ပေးရန်"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"အင်တာနက်မရှိ"</string>
<string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"ကြိုးမဲ့ဆက်သွယ်မှု"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPSအားရှာဖွေသည်"</string>
@@ -227,13 +227,13 @@
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"ဘလူးတု"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"ဘလူးတု (<xliff:g id="NUMBER">%d</xliff:g> စက်များ)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"ဘလူးတု ပိတ်ထားရန်"</string>
- <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ချိတ်တွဲထားသည့် ကိရိယာများ မရှိ"</string>
+ <string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"ချိတ်တွဲထားသည့် ကိရိယာများ မရှိ"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"အလင်းတောက်ပမှု"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"အော်တို-လည်"</string>
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"လည်မှု သော့ပိတ်ထား"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"ဒေါင်လိုက်"</string>
<string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"ဘေးတိုက်"</string>
- <string name="quick_settings_ime_label" msgid="7073463064369468429">"ထည့်သွင်းရန်နည်းလမ်း"</string>
+ <string name="quick_settings_ime_label" msgid="7073463064369468429">"ထည့်သွင်းရန်နည်းလမ်း"</string>
<string name="quick_settings_location_label" msgid="5011327048748762257">"တည်နေရာ"</string>
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"တည်နေရာပြမှု မရှိ"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"မီဒီယာ စက်ပစ္စည်း"</string>
@@ -252,7 +252,7 @@
<string name="quick_settings_cast_title" msgid="1893629685050355115">"ကာစ်တ် မျက်နှာပြင်"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"ကာစ်တင်"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"အမည်မတပ် ကိရိယာ"</string>
- <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
+ <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
<string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ကိရိယာများ မရှိ"</string>
<string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"အလင်းတောက်ပမှု"</string>
<string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"အလိုအလျောက်"</string>
@@ -269,9 +269,9 @@
<string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"ဆယ်လူလာ ဒေတာ"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"ဒေတာ သုံးစွဲမှု"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"ကျန်ရှိ ဒေတာ"</string>
- <string name="quick_settings_cellular_detail_over_limit" msgid="3242930457130971204">"ကန့်သတ်ချက် ပြည့်မီသွားပြီ - ဒေတာ သုံးစွဲမှု ဆိုင်းငံ့ထားပြီ"</string>
+ <string name="quick_settings_cellular_detail_over_limit" msgid="3242930457130971204">"ကန့်သတ်ချက် ပြည့်မီသွားပြီ - ဒေတာ သုံးစွဲမှု ဆိုင်းငံ့ထားပြီ"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> သုံးထား"</string>
- <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ကန့်သတ်ချက်"</string>
+ <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ကန့်သတ်ချက်"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> သတိပေးချက်"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"သင်၏ မကြာမီက မျက်နှာပြင်များ ဒီမှာ ပေါ်လာကြမည်"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"အပလီကေးရှင်း အင်ဖို"</string>
@@ -280,94 +280,86 @@
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
<string name="expanded_header_battery_charged" msgid="5945855970267657951">"အားသွင်းပြီး"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"အားသွင်းနေ"</string>
- <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ပြည်သည့် အထိ"</string>
+ <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"<xliff:g id="CHARGING_TIME">%s</xliff:g> ပြည်သည့် အထိ"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"အား မသွင်းပါ"</string>
<string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ကွန်ယက်ကို\n စောင့်ကြည့်စစ်ဆေးခံရနိုင်သည်"</string>
<string name="description_target_search" msgid="3091587249776033139">"ရှာဖွေရန်"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် အပေါ်ကို ပွတ်ဆွဲပါ"</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> အတွက် ဖယ်ဘက်ကို ပွတ်ဆွဲပါ"</string>
<string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"ကြားဖြတ်ဝင်မှုများ မရှိခဲ့။ နှိုးစက်ပင် မရှိခဲ့။"</string>
- <string name="zen_no_interruptions" msgid="7970973750143632592">"ကြားဖြတ်ဝင်မှု ခွင့်မပြုရန်"</string>
+ <string name="zen_no_interruptions" msgid="7970973750143632592">"ကြားဖြတ်ဝင်မှု ခွင့်မပြုရန်"</string>
<string name="zen_important_interruptions" msgid="3477041776609757628">"ဦးစားပေး ကြားဖြတ်ဝင်မှုများ သာလျှင်"</string>
<string name="zen_alarm_information_time" msgid="5235772206174372272">"သင်၏ နောက် နှိုးစက်၏ အချိန်မှာ<xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
<string name="zen_alarm_information_day_time" msgid="8422733576255047893">"သင်၏ နောက် နှိုးစက်မှာ <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
<string name="zen_alarm_warning" msgid="6873910860111498041">"သင်သည် သင်၏ <xliff:g id="ALARM_TIME">%s</xliff:g> နှိုးစက်ကို ကြားရမည် မဟုတ်"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
- <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
- <string name="notification_tap_again" msgid="8524949573675922138">"ဖွင့်ရန် ထပ်ပြီး ထိပါ"</string>
- <string name="keyguard_unlock" msgid="8043466894212841998">"သော့ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
+ <string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
+ <string name="notification_tap_again" msgid="8524949573675922138">"ဖွင့်ရန် ထပ်ပြီး ထိပါ"</string>
+ <string name="keyguard_unlock" msgid="8043466894212841998">"သော့ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
<string name="phone_hint" msgid="3101468054914424646">"ဖုန်း အတွက် ညာသို့ ပွတ်ဆွဲပါ"</string>
<string name="camera_hint" msgid="5241441720959174226">"ကင်မရာ အတွက် ဘယ်သို့ ပွတ်ဆွဲပါ"</string>
<string name="interruption_level_none" msgid="3831278883136066646">"မရှိ"</string>
<string name="interruption_level_priority" msgid="6517366750688942030">"ဦးစားပေးမှု"</string>
<string name="interruption_level_all" msgid="1330581184930945764">"အားလုံး"</string>
- <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> အပြည့် အထိ) အားသွင်းနေ"</string>
+ <string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> အပြည့် အထိ) အားသွင်းနေ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
<string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"အသုံးပြုသူကို ပြောင်းရန်၊ လက်ရှိ အသုံးပြုသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ပရိုဖိုင်ကို ပြရန်"</string>
<string name="user_add_user" msgid="5110251524486079492">"သုံးသူ ထပ်ထည့်ရန်"</string>
<string name="user_new_user_name" msgid="426540612051178753">"အသုံးပြုသူ အသစ်"</string>
- <string name="guest_nickname" msgid="8059989128963789678">"ဧည့်သည်"</string>
- <string name="guest_new_guest" msgid="600537543078847803">"ဧည့်သည့်ကို ထည့်ပေးရန်"</string>
- <string name="guest_exit_guest" msgid="7187359342030096885">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
- <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"ဧည့်သည်ကို ဖယ်ထုတ်လိုက်ရမလား?"</string>
- <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"ဒီချိတ်ဆက်မှု ထဲက appများ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
+ <string name="guest_nickname" msgid="8059989128963789678">"ဧည့်သည်"</string>
+ <string name="guest_new_guest" msgid="600537543078847803">"ဧည့်သည့်ကို ထည့်ပေးရန်"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"ဧည့်သည်ကို ဖယ်ထုတ်ရန်"</string>
+ <string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"ဧည့်သည်ကို ဖယ်ထုတ်လိုက်ရမလား?"</string>
+ <string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"ဒီချိတ်ဆက်မှု ထဲက appများ အားလုံး နှင့် ဒေတာကို ဖျက်ပစ်မည်။"</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ဖယ်ထုတ်ပါ"</string>
- <string name="guest_wipe_session_title" msgid="6419439912885956132">"ပြန်လာတာ ကြိုဆိုပါသည်၊ ဧည့်သည်!"</string>
+ <string name="guest_wipe_session_title" msgid="6419439912885956132">"ပြန်လာတာ ကြိုဆိုပါသည်၊ ဧည့်သည်!"</string>
<string name="guest_wipe_session_message" msgid="8476238178270112811">"သင်သည် သင်၏ ချိတ်ဆက်မှုကို ဆက်ပြုလုပ် လိုပါသလား?"</string>
<string name="guest_wipe_session_wipe" msgid="5065558566939858884">"အစမှ ပြန်စပါ"</string>
<string name="guest_wipe_session_dontwipe" msgid="1401113462524894716">"ဟုတ်ကဲ့၊ ဆက်လုပ်ပါ"</string>
- <string name="user_add_user_title" msgid="4553596395824132638">"အသုံးပြုသူ အသစ်ကို ထည့်ရမလား?"</string>
- <string name="user_add_user_message_short" msgid="2161624834066214559">"သင်က အသုံးပြုသူ အသစ် တစ်ဦးကို ထည့်ပေးလိုက်လျှင်၊ ထိုသူသည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်မည်။\n\n အသုံးပြုသူ မည်သူမဆို ကျန်အသုံးပြုသူ အားလုံးတို့အတွက် appများကို မွမ်းမံပေးနိုင်သည်။"</string>
- <string name="battery_saver_notification_title" msgid="237918726750955859">"ဘက်ထရီ ချွေတာသူ ဖွင့်ထား"</string>
- <string name="battery_saver_notification_text" msgid="820318788126672692">"လုပ်ကိုင်မှုကို လျှော့ချလျက် နောက်ခံ ဒေတာကို ကန့်သတ်သည်"</string>
+ <string name="user_add_user_title" msgid="4553596395824132638">"အသုံးပြုသူ အသစ်ကို ထည့်ရမလား?"</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"သင်က အသုံးပြုသူ အသစ် တစ်ဦးကို ထည့်ပေးလိုက်လျှင်၊ ထိုသူသည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်မည်။\n\n အသုံးပြုသူ မည်သူမဆို ကျန်အသုံးပြုသူ အားလုံးတို့အတွက် appများကို မွမ်းမံပေးနိုင်သည်။"</string>
+ <string name="battery_saver_notification_title" msgid="237918726750955859">"ဘက်ထရီ ချွေတာသူ ဖွင့်ထား"</string>
+ <string name="battery_saver_notification_text" msgid="820318788126672692">"လုပ်ကိုင်မှုကို လျှော့ချလျက် နောက်ခံ ဒေတာကို ကန့်သတ်သည်"</string>
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"ဘက်ထရီ ချွေတာမှုကို ပိတ်ထားရန်"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"အကြောင်းအရာများ ဝှက်ထား"</string>
- <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က သင်၏ မျက်နှာပြင် ပေါ်မှာ ပြသထားသည့် အရာတိုင်းကို စတင် ဖမ်းယူမည်။"</string>
+ <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က သင်၏ မျက်နှာပြင် ပေါ်မှာ ပြသထားသည့် အရာတိုင်းကို စတင် ဖမ်းယူမည်။"</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"နောက်ထပ် မပြပါနှင့်"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"အားလုံး ရှင်းလင်းရန်"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="708135716272867002">"အကြောင်းကြားချက်များ မရှိ"</string>
- <string name="device_owned_footer" msgid="3802752663326030053">"ကိရိယာကို စောင့်ကြပ် နိုင်ပါသည်"</string>
- <string name="profile_owned_footer" msgid="8021888108553696069">"ပရိုဖိုင်ကို စောင့်ကြပ်နိုင်သည်"</string>
- <string name="vpn_footer" msgid="2388611096129106812">"ကွန်ရက်ကို ကို စောင့်ကြပ် နိုင်ပါသည်"</string>
+ <string name="device_owned_footer" msgid="3802752663326030053">"ကိရိယာကို စောင့်ကြပ် နိုင်ပါသည်"</string>
+ <string name="profile_owned_footer" msgid="8021888108553696069">"ပရိုဖိုင်ကို စောင့်ကြပ်နိုင်သည်"</string>
+ <string name="vpn_footer" msgid="2388611096129106812">"ကွန်ရက်ကို ကို စောင့်ကြပ် နိုင်ပါသည်"</string>
<string name="monitoring_title_device_owned" msgid="7121079311903859610">"ကိရိယာကို စောင့်ကြပ်ခြင်း"</string>
- <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"ပရိုဖိုင် စောင့်ကြပ်မှု"</string>
+ <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"ပရိုဖိုင် စောင့်ကြပ်မှု"</string>
<string name="monitoring_title" msgid="169206259253048106">"ကွန်ရက်ကို စောင့်ကြပ်ခြင်း"</string>
<string name="disable_vpn" msgid="4435534311510272506">"VPN ကို ပိတ်ထားရန်"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"VPN ကို အဆက်ဖြတ်ရန်"</string>
<string name="monitoring_description_device_owned" msgid="7512371572956715493">"ဤစက်ပစ္စည်းကို စီမံခန့်ခွဲသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင့်အက်ဒ်မင်သည် သင့်စက်ပစ္စည်းနှင့် အီးမေးများ၊ app များ နှင့် လုံခြုံသည့်ဝက်ဘ်ဆိုက် အပါအဝင် ကွန်ရက် လှုပ်ှရားမှုများကို စောင့်ကြည့်နိုင်သည်။\n\nနောက်ထပ်အချက်အလက်များအတွက်၊ သင့်အက်ဒ်မင်ကို ဆက်သွယ်ပါ။"</string>
<string name="monitoring_description_vpn" msgid="7288268682714305659">"သင် \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" ကို VPN စတင်သုံးခွင့်ပေးလိုက်သည်။ \n\n ဤ app သည် သင့်စက်ပစ္စည်းနှင့် အီးမေးများ၊ app များ နှင့် လုံခြုံသည့်ဝက်ဘ်ဆိုက် အပါအဝင် ကွန်ရက် လှုပ်ှရားမှုများကို စောင့်ကြည့်နိုင်သည်။"</string>
<string name="monitoring_description_legacy_vpn" msgid="4740349017929725435">"VPN (\"<xliff:g id="APPLICATION">%1$s</xliff:g>\") ကို သင်ချိတ်ဆက်မိ၏။\n\nသင့် VPN ဝန်ဆောင်မှုပေးသူသည် သင့်စက်ပစ္စည်းနှင့် အီးမေးများ၊ app များ နှင့် လုံခြုံသည့်ဝက်ဘ်ဆိုက် အပါအဝင် ကွန်ရက် လှုပ်ှရားမှုများကို စောင့်ကြည့်နိုင်သည်။"</string>
- <string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"ဒီကိရိယာကို စီမံကွပ်ကဲသူမှာ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူက သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ် နိုင်ပါသည်။ အချက်အလက်များ ပိုပြီး ရယူရန်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\n ထို့အပြင် သင်သည် \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" အား VPN ချိတ်ဆက်မှု စဖွင့်လုပ်ကိုင်ရန် ခွင့်ပြုခဲ့သည်။ ဒီ appကပါ သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ် နိုင်ပါသည်။"</string>
- <string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"ဒီကိရိယာကို စီမံကွပ်ကဲသူမှာ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူက သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ် နိုင်ပါသည်။ အချက်အလက်များ ပိုပြီး ရယူရန်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\nထို့အပြင်၊ သင်သည် VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\") သို့ ချိတ်ဆက်ထားသည်။ သင်၏ VPN ဝန်ဆောင်မှုကို စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုများကို စောင့်ကြပ်နိုင်သေးသည်။"</string>
- <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"ဒီပရိုဖိုင်ကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူသည် သင်၏ ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုများကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ်နိုင်သည်။ \n\n နောက်ထပ် သိလိုလျှင်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။"</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"ဒီကိရိယာကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့် ပရိုဖိုင်ကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူသည် သင်၏ ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုများကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ်နိုင်သည်။\n\nနောက်ထပ် သိလိုလျှင်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။"</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင့် စီမံအုပ်ချုပ်သူက သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်၊ စောင့်ကြပ်နိုင်သည်။ ထပ် သိလိုလျှင်၊ သင့် စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\n သင်သည် \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" အား VPN ချိတ်ဆက်မှု ထူထောင်ခွင့် ပေးခဲ့သည်။ ဒီappကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
- <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင့်စီမံအုပ်ချုပ်သူက သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။ ထပ် သိလိုလျှင်၊ သင့်စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\nသင်သည် VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\") သို့ပါ ချိတ်ထားသည်။ သင်၏ VPN စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"ကိရိယာကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့်ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nသင့်စီမံအုပ်ချုပ်သူသည် သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။\n\nသင်သည် \"<xliff:g id="APPLICATION">%3$s</xliff:g>\"အား VPN ချိတ်ဆက်မှု ထူထောင်ခွင့် ပေးခဲ့သည်။ ဒီappကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
- <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"ဒီကိရိယာ စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့် ပရိုဖိုင် စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n စီမံအုပ်ချုပ်သူသည် သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။\n\nထပ် သိလိုလျှင်၊ သင့်စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။ သင်သည် VPN (\"<xliff:g id="APPLICATION">%3$s</xliff:g>\") သို့ပါ ချိတ်ထားသည်။ သင်၏ VPN စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
- <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"သင်က လက်ဖြင့် သော့မဖွင့်မချင်း ကိရိယာမှာ သော့ပိတ်လျက် ရှိနေမည်"</string>
+ <string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"ဒီကိရိယာကို စီမံကွပ်ကဲသူမှာ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူက သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ် နိုင်ပါသည်။ အချက်အလက်များ ပိုပြီး ရယူရန်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\n ထို့အပြင် သင်သည် \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" အား VPN ချိတ်ဆက်မှု စဖွင့်လုပ်ကိုင်ရန် ခွင့်ပြုခဲ့သည်။ ဒီ appကပါ သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ် နိုင်ပါသည်။"</string>
+ <string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"ဒီကိရိယာကို စီမံကွပ်ကဲသူမှာ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူက သင်၏ ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ် နိုင်ပါသည်။ အချက်အလက်များ ပိုပြီး ရယူရန်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\nထို့အပြင်၊ သင်သည် VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\") သို့ ချိတ်ဆက်ထားသည်။ သင်၏ VPN ဝန်ဆောင်မှုကို စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုများကို စောင့်ကြပ်နိုင်သေးသည်။"</string>
+ <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"ဒီပရိုဖိုင်ကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူသည် သင်၏ ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုများကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ်နိုင်သည်။ \n\n နောက်ထပ် သိလိုလျှင်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။"</string>
+ <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"ဒီကိရိယာကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့် ပရိုဖိုင်ကို စီမံကွပ်ကဲပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nသင်၏ စီမံအုပ်ချုပ်သူသည် သင်၏ ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုများကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို၊ စောင့်ကြပ်နိုင်သည်။\n\nနောက်ထပ် သိလိုလျှင်၊ သင်၏ စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင့် စီမံအုပ်ချုပ်သူက သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှုကို၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်၊ စောင့်ကြပ်နိုင်သည်။ ထပ် သိလိုလျှင်၊ သင့် စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\n သင်သည် \"<xliff:g id="APPLICATION">%2$s</xliff:g>\" အား VPN ချိတ်ဆက်မှု ထူထောင်ခွင့် ပေးခဲ့သည်။ ဒီappကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
+ <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nသင့်စီမံအုပ်ချုပ်သူက သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။ ထပ် သိလိုလျှင်၊ သင့်စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။\n\nသင်သည် VPN (\"<xliff:g id="APPLICATION">%2$s</xliff:g>\") သို့ပါ ချိတ်ထားသည်။ သင်၏ VPN စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
+ <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"ကိရိယာကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့်ပရိုဖိုင်ကို စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nသင့်စီမံအုပ်ချုပ်သူသည် သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။\n\nသင်သည် \"<xliff:g id="APPLICATION">%3$s</xliff:g>\"အား VPN ချိတ်ဆက်မှု ထူထောင်ခွင့် ပေးခဲ့သည်။ ဒီappကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
+ <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"ဒီကိရိယာ စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nသင့် ပရိုဖိုင် စီမံပေးသူ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n စီမံအုပ်ချုပ်သူသည် သင့် ကိရိယာ နှင့် ကွန်ရက် လှုပ်ရှားမှု၊ အီးမေးလ်များ၊ appများ နှင့် လုံခြုံသည့် ဝက်ဘ်ဆိုက်များ အပါအဝင်ကို စောင့်ကြပ်နိုင်သည်။\n\nထပ် သိလိုလျှင်၊ သင့်စီမံအုပ်ချုပ်သူကို ဆက်သွယ်ပါ။ သင်သည် VPN (\"<xliff:g id="APPLICATION">%3$s</xliff:g>\") သို့ပါ ချိတ်ထားသည်။ သင်၏ VPN စီမံပေးသူကပါ ကွန်ရက် လှုပ်ရှားမှုကို စောင့်ကြပ်နိုင်သည်။"</string>
+ <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"သင်က လက်ဖြင့် သော့မဖွင့်မချင်း ကိရိယာမှာ သော့ပိတ်လျက် ရှိနေမည်"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"အကြောင်းကြားချက်များ မြန်မြန်ရရန်"</string>
- <string name="hidden_notifications_text" msgid="2326409389088668981">"မဖွင့်ခင် ၎င်းတို့ကို ကြည့်ပါ"</string>
+ <string name="hidden_notifications_text" msgid="2326409389088668981">"မဖွင့်ခင် ၎င်းတို့ကို ကြည့်ပါ"</string>
<string name="hidden_notifications_cancel" msgid="3690709735122344913">"မလိုအပ်ပါ"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"သတ်မှတ်ရန်"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> အသံပိတ်သည်"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>။ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"မျက်နှာပြင် ပင်ထိုးပြီးပါပြီ"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"သင်ပင်ဖြုတ်သည့် တိုင်အောင် ၎င်းအား မြင်ကွင်းတွင် ထားရှိပါမည်။ ပင်ဖြုတ်ရန် အနောက်နှင့် ခြုံငုံကြည့်ခြင်းကို ဖိ၍ နှိပ်ထားနိုင်သည်။"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"သင်ပင်ဖြုတ်သည့် တိုင်အောင် ၎င်းအား မြင်ကွင်းတွင် ထားရှိပါမည်။ ပင်ဖြုတ်ရန် ခြုံငုံကြည့်ခြင်းကို ဖိ၍ နှိပ်ထားနိုင်သည်။"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"အဲဒါ ရပြီ"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"မလို ကျေးဇူးပဲ"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ဝှက်မည်လား?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"နောက်တစ်ကြိမ်သင် ချိန်ညှိချက်များဖွင့်လျှင် ၎င်းပေါ်လာပါမည်။"</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ဖျောက်ထားမည်"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index a1abb1f..173e866 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"सेटअप गर्नुहोस्"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा मौन गरिएको"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"पर्दा राखेका छ"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन फिर्ता र सिंहावलोकन नै समय मा पकड।"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन गर्न सिंहावलोकन पकड।"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"बुझेँ"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"धन्यवाद पर्दैन"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"लुकाउनुहुन्छ <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"यो तपाईं सेटिङ् मा यो बारी अर्को समय देखापर्नेछ।"</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"लुकाउनुहोस्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index c638e76..691e4a4 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Config."</string>
<string name="muted_by" msgid="6147073845094180001">"Dezactivate de <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Ecranul este fixat"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Ecranul este afișat până anulați fixarea. Apăsați lung pe Înapoi și pe Vizualizare generală simultan pentru a anula fixarea."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ecranul este afișat până anulați fixarea. Apăsați lung pe Vizualizare generală pentru a anula fixarea."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Am înțeles"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Nu, mulțumesc"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ascundeți <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Va reapărea la următoarea activare în setări."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ascundeți"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 80d5f77..3c29ff9 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Sanidi"</string>
<string name="muted_by" msgid="6147073845094180001">"Sauti imezimwa na <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Skrini imebandikwa"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Hii itaendelea kuonyesha hadi ubandue. Gusa na ushikilie Nyuma na Muhtasari kwa wakati mmoja ili ubandue."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Hii itaendelea kuonyesha hadi uibandue. Gusa na ushikilie Muhtasari ili ubandue."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Nimeelewa"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Hapana, asante"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Ungependa kuficha <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Itaonekana tena wakati mwingine utakapoiwasha katika mipangilio."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Ficha"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8318405..5ffbc8b 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"ตั้งค่า"</string>
<string name="muted_by" msgid="6147073845094180001">"ปิดเสียงโดย <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g> <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"ตรึงหน้าจอแล้ว"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"การดำเนินการนี้จะเปิดหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"ภาพรวม\" พร้อมกันค้างไว้เพื่อเลิกตรึง"</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"การดำเนินการนี้จะเปิดหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"รับทราบ"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"ไม่เป็นไร ขอบคุณ"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"ซ่อน <xliff:g id="TILE_LABEL">%1$s</xliff:g> ไหม"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"จะปรากฏอีกครั้งเมื่อคุณเปิดใช้ในการตั้งค่าครั้งถัดไป"</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ซ่อน"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7a7e2f71..04c07e8 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Налаштув."</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає звук"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Екран закріплено"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Закріпить екран, щоб ви могли постійно його бачити, доки не відкріпите. Щоб відкріпити, одночасно натисніть і втримуйте кнопки \"Назад\" і \"Огляд\"."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Закріпить екран, щоб ви могли постійно його бачити, доки не відкріпите. Щоб відкріпити, натисніть і втримуйте кнопку \"Огляд\"."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Зрозуміло"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Ні, дякую"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Сховати <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"З’явиться знову, коли ви ввімкнете його в налаштуваннях."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Сховати"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 11bd4fd..267f737 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Sozlash"</string>
<string name="muted_by" msgid="6147073845094180001">"“<xliff:g id="THIRD_PARTY">%1$s</xliff:g>” tomonidan ovozsiz qilingan"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Ekran qadaldi"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Ekran yechilmaguncha u qadalgan holatda qoladi. Uni yechish uchun “Orqaga” va “Umumiy nazar” tugmalarini bir vaqtda bosing va ushlab turing."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ekran yechilmaguncha u qadalgan holatda qoladi. Uni yechish uchun “Umumiy nazar” tugmasini bosing va ushlab turing."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"OK"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Yo‘q, kerakmas"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> berkitilsinmi?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Keyingi safar sozlamalardan yoqilgan paydo bo‘ladi."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Berkitish"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 50cc5f4..973c20f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -354,20 +354,12 @@
<string name="hidden_notifications_setup" msgid="41079514801976810">"Lungisa"</string>
<string name="muted_by" msgid="6147073845094180001">"Ithuliswe ngu-<xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
- <!-- no translation found for screen_pinning_title (3273740381976175811) -->
- <skip />
- <!-- no translation found for screen_pinning_description (1346522416878235405) -->
- <skip />
- <!-- no translation found for screen_pinning_description_accessible (8518446209564202557) -->
- <skip />
- <!-- no translation found for screen_pinning_positive (3783985798366751226) -->
- <skip />
- <!-- no translation found for screen_pinning_negative (3741602308343880268) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_title (748792586749897883) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_message (2235970126803317374) -->
- <skip />
- <!-- no translation found for quick_settings_reset_confirmation_button (2660339101868367515) -->
- <skip />
+ <string name="screen_pinning_title" msgid="3273740381976175811">"Isikrini siphiniwe"</string>
+ <string name="screen_pinning_description" msgid="1346522416878235405">"Lokhu kukugcina kubukeka uze ususe ukuphina. Thinta futhi ubambe u-Emuva no-Ukubuka konke ngesikhathi esisodwa ukuze ususe ukuphina."</string>
+ <string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Lokhu kukugcina kubukeka uze ususe ukuphina. Thinta futhi ubambe u-Ukubuka konke ukuze ususe ukuphina."</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"Ngiyitholile"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"Cha ngiyabonga"</string>
+ <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Fihla i-<xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string>
+ <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Izovela ngesikhathi esilandelayo uma uvule lesi silungiselelo."</string>
+ <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Fihla"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
new file mode 100644
index 0000000..c0d7b9b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -0,0 +1,260 @@
+/*
+ * 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 com.android.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Handler;
+import android.util.Log;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.doze.DozeHost;
+import com.android.systemui.doze.DozeLog;
+
+/**
+ * Controller which handles all the doze animations of the scrims.
+ */
+public class DozeScrimController {
+ private static final String TAG = "DozeScrimController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+ private final DozeParameters mDozeParameters;
+ private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT;
+ private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN;
+ private final Interpolator mDozeAnimationInterpolator;
+ private final Handler mHandler = new Handler();
+ private final ScrimController mScrimController;
+
+ private boolean mDozing;
+ private DozeHost.PulseCallback mPulseCallback;
+ private Animator mInFrontAnimator;
+ private Animator mBehindAnimator;
+ private float mInFrontTarget;
+ private float mBehindTarget;
+
+ public DozeScrimController(ScrimController scrimController, Context context) {
+ mScrimController = scrimController;
+ mDozeParameters = new DozeParameters(context);
+ mDozeAnimationInterpolator = AnimationUtils.loadInterpolator(context,
+ android.R.interpolator.linear_out_slow_in);
+ }
+
+ public void setDozing(boolean dozing, boolean animate) {
+ if (mDozing == dozing) return;
+ mDozing = dozing;
+ if (mDozing) {
+ abortAnimations();
+ mScrimController.setDozeBehindAlpha(1f);
+ mScrimController.setDozeInFrontAlpha(1f);
+ } else {
+ cancelPulsing();
+ if (animate) {
+ startScrimAnimation(false /* inFront */, 0f /* target */,
+ NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator);
+ startScrimAnimation(true /* inFront */, 0f /* target */,
+ NotificationPanelView.DOZE_ANIMATION_DURATION, mDozeAnimationInterpolator);
+ } else {
+ abortAnimations();
+ mScrimController.setDozeBehindAlpha(0f);
+ mScrimController.setDozeInFrontAlpha(0f);
+ }
+ }
+ }
+
+ /** When dozing, fade screen contents in and out using the front scrim. */
+ public void pulse(@NonNull DozeHost.PulseCallback callback) {
+ if (callback == null) {
+ throw new IllegalArgumentException("callback must not be null");
+ }
+
+ if (!mDozing || mPulseCallback != null) {
+ // Pulse suppressed.
+ callback.onPulseFinished();
+ return;
+ }
+
+ // Begin pulse. Note that it's very important that the pulse finished callback
+ // be invoked when we're done so that the caller can drop the pulse wakelock.
+ mPulseCallback = callback;
+ mHandler.post(mPulseIn);
+ }
+
+ public boolean isPulsing() {
+ return mPulseCallback != null;
+ }
+
+ private void cancelPulsing() {
+ if (DEBUG) Log.d(TAG, "Cancel pulsing");
+
+ if (mPulseCallback != null) {
+ mHandler.removeCallbacks(mPulseIn);
+ mHandler.removeCallbacks(mPulseOut);
+ pulseFinished();
+ }
+ }
+
+ private void pulseStarted() {
+ if (mPulseCallback != null) {
+ mPulseCallback.onPulseStarted();
+ }
+ }
+
+ private void pulseFinished() {
+ if (mPulseCallback != null) {
+ mPulseCallback.onPulseFinished();
+ mPulseCallback = null;
+ }
+ }
+
+ private void abortAnimations() {
+ if (mInFrontAnimator != null) {
+ mInFrontAnimator.cancel();
+ }
+ if (mBehindAnimator != null) {
+ mBehindAnimator.cancel();
+ }
+ }
+
+ private void startScrimAnimation(final boolean inFront, float target, long duration,
+ Interpolator interpolator) {
+ startScrimAnimation(inFront, target, duration, interpolator, 0 /* delay */,
+ null /* endRunnable */);
+ }
+
+ private void startScrimAnimation(final boolean inFront, float target, long duration,
+ Interpolator interpolator, long delay, final Runnable endRunnable) {
+ Animator current = getCurrentAnimator(inFront);
+ if (current != null) {
+ float currentTarget = getCurrentTarget(inFront);
+ if (currentTarget == target) {
+ return;
+ }
+ current.cancel();
+ }
+ ValueAnimator anim = ValueAnimator.ofFloat(getDozeAlpha(inFront), target);
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float value = (float) animation.getAnimatedValue();
+ setDozeAlpha(inFront, value);
+ }
+ });
+ anim.setInterpolator(interpolator);
+ anim.setDuration(duration);
+ anim.setStartDelay(delay);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setCurrentAnimator(inFront, null);
+ if (endRunnable != null) {
+ endRunnable.run();
+ }
+ }
+ });
+ anim.start();
+ setCurrentAnimator(inFront, anim);
+ setCurrentTarget(inFront, target);
+ }
+
+ private float getCurrentTarget(boolean inFront) {
+ return inFront ? mInFrontTarget : mBehindTarget;
+ }
+
+ private void setCurrentTarget(boolean inFront, float target) {
+ if (inFront) {
+ mInFrontTarget = target;
+ } else {
+ mBehindTarget = target;
+ }
+ }
+
+ private Animator getCurrentAnimator(boolean inFront) {
+ return inFront ? mInFrontAnimator : mBehindAnimator;
+ }
+
+ private void setCurrentAnimator(boolean inFront, Animator animator) {
+ if (inFront) {
+ mInFrontAnimator = animator;
+ } else {
+ mBehindAnimator = animator;
+ }
+ }
+
+ private void setDozeAlpha(boolean inFront, float alpha) {
+ if (inFront) {
+ mScrimController.setDozeInFrontAlpha(alpha);
+ } else {
+ mScrimController.setDozeBehindAlpha(alpha);
+ }
+ }
+
+ private float getDozeAlpha(boolean inFront) {
+ return inFront
+ ? mScrimController.getDozeInFrontAlpha()
+ : mScrimController.getDozeBehindAlpha();
+ }
+
+ private final Runnable mPulseIn = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
+ if (!mDozing) return;
+ DozeLog.tracePulseStart();
+ startScrimAnimation(true /* inFront */, 0f, mDozeParameters.getPulseInDuration(),
+ mPulseInInterpolator, mDozeParameters.getPulseInDelay(), mPulseInFinished);
+
+ // Signal that the pulse is ready to turn the screen on and draw.
+ pulseStarted();
+ }
+ };
+
+ private final Runnable mPulseInFinished = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
+ if (!mDozing) return;
+ mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
+ }
+ };
+
+ private final Runnable mPulseOut = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
+ if (!mDozing) return;
+ startScrimAnimation(true /* inFront */, 1f, mDozeParameters.getPulseOutDuration(),
+ mPulseOutInterpolator, 0 /* delay */, mPulseOutFinished);
+ }
+ };
+
+ private final Runnable mPulseOutFinished = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Log.d(TAG, "Pulse out finished");
+ DozeLog.tracePulseFinish();
+
+ // Signal that the pulse is all finished so we can turn the screen off now.
+ pulseFinished();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 9d7d310..de99a82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -23,10 +23,7 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
-import android.util.LayoutDirection;
import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.VelocityTracker;
@@ -63,8 +60,6 @@
private static final float HEADER_RUBBERBAND_FACTOR = 2.05f;
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
- private static final int DOZE_BACKGROUND_COLOR = 0xff000000;
- private static final int TAG_KEY_ANIM = R.id.scrim;
public static final long DOZE_ANIMATION_DURATION = 700;
private KeyguardAffordanceHelper mAfforanceHelper;
@@ -1824,11 +1819,9 @@
if (dozing == mDozing) return;
mDozing = dozing;
if (mDozing) {
- setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/);
mKeyguardStatusBar.setVisibility(View.INVISIBLE);
mKeyguardBottomArea.setVisibility(View.INVISIBLE);
} else {
- setBackgroundColorAlpha(DOZE_BACKGROUND_COLOR, 0, animate);
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardStatusBar.setVisibility(View.VISIBLE);
if (animate) {
@@ -1843,52 +1836,6 @@
return mDozing;
}
- private void setBackgroundColorAlpha(int rgb, int targetAlpha,
- boolean animate) {
- int currentAlpha = getBackgroundAlpha(this);
- if (currentAlpha == targetAlpha) {
- return;
- }
- final int r = Color.red(rgb);
- final int g = Color.green(rgb);
- final int b = Color.blue(rgb);
- Object runningAnim = getTag(TAG_KEY_ANIM);
- if (runningAnim instanceof ValueAnimator) {
- ((ValueAnimator) runningAnim).cancel();
- }
- if (!animate) {
- setBackgroundColor(Color.argb(targetAlpha, r, g, b));
- return;
- }
- ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha);
- anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- int value = (int) animation.getAnimatedValue();
- setBackgroundColor(Color.argb(value, r, g, b));
- }
- });
- anim.setInterpolator(mDozeAnimationInterpolator);
- anim.setDuration(DOZE_ANIMATION_DURATION);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- setTag(TAG_KEY_ANIM, null);
- }
- });
- anim.start();
- setTag(TAG_KEY_ANIM, anim);
- }
-
- private static int getBackgroundAlpha(View view) {
- if (view.getBackground() instanceof ColorDrawable) {
- ColorDrawable drawable = (ColorDrawable) view.getBackground();
- return Color.alpha(drawable.getColor());
- } else {
- return 0;
- }
- }
-
public void setShadeEmpty(boolean shadeEmpty) {
mShadeEmpty = shadeEmpty;
updateEmptyShadeView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 988534b..d94f122 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -414,6 +414,7 @@
private ViewMediatorCallback mKeyguardViewMediatorCallback;
private ScrimController mScrimController;
+ private DozeScrimController mDozeScrimController;
private final Runnable mAutohide = new Runnable() {
@Override
@@ -741,6 +742,7 @@
mScrimController = new ScrimController(scrimBehind, scrimInFront, mScrimSrcModeEnabled);
mScrimController.setBackDropView(mBackdrop);
mStatusBarView.setScrimController(mScrimController);
+ mDozeScrimController = new DozeScrimController(mScrimController, context);
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
mHeader.setActivityStarter(this);
@@ -3677,13 +3679,14 @@
if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
return;
}
- mNotificationPanel.setDozing(mDozing, mScrimController.isPulsing() /*animate*/);
+ mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/);
if (mDozing) {
mStackScroller.setDark(true, false /*animate*/);
} else {
mStackScroller.setDark(false, false /*animate*/);
}
- mScrimController.setDozing(mDozing, mScrimController.isPulsing() /*animate*/);
+ mScrimController.setDozing(mDozing);
+ mDozeScrimController.setDozing(mDozing, mDozeScrimController.isPulsing() /* animate */);
}
public void updateStackScrollerState(boolean goingToFullShade) {
@@ -4060,11 +4063,12 @@
}
public void wakeUpIfDozing(long time, boolean fromTouch) {
- if (mDozing && mScrimController.isPulsing()) {
+ if (mDozing && mDozeScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(time);
if (fromTouch) {
mScreenOnComingFromTouch = true;
+ mNotificationPanel.setTouchDisabled(false);
}
}
}
@@ -4174,7 +4178,7 @@
}
private void handlePulseWhileDozing(@NonNull PulseCallback callback) {
- mScrimController.pulse(callback);
+ mDozeScrimController.pulse(callback);
}
private void handleStopDozing() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 10d6594..d6bd94b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -19,20 +19,15 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
-import android.annotation.NonNull;
import android.content.Context;
import android.graphics.Color;
-import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import com.android.systemui.R;
-import com.android.systemui.doze.DozeHost;
-import com.android.systemui.doze.DozeLog;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.ScrimView;
@@ -41,9 +36,6 @@
* security method gets shown).
*/
public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
- private static final String TAG = "ScrimController";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
public static final long ANIMATION_DURATION = 220;
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
@@ -55,7 +47,6 @@
private final ScrimView mScrimBehind;
private final ScrimView mScrimInFront;
private final UnlockMethodCache mUnlockMethodCache;
- private final DozeParameters mDozeParameters;
private boolean mKeyguardShowing;
private float mFraction;
@@ -70,15 +61,15 @@
private long mAnimationDelay;
private Runnable mOnAnimationFinished;
private boolean mAnimationStarted;
- private boolean mDozing;
- private boolean mPulsingOut;
- private DozeHost.PulseCallback mPulseCallback;
private final Interpolator mInterpolator = new DecelerateInterpolator();
private final Interpolator mLinearOutSlowInInterpolator;
- private final Interpolator mPulseInInterpolator = PhoneStatusBar.ALPHA_OUT;
- private final Interpolator mPulseOutInterpolator = PhoneStatusBar.ALPHA_IN;
private BackDropView mBackDropView;
private boolean mScrimSrcEnabled;
+ private boolean mDozing;
+ private float mDozeInFrontAlpha;
+ private float mDozeBehindAlpha;
+ private float mCurrentInFrontAlpha;
+ private float mCurrentBehindAlpha;
public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront, boolean scrimSrcEnabled) {
mScrimBehind = scrimBehind;
@@ -87,7 +78,6 @@
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in);
- mDozeParameters = new DozeParameters(context);
mScrimSrcEnabled = scrimSrcEnabled;
}
@@ -134,60 +124,27 @@
scheduleUpdate();
}
- public void setDozing(boolean dozing, boolean animate) {
- if (mDozing == dozing) return;
+ public void setDozing(boolean dozing) {
mDozing = dozing;
- if (!mDozing) {
- cancelPulsing();
- mAnimateChange = animate;
- }
scheduleUpdate();
}
- /** When dozing, fade screen contents in and out using the front scrim. */
- public void pulse(@NonNull DozeHost.PulseCallback callback) {
- if (callback == null) {
- throw new IllegalArgumentException("callback must not be null");
- }
-
- if (!mDozing || mPulseCallback != null) {
- // Pulse suppressed.
- callback.onPulseFinished();
- return;
- }
-
- // Begin pulse. Note that it's very important that the pulse finished callback
- // be invoked when we're done so that the caller can drop the pulse wakelock.
- mPulseCallback = callback;
- mScrimInFront.post(mPulseIn);
+ public void setDozeInFrontAlpha(float alpha) {
+ mDozeInFrontAlpha = alpha;
+ updateScrimColor(mScrimInFront);
}
- public boolean isPulsing() {
- return mPulseCallback != null;
+ public void setDozeBehindAlpha(float alpha) {
+ mDozeBehindAlpha = alpha;
+ updateScrimColor(mScrimBehind);
}
- private void cancelPulsing() {
- if (DEBUG) Log.d(TAG, "Cancel pulsing");
-
- if (mPulseCallback != null) {
- mScrimInFront.removeCallbacks(mPulseIn);
- mScrimInFront.removeCallbacks(mPulseOut);
- pulseFinished();
- }
+ public float getDozeBehindAlpha() {
+ return mDozeBehindAlpha;
}
- private void pulseStarted() {
- if (mPulseCallback != null) {
- mPulseCallback.onPulseStarted();
- }
- }
-
- private void pulseFinished() {
- mPulsingOut = false;
- if (mPulseCallback != null) {
- mPulseCallback.onPulseFinished();
- mPulseCallback = null;
- }
+ public float getDozeInFrontAlpha() {
+ return mDozeInFrontAlpha;
}
private void scheduleUpdate() {
@@ -223,12 +180,6 @@
} else if (mBouncerShowing) {
setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
setScrimBehindColor(0f);
- } else if (mDozing && isPulsing() && !mPulsingOut) {
- setScrimInFrontColor(0);
- setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD);
- } else if (mDozing) {
- setScrimInFrontColor(1);
- setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD);
} else {
float fraction = Math.max(0, Math.min(mFraction, 1));
setScrimInFrontColor(0f);
@@ -272,26 +223,46 @@
((ValueAnimator) runningAnim).cancel();
scrim.setTag(TAG_KEY_ANIM, null);
}
- int color = Color.argb((int) (alpha * 255), 0, 0, 0);
if (mAnimateChange) {
- startScrimAnimation(scrim, color);
+ startScrimAnimation(scrim, alpha);
} else {
- scrim.setScrimColor(color);
+ setCurrentScrimAlpha(scrim, alpha);
+ updateScrimColor(scrim);
}
}
- private void startScrimAnimation(final ScrimView scrim, int targetColor) {
- int current = Color.alpha(scrim.getScrimColor());
- int target = Color.alpha(targetColor);
- if (current == target) {
- return;
+ private float getDozeAlpha(View scrim) {
+ return scrim == mScrimBehind ? mDozeBehindAlpha : mDozeInFrontAlpha;
+ }
+
+ private float getCurrentScrimAlpha(View scrim) {
+ return scrim == mScrimBehind ? mCurrentBehindAlpha : mCurrentInFrontAlpha;
+ }
+
+ private void setCurrentScrimAlpha(View scrim, float alpha) {
+ if (scrim == mScrimBehind) {
+ mCurrentBehindAlpha = alpha;
+ } else {
+ mCurrentInFrontAlpha = alpha;
}
- ValueAnimator anim = ValueAnimator.ofInt(current, target);
+ }
+
+ private void updateScrimColor(ScrimView scrim) {
+ float alpha1 = getCurrentScrimAlpha(scrim);
+ float alpha2 = getDozeAlpha(scrim);
+ float alpha = 1 - (1 - alpha1) * (1 - alpha2);
+ scrim.setScrimColor(Color.argb((int) (alpha * 255), 0, 0, 0));
+ }
+
+ private void startScrimAnimation(final ScrimView scrim, float target) {
+ float current = getCurrentScrimAlpha(scrim);
+ ValueAnimator anim = ValueAnimator.ofFloat(current, target);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
- int value = (int) animation.getAnimatedValue();
- scrim.setScrimColor(Color.argb(value, 0, 0, 0));
+ float alpha = (float) animation.getAnimatedValue();
+ setCurrentScrimAlpha(scrim, alpha);
+ updateScrimColor(scrim);
}
});
anim.setInterpolator(getInterpolator());
@@ -313,15 +284,7 @@
}
private Interpolator getInterpolator() {
- if (mAnimateKeyguardFadingOut) {
- return mLinearOutSlowInInterpolator;
- } else if (isPulsing() && !mPulsingOut) {
- return mPulseInInterpolator;
- } else if (isPulsing()) {
- return mPulseOutInterpolator;
- } else {
- return mInterpolator;
- }
+ return mAnimateKeyguardFadingOut ? mLinearOutSlowInInterpolator : mInterpolator;
}
@Override
@@ -342,56 +305,6 @@
return true;
}
- private final Runnable mPulseIn = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
- if (!mDozing) return;
- DozeLog.tracePulseStart();
- mDurationOverride = mDozeParameters.getPulseInDuration();
- mAnimationDelay = mDozeParameters.getPulseInDelay();
- mAnimateChange = true;
- mOnAnimationFinished = mPulseInFinished;
- scheduleUpdate();
-
- // Signal that the pulse is ready to turn the screen on and draw.
- pulseStarted();
- }
- };
-
- private final Runnable mPulseInFinished = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
- if (!mDozing) return;
- mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
- }
- };
-
- private final Runnable mPulseOut = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
- if (!mDozing) return;
- mDurationOverride = mDozeParameters.getPulseOutDuration();
- mAnimateChange = true;
- mOnAnimationFinished = mPulseOutFinished;
- mPulsingOut = true;
- scheduleUpdate();
- }
- };
-
- private final Runnable mPulseOutFinished = new Runnable() {
- @Override
- public void run() {
- if (DEBUG) Log.d(TAG, "Pulse out finished");
- DozeLog.tracePulseFinish();
-
- // Signal that the pulse is all finished so we can turn the screen off now.
- pulseFinished();
- }
- };
-
public void setBackDropView(BackDropView backDropView) {
mBackDropView = backDropView;
mBackDropView.setOnVisibilityChangedRunnable(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 9cfd26b..0caded5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -177,12 +177,21 @@
* Construct this controller object and register for updates.
*/
public NetworkControllerImpl(Context context) {
+ this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
+ (WifiManager) context.getSystemService(Context.WIFI_SERVICE));
+ registerListeners();
+ }
+
+ @VisibleForTesting
+ NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
+ TelephonyManager telephonyManager, WifiManager wifiManager) {
mContext = context;
final Resources res = context.getResources();
- mConnectivityManager =
- (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- mHasMobileDataFeature = getCM().isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+ mConnectivityManager = connectivityManager;
+ mHasMobileDataFeature =
+ mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
mShowPhoneRSSIForData = res.getBoolean(R.bool.config_showPhoneRSSIForData);
mShowAtLeastThreeGees = res.getBoolean(R.bool.config_showMin3G);
@@ -203,7 +212,7 @@
mNetworkName = mNetworkNameDefault;
// wifi
- mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ mWifiManager = wifiManager;
Handler handler = new WifiHandler();
mWifiChannel = new AsyncChannel();
Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
@@ -211,8 +220,6 @@
mWifiChannel.connect(mContext, handler, wifiMessenger);
}
- registerListeners();
-
// AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
updateAirplaneMode();
@@ -227,13 +234,7 @@
});
}
- @VisibleForTesting
- protected ConnectivityManager getCM() {
- return mConnectivityManager;
- }
-
- @VisibleForTesting
- protected void registerListeners() {
+ private void registerListeners() {
mPhone.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
@@ -1085,7 +1086,7 @@
Log.d(TAG, "updateConnectivity: intent=" + intent);
}
- final NetworkInfo info = getCM().getActiveNetworkInfo();
+ final NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
// Are we connected at all, by any interface?
mConnected = info != null && info.isConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index b325653..ed6ddd2 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -244,7 +244,7 @@
}
private void setExitCondition(Condition exitCondition) {
- if (sameConditionId(mExitCondition, exitCondition)) return;
+ if (Objects.equals(mExitCondition, exitCondition)) return;
mExitCondition = exitCondition;
refreshExitConditionText();
updateWidgets();
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 262e071..8b87522 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -19,7 +19,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
LOCAL_PACKAGE_NAME := SystemUITests
LOCAL_INSTRUMENTATION_FOR := SystemUI
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index c0aa31d..97605ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -4,16 +4,19 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
import android.test.AndroidTestCase;
import android.util.Log;
+import com.android.internal.telephony.cdma.EriInfo;
+import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
import org.mockito.ArgumentCaptor;
@@ -24,13 +27,23 @@
public class NetworkControllerBaseTest extends AndroidTestCase {
private static final String TAG = "NetworkControllerBaseTest";
+ protected static final int DEFAULT_LEVEL = 2;
+ protected static final int DEFAULT_SIGNAL_STRENGTH =
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL];
+ protected static final int DEFAULT_QS_SIGNAL_STRENGTH =
+ TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL];
+ protected static final int DEFAULT_ICON = TelephonyIcons.ICON_3G;
+ protected static final int DEFAULT_QS_ICON = TelephonyIcons.QS_ICON_3G;
protected NetworkControllerImpl mNetworkController;
protected PhoneStateListener mPhoneStateListener;
protected SignalCluster mSignalCluster;
+ protected NetworkSignalChangedCallback mNetworkSignalChangedCallback;
private SignalStrength mSignalStrength;
private ServiceState mServiceState;
- private ConnectivityManager mMockCM;
+ protected ConnectivityManager mMockCm;
+ protected WifiManager mMockWm;
+ protected TelephonyManager mMockTm;
@Override
protected void setUp() throws Exception {
@@ -39,17 +52,24 @@
System.setProperty("dexmaker.dexcache", mContext.getCacheDir().getPath());
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
- mMockCM = mock(ConnectivityManager.class);
- when(mMockCM.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
+ mMockWm = mock(WifiManager.class);
+ mMockTm = mock(TelephonyManager.class);
+ mMockCm = mock(ConnectivityManager.class);
+ when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(true);
- // TODO: Move away from fake, use spy if possible after MSIM refactor.
- mNetworkController = new FakeNetworkControllerImpl(mContext);
-
- mPhoneStateListener = mNetworkController.mPhoneStateListener;
mSignalStrength = mock(SignalStrength.class);
mServiceState = mock(ServiceState.class);
mSignalCluster = mock(SignalCluster.class);
+ mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class);
+
+ mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm);
+ setupNetworkController();
+ }
+
+ protected void setupNetworkController() {
+ mPhoneStateListener = mNetworkController.mPhoneStateListener;
mNetworkController.addSignalCluster(mSignalCluster);
+ mNetworkController.addNetworkSignalChangedCallback(mNetworkSignalChangedCallback);
}
@Override
@@ -62,13 +82,24 @@
super.tearDown();
}
+ // 2 Bars 3G GSM.
+ public void setupDefaultSignal() {
+ setIsGsm(true);
+ setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+ setGsmRoaming(false);
+ setLevel(DEFAULT_LEVEL);
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_UMTS);
+ setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+ }
+
public void setConnectivity(int inetCondition, int networkType, boolean isConnected) {
Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
NetworkInfo networkInfo = mock(NetworkInfo.class);
when(networkInfo.isConnected()).thenReturn(isConnected);
when(networkInfo.getType()).thenReturn(networkType);
when(networkInfo.getTypeName()).thenReturn("");
- when(mMockCM.getActiveNetworkInfo()).thenReturn(networkInfo);
+ when(mMockCm.getActiveNetworkInfo()).thenReturn(networkInfo);
i.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, inetCondition);
mNetworkController.onReceive(mContext, i);
@@ -79,11 +110,24 @@
updateServiceState();
}
+ public void setCdmaRoaming(boolean isRoaming) {
+ when(mServiceState.getCdmaEriIconIndex()).thenReturn(isRoaming ?
+ EriInfo.ROAMING_INDICATOR_ON : EriInfo.ROAMING_INDICATOR_OFF);
+ when(mServiceState.getCdmaEriIconMode()).thenReturn(isRoaming ?
+ EriInfo.ROAMING_ICON_MODE_NORMAL : -1);
+ updateServiceState();
+ }
+
public void setVoiceRegState(int voiceRegState) {
when(mServiceState.getVoiceRegState()).thenReturn(voiceRegState);
updateServiceState();
}
+ public void setDataRegState(int dataRegState) {
+ when(mServiceState.getDataRegState()).thenReturn(dataRegState);
+ updateServiceState();
+ }
+
public void setIsEmergencyOnly(boolean isEmergency) {
when(mServiceState.isEmergencyOnly()).thenReturn(isEmergency);
updateServiceState();
@@ -131,32 +175,49 @@
mPhoneStateListener.onDataActivity(dataActivity);
}
- protected void verifyLastMobileDataIndicators(boolean visible, int icon) {
+ protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon,
+ boolean dataIn, boolean dataOut, boolean noSim) {
ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> noSimArg = ArgumentCaptor.forClass(Boolean.class);
+
+ Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce())
+ .onMobileDataSignalChanged(visibleArg.capture(), iconArg.capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ typeIconArg.capture(),
+ dataInArg.capture(),
+ dataOutArg.capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ noSimArg.capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture());
+ assertEquals("Visibility in, quick settings", visible, (boolean) visibleArg.getValue());
+ assertEquals("Signal icon in, quick settings", icon, (int) iconArg.getValue());
+ assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue());
+ assertEquals("Data direction in, in quick settings", dataIn,
+ (boolean) dataInArg.getValue());
+ assertEquals("Data direction out, in quick settings", dataOut,
+ (boolean) dataOutArg.getValue());
+ assertEquals("Sim state in quick settings", noSim, (boolean) noSimArg.getValue());
+ }
+
+ protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon) {
+ ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
// TODO: Verify all fields.
Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setMobileDataIndicators(
- visibleArg.capture(), iconArg.capture(),
- ArgumentCaptor.forClass(Integer.class).capture(),
+ visibleArg.capture(), iconArg.capture(), typeIconArg.capture(),
ArgumentCaptor.forClass(String.class).capture(),
ArgumentCaptor.forClass(String.class).capture(),
ArgumentCaptor.forClass(Boolean.class).capture());
- assertEquals(icon, (int) iconArg.getValue());
- assertEquals(visible, (boolean) visibleArg.getValue());
- }
-
- private class FakeNetworkControllerImpl extends NetworkControllerImpl {
- public FakeNetworkControllerImpl(Context context) {
- super(context);
- }
-
- @Override
- public ConnectivityManager getCM() {
- return mMockCM;
- }
-
- public void registerListeners() {};
+ assertEquals("Signal icon in status bar", icon, (int) iconArg.getValue());
+ assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
+ assertEquals("Visibility in status bar", visible, (boolean) visibleArg.getValue());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
new file mode 100644
index 0000000..146e76d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -0,0 +1,99 @@
+package com.android.systemui.statusbar.policy;
+
+import android.telephony.TelephonyManager;
+
+// WARNING: Many of these tests may fail with config showMin3G.
+// TODO: Maybe fix the above.
+public class NetworkControllerDataTest extends NetworkControllerBaseTest {
+
+ public void test3gDataIcon() {
+ setupDefaultSignal();
+
+ verifyDataIndicators(TelephonyIcons.DATA_3G[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_3G[1]);
+ }
+
+ public void testRoamingDataIcon() {
+ setupDefaultSignal();
+ setGsmRoaming(true);
+
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
+ TelephonyIcons.ROAMING_ICON);
+ verifyLastQsMobileDataIndicators(true,
+ TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][DEFAULT_LEVEL],
+ TelephonyIcons.QS_DATA_R[1], false, false, false);
+ }
+
+ public void test2gDataIcon() {
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_GSM);
+
+ verifyDataIndicators(TelephonyIcons.DATA_G[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_G[1]);
+ }
+
+ public void testCdmaDataIcon() {
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_CDMA);
+
+ verifyDataIndicators(TelephonyIcons.DATA_1X[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_1X[1]);
+ }
+
+ public void testEdgeDataIcon() {
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_EDGE);
+
+ verifyDataIndicators(TelephonyIcons.DATA_E[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_E[1]);
+ }
+
+ public void testLteDataIcon() {
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_LTE);
+
+ // WARNING: May fail depending on config.
+ verifyDataIndicators(TelephonyIcons.DATA_LTE[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_LTE[1]);
+ }
+
+ public void testHspaDataIcon() {
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_HSPA);
+
+ // WARNING: May fail depending on config.
+ verifyDataIndicators(TelephonyIcons.DATA_H[1][0 /* No direction */],
+ TelephonyIcons.QS_DATA_H[1]);
+ }
+
+ public void testDataActivity() {
+ setupDefaultSignal();
+
+ testDataActivity(TelephonyManager.DATA_ACTIVITY_NONE, false, false);
+ testDataActivity(TelephonyManager.DATA_ACTIVITY_IN, true, false);
+ testDataActivity(TelephonyManager.DATA_ACTIVITY_OUT, false, true);
+ testDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT, true, true);
+ }
+
+ private void testDataActivity(int direction, boolean in, boolean out) {
+ updateDataActivity(direction);
+
+ verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, DEFAULT_ICON);
+ verifyLastQsMobileDataIndicators(true, DEFAULT_QS_SIGNAL_STRENGTH,
+ DEFAULT_QS_ICON, in, out, false);
+
+ }
+
+ private void verifyDataIndicators(int dataIcon, int qsDataIcon) {
+ verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, dataIcon);
+ verifyLastQsMobileDataIndicators(true, DEFAULT_QS_SIGNAL_STRENGTH, qsDataIcon, false,
+ false, false);
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index fc2b1aa..ed76ae5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -5,33 +5,122 @@
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
+import com.android.systemui.R;
+
+import org.mockito.Mockito;
+
public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
- public void testSignalStrength() {
- int testStrength = SignalStrength.SIGNAL_STRENGTH_MODERATE;
- setIsGsm(true);
- setVoiceRegState(ServiceState.STATE_IN_SERVICE);
- setGsmRoaming(false);
- setLevel(testStrength);
- updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
- TelephonyManager.NETWORK_TYPE_UMTS);
- setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+ public void testNoIconWithoutMobile() {
+ // Turn off mobile network support.
+ Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+ // Create a new NetworkController as this is currently handled in constructor.
+ mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm);
+ setupNetworkController();
- verifyLastMobileDataIndicators(true,
- TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength]);
+ verifyLastMobileDataIndicators(false, 0, 0);
+ }
+
+ public void testSignalStrength() {
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setLevel(testStrength);
+
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+ DEFAULT_ICON);
+
+ // Verify low inet number indexing.
+ setConnectivity(10, ConnectivityManager.TYPE_MOBILE, true);
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[0][testStrength], 0);
+ }
+ }
+
+ public void testCdmaSignalStrength() {
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setCdma();
+ setLevel(testStrength);
+
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+ TelephonyIcons.DATA_1X[1][0 /* No direction */]);
+ }
}
public void testSignalRoaming() {
- int testStrength = SignalStrength.SIGNAL_STRENGTH_MODERATE;
- setIsGsm(true);
- setVoiceRegState(ServiceState.STATE_IN_SERVICE);
- setGsmRoaming(true);
- setLevel(testStrength);
- updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
- TelephonyManager.NETWORK_TYPE_UMTS);
- setConnectivity(100, ConnectivityManager.TYPE_MOBILE, true);
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setGsmRoaming(true);
+ setLevel(testStrength);
- verifyLastMobileDataIndicators(true,
- TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength]);
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
+ TelephonyIcons.ROAMING_ICON);
+ }
+ }
+
+ public void testCdmaSignalRoaming() {
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setCdma();
+ setCdmaRoaming(true);
+ setLevel(testStrength);
+
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][testStrength],
+ TelephonyIcons.ROAMING_ICON);
+ }
+ }
+
+ public void testQsSignalStrength() {
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setLevel(testStrength);
+
+ verifyLastQsMobileDataIndicators(true,
+ TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+ DEFAULT_QS_ICON, false, false, false);
+ }
+ }
+
+ public void testCdmaQsSignalStrength() {
+ for (int testStrength = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ testStrength <= SignalStrength.SIGNAL_STRENGTH_GREAT; testStrength++) {
+ setupDefaultSignal();
+ setCdma();
+ setLevel(testStrength);
+
+ verifyLastQsMobileDataIndicators(true,
+ TelephonyIcons.QS_TELEPHONY_SIGNAL_STRENGTH[1][testStrength],
+ TelephonyIcons.QS_ICON_1X, false, false, false);
+ }
+ }
+
+ public void testNoRoamingWithoutSignal() {
+ setupDefaultSignal();
+ setCdma();
+ setCdmaRoaming(true);
+ setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE);
+ setDataRegState(ServiceState.STATE_OUT_OF_SERVICE);
+
+ // This exposes the bug in b/18034542, and should be switched to the commented out
+ // verification below (and pass), once the bug is fixed.
+ verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null,
+ TelephonyIcons.ROAMING_ICON);
+ //verifyLastMobileDataIndicators(true, R.drawable.stat_sys_signal_null, 0 /* No Icon */);
+ }
+
+ private void setCdma() {
+ setIsGsm(false);
+ updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.NETWORK_TYPE_CDMA);
+ setCdmaRoaming(false);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
new file mode 100644
index 0000000..4ffdff2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -0,0 +1,201 @@
+package com.android.systemui.statusbar.policy;
+
+import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+
+import com.android.systemui.R;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
+ // These match the constants in WifiManager and need to be kept up to date.
+ private static final int MIN_RSSI = -100;
+ private static final int MAX_RSSI = -55;
+
+ // TODO: Move this into WifiIcons, remove all R.drawable from NetworkControllerImpl.
+ private static final int NULL_SIGNAL = R.drawable.stat_sys_wifi_signal_null;
+ private static final int QS_NO_NET = R.drawable.ic_qs_wifi_no_network;
+
+ public void testWifiIcon() {
+ String testSsid = "Test SSID";
+ setWifiEnabled(true);
+ verifyLastWifiIcon(false, NULL_SIGNAL);
+
+ setWifiState(true, testSsid);
+ verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
+
+ for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
+ setWifiLevel(testLevel);
+
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+ setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][testLevel]);
+ }
+ }
+
+ public void testQsWifiIcon() {
+ String testSsid = "Test SSID";
+
+ setWifiEnabled(false);
+ verifyLastQsWifiIcon(false, false, 0, null);
+
+ setWifiEnabled(true);
+ verifyLastQsWifiIcon(true, false, QS_NO_NET, null);
+
+ setWifiState(true, testSsid);
+ for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
+ setWifiLevel(testLevel);
+
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel],
+ testSsid);
+ setConnectivity(10, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastQsWifiIcon(true, true, WifiIcons.QS_WIFI_SIGNAL_STRENGTH[0][testLevel],
+ testSsid);
+ }
+ }
+
+ public void testQsDataDirection() {
+ // Setup normal connection
+ String testSsid = "Test SSID";
+ int testLevel = 2;
+ setWifiEnabled(true);
+ setWifiState(true, testSsid);
+ setWifiLevel(testLevel);
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastQsWifiIcon(true, true,
+ WifiIcons.QS_WIFI_SIGNAL_STRENGTH[1][testLevel], testSsid);
+
+ setWifiActivity(WifiManager.DATA_ACTIVITY_NONE);
+ verifyLastQsDataDirection(false, false);
+ setWifiActivity(WifiManager.DATA_ACTIVITY_IN);
+ verifyLastQsDataDirection(true, false);
+ setWifiActivity(WifiManager.DATA_ACTIVITY_OUT);
+ verifyLastQsDataDirection(false, true);
+ setWifiActivity(WifiManager.DATA_ACTIVITY_INOUT);
+ verifyLastQsDataDirection(true, true);
+ }
+
+ public void testNoDataIconDuringWifi() {
+ // Setup normal connection
+ String testSsid = "Test SSID";
+ int testLevel = 2;
+ setWifiEnabled(true);
+ setWifiState(true, testSsid);
+ setWifiLevel(testLevel);
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+ setupDefaultSignal();
+ // Still be on wifi though.
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, 0 /* No icon */);
+ }
+
+ public void testRoamingIconDuringWifi() {
+ // Setup normal connection
+ String testSsid = "Test SSID";
+ int testLevel = 2;
+ setWifiEnabled(true);
+ setWifiState(true, testSsid);
+ setWifiLevel(testLevel);
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[1][testLevel]);
+
+ setupDefaultSignal();
+ setGsmRoaming(true);
+ // Still be on wifi though.
+ setConnectivity(100, ConnectivityManager.TYPE_WIFI, true);
+ verifyLastMobileDataIndicators(true,
+ TelephonyIcons.TELEPHONY_SIGNAL_STRENGTH_ROAMING[1][DEFAULT_LEVEL],
+ TelephonyIcons.ROAMING_ICON);
+ }
+
+ protected void setWifiActivity(int activity) {
+ // TODO: Not this, because this variable probably isn't sticking around.
+ mNetworkController.mWifiActivity = activity;
+ mNetworkController.refreshViews();
+ }
+
+ protected void setWifiLevel(int level) {
+ float amountPerLevel = (MAX_RSSI - MIN_RSSI) / (WifiIcons.WIFI_LEVEL_COUNT - 1);
+ int rssi = (int)(MIN_RSSI + level * amountPerLevel);
+ // Put RSSI in the middle of the range.
+ rssi += amountPerLevel / 2;
+ Intent i = new Intent(WifiManager.RSSI_CHANGED_ACTION);
+ i.putExtra(WifiManager.EXTRA_NEW_RSSI, rssi);
+ mNetworkController.onReceive(mContext, i);
+ }
+
+ protected void setWifiEnabled(boolean enabled) {
+ Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ i.putExtra(WifiManager.EXTRA_WIFI_STATE,
+ enabled ? WifiManager.WIFI_STATE_ENABLED : WifiManager.WIFI_STATE_DISABLED);
+ mNetworkController.onReceive(mContext, i);
+ }
+
+ protected void setWifiState(boolean connected, String ssid) {
+ Intent i = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
+ Mockito.when(networkInfo.isConnected()).thenReturn(connected);
+
+ WifiInfo wifiInfo = Mockito.mock(WifiInfo.class);
+ Mockito.when(wifiInfo.getSSID()).thenReturn(ssid);
+
+ i.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
+ i.putExtra(WifiManager.EXTRA_WIFI_INFO, wifiInfo);
+ mNetworkController.onReceive(mContext, i);
+ }
+
+ protected void verifyLastQsDataDirection(boolean in, boolean out) {
+ ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
+
+ Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(Integer.class).capture(),
+ inArg.capture(), outArg.capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ ArgumentCaptor.forClass(String.class).capture());
+ assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
+ assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
+ }
+
+ protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon,
+ String description) {
+ ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> connectedArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+
+ Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
+ enabledArg.capture(), connectedArg.capture(), iconArg.capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ descArg.capture());
+ assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
+ assertEquals("WiFi connected, in quick settings", connected,
+ (boolean) connectedArg.getValue());
+ assertEquals("WiFi signal, in quick settings", icon, (int) iconArg.getValue());
+ assertEquals("WiFI desc (ssid), in quick settings", description,
+ (String) descArg.getValue());
+ }
+
+ protected void verifyLastWifiIcon(boolean visible, int icon) {
+ ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+
+ Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setWifiIndicators(
+ visibleArg.capture(), iconArg.capture(),
+ ArgumentCaptor.forClass(String.class).capture());
+ assertEquals("WiFi visible, in status bar", visible, (boolean) visibleArg.getValue());
+ assertEquals("WiFi signal, in status bar", icon, (int) iconArg.getValue());
+ }
+}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b670584..f9a6359 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -998,6 +998,10 @@
}
break;
case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
+ Slog.i(TAG, "Starting brightness boost.");
+ if (!interactive) {
+ wakeUpFromPowerKey(eventTime);
+ }
mPowerManager.boostScreenBrightness(eventTime);
break;
}
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 9596b57..da50751 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -16,8 +16,6 @@
package com.android.server;
-import com.android.internal.telephony.IMms;
-
import android.Manifest;
import android.app.AppOpsManager;
import android.app.PendingIntent;
@@ -38,6 +36,8 @@
import android.telephony.TelephonyManager;
import android.util.Slog;
+import com.android.internal.telephony.IMms;
+
/**
* This class is a proxy for MmsService APIs. We need this because MmsService runs
* in phone process and may crash anytime. This manages a connection to the actual
@@ -118,7 +118,7 @@
}
public void systemRunning() {
- tryConnecting();
+ Slog.i(TAG, "Delay connecting to MmsService until an API is called");
}
private void tryConnecting() {
@@ -206,7 +206,7 @@
* Throws a security exception unless the caller has carrier privilege.
*/
private void enforceCarrierPrivilege() {
- String[] packages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
+ final String[] packages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
for (String pkg : packages) {
if (getTelephonyManager().checkCarrierPrivilegesForPackage(pkg) ==
TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
@@ -216,12 +216,21 @@
throw new SecurityException("No carrier privilege");
}
+ private String getCallingPackageName() {
+ final String[] packages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
+ if (packages != null && packages.length > 0) {
+ return packages[0];
+ }
+ return "unknown";
+ }
+
// Service API calls implementation, proxied to the real MmsService in "com.android.mms.service"
private final class BinderService extends IMms.Stub {
@Override
public void sendMessage(int subId, String callingPkg, Uri contentUri,
String locationUrl, Bundle configOverrides, PendingIntent sentIntent)
throws RemoteException {
+ Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");
if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
callingPkg) != AppOpsManager.MODE_ALLOWED) {
@@ -235,6 +244,7 @@
public void downloadMessage(int subId, String callingPkg, String locationUrl,
Uri contentUri, Bundle configOverrides,
PendingIntent downloadedIntent) throws RemoteException {
+ Slog.d(TAG, "downloadMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS,
"Download MMS message");
if (getAppOpsManager().noteOp(AppOpsManager.OP_RECEIVE_MMS, Binder.getCallingUid(),
@@ -260,6 +270,7 @@
@Override
public Bundle getCarrierConfigValues(int subId) throws RemoteException {
+ Slog.d(TAG, "getCarrierConfigValues() by " + getCallingPackageName());
return getServiceGuarded().getCarrierConfigValues(subId);
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index d480f68..a2f4d56 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -77,7 +77,6 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.FgThread;
-
import com.google.android.collect.Lists;
import com.google.android.collect.Sets;
@@ -487,7 +486,7 @@
for (Account sa : sharedAccounts) {
if (ArrayUtils.contains(accounts, sa)) continue;
// Account doesn't exist. Copy it now.
- copyAccountToUser(sa, UserHandle.USER_OWNER, userId);
+ copyAccountToUser(null /*no response*/, sa, UserHandle.USER_OWNER, userId);
}
}
@@ -673,16 +672,31 @@
}
}
- private boolean copyAccountToUser(final Account account, int userFrom, int userTo) {
+ @Override
+ public void copyAccountToUser(final IAccountManagerResponse response, final Account account,
+ int userFrom, int userTo) {
+ enforceCrossUserPermission(UserHandle.USER_ALL, "Calling copyAccountToUser requires "
+ + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
final UserAccounts fromAccounts = getUserAccounts(userFrom);
final UserAccounts toAccounts = getUserAccounts(userTo);
if (fromAccounts == null || toAccounts == null) {
- return false;
+ if (response != null) {
+ Bundle result = new Bundle();
+ result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
+ try {
+ response.onResult(result);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to report error back to the client." + e);
+ }
+ }
+ return;
}
+ Slog.d(TAG, "Copying account " + account.name
+ + " from user " + userFrom + " to user " + userTo);
long identityToken = clearCallingIdentity();
try {
- new Session(fromAccounts, null, account.type, false,
+ new Session(fromAccounts, response, account.type, false,
false /* stripAuthTokenFromResult */) {
@Override
protected String toDebugString(long now) {
@@ -697,12 +711,10 @@
@Override
public void onResult(Bundle result) {
- if (result != null) {
- if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) {
- // Create a Session for the target user and pass in the bundle
- completeCloningAccount(result, account, toAccounts);
- }
- return;
+ if (result != null
+ && result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) {
+ // Create a Session for the target user and pass in the bundle
+ completeCloningAccount(response, result, account, toAccounts);
} else {
super.onResult(result);
}
@@ -711,14 +723,13 @@
} finally {
restoreCallingIdentity(identityToken);
}
- return true;
}
- void completeCloningAccount(final Bundle result, final Account account,
- final UserAccounts targetUser) {
+ private void completeCloningAccount(IAccountManagerResponse response,
+ final Bundle accountCredentials, final Account account, final UserAccounts targetUser) {
long id = clearCallingIdentity();
try {
- new Session(targetUser, null, account.type, false,
+ new Session(targetUser, response, account.type, false,
false /* stripAuthTokenFromResult */) {
@Override
protected String toDebugString(long now) {
@@ -731,10 +742,10 @@
// Confirm that the owner's account still exists before this step.
UserAccounts owner = getUserAccounts(UserHandle.USER_OWNER);
synchronized (owner.cacheLock) {
- Account[] ownerAccounts = getAccounts(UserHandle.USER_OWNER);
- for (Account acc : ownerAccounts) {
+ for (Account acc : getAccounts(UserHandle.USER_OWNER)) {
if (acc.equals(account)) {
- mAuthenticator.addAccountFromCredentials(this, account, result);
+ mAuthenticator.addAccountFromCredentials(
+ this, account, accountCredentials);
break;
}
}
@@ -743,17 +754,10 @@
@Override
public void onResult(Bundle result) {
- if (result != null) {
- if (result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)) {
- // TODO: Anything?
- } else {
- // TODO: Show error notification
- // TODO: Should we remove the shadow account to avoid retries?
- }
- return;
- } else {
- super.onResult(result);
- }
+ // TODO: Anything to do if if succedded?
+ // TODO: If it failed: Show error notification? Should we remove the shadow
+ // account to avoid retries?
+ super.onResult(result);
}
@Override
@@ -1043,7 +1047,8 @@
}
@Override
- public void removeAccount(IAccountManagerResponse response, Account account) {
+ public void removeAccount(IAccountManagerResponse response, Account account,
+ boolean expectActivityLaunch) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "removeAccount: " + account
+ ", response " + response
@@ -1088,7 +1093,7 @@
}
try {
- new RemoveAccountSession(accounts, response, account).bind();
+ new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1096,7 +1101,7 @@
@Override
public void removeAccountAsUser(IAccountManagerResponse response, Account account,
- int userId) {
+ boolean expectActivityLaunch, int userId) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "removeAccount: " + account
+ ", response " + response
@@ -1145,7 +1150,30 @@
}
try {
- new RemoveAccountSession(accounts, response, account).bind();
+ new RemoveAccountSession(accounts, response, account, expectActivityLaunch).bind();
+ } finally {
+ restoreCallingIdentity(identityToken);
+ }
+ }
+
+ @Override
+ public boolean removeAccountExplicitly(Account account) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "removeAccountExplicitly: " + account
+ + ", caller's uid " + Binder.getCallingUid()
+ + ", pid " + Binder.getCallingPid());
+ }
+ if (account == null) throw new IllegalArgumentException("account is null");
+ checkAuthenticateAccountsPermission(account);
+
+ UserAccounts accounts = getUserAccountsForCaller();
+ int userId = Binder.getCallingUserHandle().getIdentifier();
+ if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
+ return false;
+ }
+ long identityToken = clearCallingIdentity();
+ try {
+ return removeAccountInternal(accounts, account);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1154,8 +1182,8 @@
private class RemoveAccountSession extends Session {
final Account mAccount;
public RemoveAccountSession(UserAccounts accounts, IAccountManagerResponse response,
- Account account) {
- super(accounts, response, account.type, false /* expectActivityLaunch */,
+ Account account, boolean expectActivityLaunch) {
+ super(accounts, response, account.type, expectActivityLaunch,
true /* stripAuthTokenFromResult */);
mAccount = account;
}
@@ -1203,10 +1231,12 @@
removeAccountInternal(getUserAccountsForCaller(), account);
}
- private void removeAccountInternal(UserAccounts accounts, Account account) {
+ private boolean removeAccountInternal(UserAccounts accounts, Account account) {
+ int deleted;
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
+ + "=?",
new String[]{account.name, account.type});
removeAccountFromCacheLocked(accounts, account);
sendAccountsChangedBroadcast(accounts.userId);
@@ -1226,6 +1256,7 @@
Binder.restoreCallingIdentity(id);
}
}
+ return (deleted > 0);
}
@Override
@@ -2714,7 +2745,7 @@
break;
case MESSAGE_COPY_SHARED_ACCOUNT:
- copyAccountToUser((Account) msg.obj, msg.arg1, msg.arg2);
+ copyAccountToUser(/*no response*/ null, (Account) msg.obj, msg.arg1, msg.arg2);
break;
default:
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 120002e..38809cb 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -121,7 +121,7 @@
static final boolean DEBUG_RELEASE = DEBUG || false;
static final boolean DEBUG_SAVED_STATE = DEBUG || false;
static final boolean DEBUG_SCREENSHOTS = DEBUG || false;
- static final boolean DEBUG_STATES = DEBUG || true;
+ static final boolean DEBUG_STATES = DEBUG || false;
static final boolean DEBUG_VISIBLE_BEHIND = DEBUG || false;
public static final int HOME_STACK_ID = 0;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 81cd94b..8cfb4b3 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -582,11 +582,8 @@
state = mPowerState.getScreenState();
// Use zero brightness when screen is off.
- // Use full brightness when screen brightness is boosted.
if (state == Display.STATE_OFF) {
brightness = PowerManager.BRIGHTNESS_OFF;
- } else if (mPowerRequest.boostScreenBrightness) {
- brightness = PowerManager.BRIGHTNESS_ON;
}
// Configure auto-brightness.
@@ -601,6 +598,16 @@
mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON);
}
+ // Apply brightness boost.
+ // We do this here after configuring auto-brightness so that we don't
+ // disable the light sensor during this temporary state. That way when
+ // boost ends we will be able to resume normal auto-brightness behavior
+ // without any delay.
+ if (mPowerRequest.boostScreenBrightness
+ && brightness != PowerManager.BRIGHTNESS_OFF) {
+ brightness = PowerManager.BRIGHTNESS_ON;
+ }
+
// Apply auto-brightness.
boolean slowChange = false;
if (brightness < 0) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 02c9fcb5..ba18f48 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -805,7 +805,12 @@
+ flags + ", suggestedStream=" + suggestedStream);
}
- if (session == null) {
+ boolean preferSuggestedStream = false;
+ if (isValidLocalStreamType(suggestedStream)
+ && AudioSystem.isStreamActive(suggestedStream, 0)) {
+ preferSuggestedStream = true;
+ }
+ if (session == null || preferSuggestedStream) {
if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0
&& !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
if (DEBUG) {
@@ -959,6 +964,12 @@
return keyCode == KeyEvent.KEYCODE_HEADSETHOOK;
}
+ // we only handle public stream types, which are 0-5
+ private boolean isValidLocalStreamType(int streamType) {
+ return streamType >= AudioManager.STREAM_VOICE_CALL
+ && streamType <= AudioManager.STREAM_NOTIFICATION;
+ }
+
private KeyEventWakeLockReceiver mKeyEventReceiver = new KeyEventWakeLockReceiver(mHandler);
class KeyEventWakeLockReceiver extends ResultReceiver implements Runnable,
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index a1085d3..5de1a64 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -260,9 +260,11 @@
for (int i = 0; i < N; i++) {
final Condition c = conditions[i];
final ConditionRecord r = getRecordLocked(c.id, info.component);
+ final Condition oldCondition = r.condition;
+ final boolean conditionUpdate = oldCondition != null && !oldCondition.equals(c);
r.info = info;
r.condition = c;
- // if manual, exit zen if false (or failed)
+ // if manual, exit zen if false (or failed), update if true (and changed)
if (r.isManual) {
if (c.state == Condition.STATE_FALSE || c.state == Condition.STATE_ERROR) {
final boolean failed = c.state == Condition.STATE_ERROR;
@@ -275,6 +277,10 @@
"manualConditionExit");
unsubscribeLocked(r);
r.isManual = false;
+ } else if (c.state == Condition.STATE_TRUE && conditionUpdate) {
+ if (DEBUG) Slog.d(TAG, "Current condition updated, still true. old="
+ + oldCondition + " new=" + c);
+ setZenModeCondition(c, "conditionUpdate");
}
}
// if automatic, exit zen if false (or failed), enter zen if true
@@ -559,7 +565,7 @@
// enter downtime, or update mode if reconfigured during an active downtime
if (inDowntime && (mode == Global.ZEN_MODE_OFF || downtimeCurrent) && config != null) {
final Condition condition = mDowntime.createCondition(config.toDowntimeInfo(),
- Condition.STATE_TRUE);
+ config.sleepNone, Condition.STATE_TRUE);
mZenModeHelper.setZenMode(downtimeMode, "downtimeEnter");
setZenModeCondition(condition, "downtime");
}
diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
index 0fb5732..097589a 100644
--- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
+++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java
@@ -122,7 +122,8 @@
if (DEBUG) Slog.d(TAG, "onRequestConditions relevance=" + relevance);
if ((relevance & Condition.FLAG_RELEVANT_NOW) != 0) {
if (isInDowntime() && mConfig != null) {
- notifyCondition(createCondition(mConfig.toDowntimeInfo(), Condition.STATE_TRUE));
+ notifyCondition(createCondition(mConfig.toDowntimeInfo(), mConfig.sleepNone,
+ Condition.STATE_TRUE));
}
}
}
@@ -135,7 +136,7 @@
final int state = mConfig.toDowntimeInfo().equals(downtime) && isInDowntime()
? Condition.STATE_TRUE : Condition.STATE_FALSE;
if (DEBUG) Slog.d(TAG, "notify condition state: " + Condition.stateToString(state));
- notifyCondition(createCondition(downtime, state));
+ notifyCondition(createCondition(downtime, mConfig.sleepNone, state));
}
}
@@ -157,14 +158,22 @@
return mDowntimeMode != Global.ZEN_MODE_OFF;
}
- public Condition createCondition(DowntimeInfo downtime, int state) {
+ public Condition createCondition(DowntimeInfo downtime, boolean orAlarm, int state) {
if (downtime == null) return null;
final Uri id = ZenModeConfig.toDowntimeConditionId(downtime);
final String skeleton = DateFormat.is24HourFormat(mContext) ? "Hm" : "hma";
final Locale locale = Locale.getDefault();
final String pattern = DateFormat.getBestDateTimePattern(locale, skeleton);
- final long time = getTime(System.currentTimeMillis(), downtime.endHour, downtime.endMinute);
- final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(time));
+ final long now = System.currentTimeMillis();
+ long endTime = getTime(now, downtime.endHour, downtime.endMinute);
+ if (orAlarm) {
+ final AlarmClockInfo nextAlarm = mTracker.getNextAlarm();
+ final long nextAlarmTime = nextAlarm != null ? nextAlarm.getTriggerTime() : 0;
+ if (nextAlarmTime > now && nextAlarmTime < endTime) {
+ endTime = nextAlarmTime;
+ }
+ }
+ final String formatted = new SimpleDateFormat(pattern, locale).format(new Date(endTime));
final String summary = mContext.getString(R.string.downtime_condition_summary, formatted);
final String line1 = mContext.getString(R.string.downtime_condition_line_one);
return new Condition(id, summary, line1, formatted, 0, state, Condition.FLAG_RELEVANT_NOW);
@@ -302,6 +311,11 @@
private void onEvaluateNextAlarm(AlarmClockInfo nextAlarm, long wakeupTime, boolean booted) {
if (!booted) return; // we don't know yet
+ // update condition description if we're in downtime (mode = none)
+ if (isInDowntime() && mConfig != null && mConfig.sleepNone) {
+ notifyCondition(createCondition(mConfig.toDowntimeInfo(), true /*orAlarm*/,
+ Condition.STATE_TRUE));
+ }
if (nextAlarm == null) return; // not fireable
if (DEBUG) Slog.d(TAG, "onEvaluateNextAlarm " + mTracker.formatAlarmDebug(nextAlarm));
if (System.currentTimeMillis() > wakeupTime) {
@@ -336,6 +350,10 @@
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
if (DEBUG) Slog.d(TAG, "timezone changed to " + TimeZone.getDefault());
mCalendar.setTimeZone(TimeZone.getDefault());
+ mFiredAlarms.clear();
+ } else if (Intent.ACTION_TIME_CHANGED.equals(action)) {
+ if (DEBUG) Slog.d(TAG, "time changed to " + now);
+ mFiredAlarms.clear();
} else {
if (DEBUG) Slog.d(TAG, action + " fired at " + now);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 25c31c1..e1f249f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -2872,6 +2872,38 @@
return PackageManager.SIGNATURE_NO_MATCH;
}
+ private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
+ if (isExternal(scannedPkg)) {
+ return mSettings.isExternalDatabaseVersionOlderThan(
+ DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
+ } else {
+ return mSettings.isInternalDatabaseVersionOlderThan(
+ DatabaseVersion.SIGNATURE_MALFORMED_RECOVER);
+ }
+ }
+
+ private int compareSignaturesRecover(PackageSignatures existingSigs,
+ PackageParser.Package scannedPkg) {
+ if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
+ return PackageManager.SIGNATURE_NO_MATCH;
+ }
+
+ String msg = null;
+ try {
+ if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
+ logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
+ + scannedPkg.packageName);
+ return PackageManager.SIGNATURE_MATCH;
+ }
+ } catch (CertificateException e) {
+ msg = e.getMessage();
+ }
+
+ logCriticalInfo(Log.INFO,
+ "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
+ return PackageManager.SIGNATURE_NO_MATCH;
+ }
+
@Override
public String[] getPackagesForUid(int uid) {
uid = UserHandle.getAppId(uid);
@@ -4160,7 +4192,8 @@
if (ps != null
&& ps.codePath.equals(srcFile)
&& ps.timeStamp == srcFile.lastModified()
- && !isCompatSignatureUpdateNeeded(pkg)) {
+ && !isCompatSignatureUpdateNeeded(pkg)
+ && !isRecoverSignatureUpdateNeeded(pkg)) {
long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
if (ps.signatures.mSignatures != null
&& ps.signatures.mSignatures.length != 0
@@ -4435,6 +4468,10 @@
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
+ match = compareSignaturesRecover(pkgSetting.signatures, pkg)
+ == PackageManager.SIGNATURE_MATCH;
+ }
+ if (!match) {
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
+ pkg.packageName + " signatures do not match the "
+ "previously installed version; ignoring!");
@@ -4451,6 +4488,10 @@
== PackageManager.SIGNATURE_MATCH;
}
if (!match) {
+ match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
+ == PackageManager.SIGNATURE_MATCH;
+ }
+ if (!match) {
throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Package " + pkg.packageName
+ " has no signatures that match those in shared user "
@@ -5394,6 +5435,9 @@
if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) {
try {
verifySignaturesLP(pkgSetting, pkg);
+ // We just determined the app is signed correctly, so bring
+ // over the latest parsed certs.
+ pkgSetting.signatures.mSignatures = pkg.mSignatures;
} catch (PackageManagerException e) {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw e;
@@ -5426,7 +5470,8 @@
+ pkg.packageName + " upgrade keys do not match the "
+ "previously installed version");
} else {
- // signatures may have changed as result of upgrade
+ // We just determined the app is signed correctly, so bring
+ // over the latest parsed certs.
pkgSetting.signatures.mSignatures = pkg.mSignatures;
}
}
@@ -6392,7 +6437,7 @@
mResolveActivity.applicationInfo = pkg.applicationInfo;
mResolveActivity.name = mCustomResolverComponentName.getClassName();
mResolveActivity.packageName = pkg.applicationInfo.packageName;
- mResolveActivity.processName = null;
+ mResolveActivity.processName = pkg.applicationInfo.packageName;
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
@@ -8937,6 +8982,7 @@
&& isVerificationEnabled(userIdentifier, installFlags)) {
final Intent verification = new Intent(
Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
PACKAGE_MIME_TYPE);
verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 200eb5f..f0506a6 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -103,7 +103,7 @@
* Note that care should be taken to make sure all database upgrades are
* idempotent.
*/
- private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_END_ENTITY;
+ private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
/**
* This class contains constants that can be referred to from upgrade code.
@@ -121,6 +121,14 @@
* just the signing certificate.
*/
public static final int SIGNATURE_END_ENTITY = 2;
+
+ /**
+ * There was a window of time in
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP} where we persisted
+ * certificates after potentially mutating them. To switch back to the
+ * original untouched certificates, we need to force a collection pass.
+ */
+ public static final int SIGNATURE_MALFORMED_RECOVER = 3;
}
private static final boolean DEBUG_STOPPED = false;
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c054e6c..4d8b98f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1234,6 +1234,7 @@
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);
updateStayOnLocked(mDirty);
+ updateScreenBrightnessBoostLocked(mDirty);
// Phase 1: Update wakefulness.
// Loop because the wake lock and user activity computations are influenced
@@ -1641,7 +1642,8 @@
|| mProximityPositive
|| (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0
|| (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT
- | USER_ACTIVITY_SCREEN_DIM)) != 0;
+ | USER_ACTIVITY_SCREEN_DIM)) != 0
+ || mScreenBrightnessBoostInProgress;
}
/**
@@ -1828,9 +1830,6 @@
| DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked();
- // Handle screen brightness boost timeout.
- updateScreenBrightnessBoostLocked();
-
// Determine appropriate screen brightness and auto-brightness adjustments.
int screenBrightness = mScreenBrightnessSettingDefault;
float screenAutoBrightnessAdjustment = 0.0f;
@@ -1879,7 +1878,7 @@
}
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest,
- mRequestWaitForNegativeProximity) && !mScreenBrightnessBoostInProgress;
+ mRequestWaitForNegativeProximity);
mRequestWaitForNegativeProximity = false;
if (DEBUG_SPEW) {
@@ -1896,20 +1895,25 @@
return mDisplayReady && !oldDisplayReady;
}
- private void updateScreenBrightnessBoostLocked() {
- if (mScreenBrightnessBoostInProgress) {
- mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
- final long boostTimeout = mLastScreenBrightnessBoostTime +
- SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
- if (boostTimeout > SystemClock.uptimeMillis()) {
- Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- msg.setAsynchronous(true);
- mHandler.sendMessageAtTime(msg, boostTimeout);
- return;
+ private void updateScreenBrightnessBoostLocked(int dirty) {
+ if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
+ if (mScreenBrightnessBoostInProgress) {
+ final long now = SystemClock.uptimeMillis();
+ mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
+ final long boostTimeout = mLastScreenBrightnessBoostTime +
+ SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
+ if (boostTimeout > now) {
+ Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, boostTimeout);
+ return;
+ }
}
+ mScreenBrightnessBoostInProgress = false;
+ userActivityNoUpdateLocked(now,
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
}
- mScreenBrightnessBoostInProgress = false;
}
}
@@ -1940,7 +1944,8 @@
if ((mWakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
|| (mUserActivitySummary & USER_ACTIVITY_SCREEN_BRIGHT) != 0
- || !mBootCompleted) {
+ || !mBootCompleted
+ || mScreenBrightnessBoostInProgress) {
return DisplayPowerRequest.POLICY_BRIGHT;
}
@@ -2037,15 +2042,13 @@
final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
final boolean autoSuspend = !needDisplaySuspendBlocker;
+ final boolean interactive = mDisplayPowerRequest.isBrightOrDim();
// Disable auto-suspend if needed.
- if (!autoSuspend) {
- if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
- setHalAutoSuspendModeLocked(false);
- }
- if (mDecoupleHalInteractiveModeFromDisplayConfig) {
- setHalInteractiveModeLocked(true);
- }
+ // FIXME We should consider just leaving auto-suspend enabled forever since
+ // we already hold the necessary wakelocks.
+ if (!autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+ setHalAutoSuspendModeLocked(false);
}
// First acquire suspend blockers if needed.
@@ -2058,6 +2061,22 @@
mHoldingDisplaySuspendBlocker = true;
}
+ // Inform the power HAL about interactive mode.
+ // Although we could set interactive strictly based on the wakefulness
+ // as reported by isInteractive(), it is actually more desirable to track
+ // the display policy state instead so that the interactive state observed
+ // by the HAL more accurately tracks transitions between AWAKE and DOZING.
+ // Refer to getDesiredScreenPolicyLocked() for details.
+ if (mDecoupleHalInteractiveModeFromDisplayConfig) {
+ // When becoming non-interactive, we want to defer sending this signal
+ // until the display is actually ready so that all transitions have
+ // completed. This is probably a good sign that things have gotten
+ // too tangled over here...
+ if (interactive || mDisplayReady) {
+ setHalInteractiveModeLocked(interactive);
+ }
+ }
+
// Then release suspend blockers if needed.
if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
mWakeLockSuspendBlocker.release();
@@ -2069,13 +2088,8 @@
}
// Enable auto-suspend if needed.
- if (autoSuspend) {
- if (mDecoupleHalInteractiveModeFromDisplayConfig) {
- setHalInteractiveModeLocked(false);
- }
- if (mDecoupleHalAutoSuspendModeFromDisplayConfig) {
- setHalAutoSuspendModeLocked(true);
- }
+ if (autoSuspend && mDecoupleHalAutoSuspendModeFromDisplayConfig) {
+ setHalAutoSuspendModeLocked(true);
}
}
@@ -2097,6 +2111,9 @@
return true;
}
}
+ if (mScreenBrightnessBoostInProgress) {
+ return true;
+ }
// Let the system suspend if the screen is off or dozing.
return false;
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index f947b6a..7e6da8b5 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -984,12 +984,7 @@
final int visibleWindowCount = visibleWindows.size();
for (int i = visibleWindowCount - 1; i >= 0; i--) {
- WindowState windowState = visibleWindows.valueAt(i);
-
- // Compute the bounds in the screen.
- Rect boundsInScreen = mTempRect;
- computeWindowBoundsInScreen(windowState, boundsInScreen);
-
+ final WindowState windowState = visibleWindows.valueAt(i);
final int flags = windowState.mAttrs.flags;
// If the window is not touchable - ignore.
@@ -997,6 +992,16 @@
continue;
}
+ // If the window is an accessibility overlay - ignore.
+ if (windowState.mAttrs.type ==
+ WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
+ continue;
+ }
+
+ // Compute the bounds in the screen.
+ final Rect boundsInScreen = mTempRect;
+ computeWindowBoundsInScreen(windowState, boundsInScreen);
+
// If the window is completely covered by other windows - ignore.
if (unaccountedSpace.quickReject(boundsInScreen)) {
continue;
@@ -1013,14 +1018,8 @@
}
}
- // Account for the space this window takes if the window
- // is not an accessibility overlay which does not change
- // the reported windows.
- if (windowState.mAttrs.type == WindowManager.LayoutParams
- .TYPE_ACCESSIBILITY_OVERLAY) {
- unaccountedSpace.op(boundsInScreen, unaccountedSpace,
- Region.Op.REVERSE_DIFFERENCE);
- }
+ unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+ Region.Op.REVERSE_DIFFERENCE);
// We figured out what is touchable for the entire screen - done.
if (unaccountedSpace.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 5deb1cd..345e8af 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -333,10 +333,11 @@
+ " hidden=" + win.mRootToken.hidden
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
- final boolean hideWhenLocked = !((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard) ||
- (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
- // Show error dialogs over apps that dismiss keyguard.
- (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
+ final boolean hideWhenLocked =
+ !(((win.mIsImWindow || imeTarget == win) && showImeOverKeyguard)
+ || (appShowWhenLocked != null && (appShowWhenLocked == win.mAppToken ||
+ // Show error dialogs over apps that dismiss keyguard.
+ (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
if (((mForceHiding == KEYGUARD_ANIMATING_IN)
&& (!winAnimator.isAnimating() || hideWhenLocked))
|| ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked)) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index eb418ed6..bcfd7f0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2541,7 +2541,7 @@
}
mInputMonitor.updateInputWindowsLw(false /*force*/);
- if (true || localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG, "addWindow: New client "
+ if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG, "addWindow: New client "
+ client.asBinder() + ": window=" + win + " Callers=" + Debug.getCallers(5));
if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) {
@@ -2706,8 +2706,7 @@
mPolicy.removeWindowLw(win);
win.removeLocked();
- if (true || DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win +
- " Callers=" + Debug.getCallers(5));
+ if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win);
mWindowMap.remove(win.mClient.asBinder());
if (win.mAppOp != AppOpsManager.OP_NONE) {
mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage());
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index cc5d004..1cf00d2 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -207,7 +207,12 @@
case MESSAGE_ADB_CONFIRM: {
String key = (String)msg.obj;
- mFingerprints = getFingerprints(key);
+ String fingerprints = getFingerprints(key);
+ if ("".equals(fingerprints)) {
+ sendResponse("NO");
+ break;
+ }
+ mFingerprints = fingerprints;
startConfirmation(key, mFingerprints);
break;
}
@@ -224,16 +229,25 @@
StringBuilder sb = new StringBuilder();
MessageDigest digester;
+ if (key == null) {
+ return "";
+ }
+
try {
digester = MessageDigest.getInstance("MD5");
} catch (Exception ex) {
- Slog.e(TAG, "Error getting digester: " + ex);
+ Slog.e(TAG, "Error getting digester", ex);
return "";
}
byte[] base64_data = key.split("\\s+")[0].getBytes();
- byte[] digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
-
+ byte[] digest;
+ try {
+ digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "error doing base64 decoding", e);
+ return "";
+ }
for (int i = 0; i < digest.length; i++) {
sb.append(hex.charAt((digest[i] >> 4) & 0xf));
sb.append(hex.charAt(digest[i] & 0xf));
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
index 8ce7f74..3ca0c84 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java
@@ -40,7 +40,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.UUID;
/**
* Helper for {@link SoundTrigger} APIs.
@@ -78,7 +77,7 @@
private IRecognitionStatusCallback mActiveListener;
private int mKeyphraseId = INVALID_VALUE;
private int mCurrentSoundModelHandle = INVALID_VALUE;
- private UUID mCurrentSoundModelUuid = null;
+ private KeyphraseSoundModel mCurrentSoundModel = null;
// FIXME: Ideally this should not be stored if allowMultipleTriggers happens at a lower layer.
private RecognitionConfig mRecognitionConfig = null;
private boolean mRequested = false;
@@ -134,7 +133,7 @@
+ (mActiveListener == null ? "null" : mActiveListener.asBinder()));
Slog.d(TAG, "current SoundModel handle=" + mCurrentSoundModelHandle);
Slog.d(TAG, "current SoundModel UUID="
- + (mCurrentSoundModelUuid == null ? null : mCurrentSoundModelUuid));
+ + (mCurrentSoundModel == null ? null : mCurrentSoundModel.uuid));
}
if (!mStarted) {
@@ -166,20 +165,16 @@
}
// Unload the previous model if the current one isn't invalid
- // and, it's not the same as the new one, or we are already started
- // if we are already started, we can get multiple calls to start
- // if the underlying sound model changes, in which case we should unload and reload.
- // The model reuse helps only in cases when we trigger and stop internally
- // without a start recognition call.
+ // and, it's not the same as the new one.
+ // This helps use cache and reuse the model and just start/stop it when necessary.
if (mCurrentSoundModelHandle != INVALID_VALUE
- && (!soundModel.uuid.equals(mCurrentSoundModelUuid) || mStarted)) {
+ && !soundModel.equals(mCurrentSoundModel)) {
Slog.w(TAG, "Unloading previous sound model");
int status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
if (status != SoundTrigger.STATUS_OK) {
Slog.w(TAG, "unloadSoundModel call failed with " + status);
}
- mCurrentSoundModelHandle = INVALID_VALUE;
- mCurrentSoundModelUuid = null;
+ internalClearSoundModelLocked();
mStarted = false;
}
@@ -198,7 +193,7 @@
// Load the sound model if the current one is null.
int soundModelHandle = mCurrentSoundModelHandle;
if (mCurrentSoundModelHandle == INVALID_VALUE
- || mCurrentSoundModelUuid == null) {
+ || mCurrentSoundModel == null) {
int[] handle = new int[] { INVALID_VALUE };
int status = mModule.loadSoundModel(soundModel, handle);
if (status != SoundTrigger.STATUS_OK) {
@@ -218,7 +213,7 @@
mRequested = true;
mKeyphraseId = keyphraseId;
mCurrentSoundModelHandle = soundModelHandle;
- mCurrentSoundModelUuid = soundModel.uuid;
+ mCurrentSoundModel = soundModel;
mRecognitionConfig = recognitionConfig;
// Register the new listener. This replaces the old one.
// There can only be a maximum of one active listener at any given time.
@@ -275,14 +270,9 @@
return status;
}
- status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "unloadSoundModel call failed with " + status);
- }
-
- // Clear the internal state once the recognition has been stopped.
- // Unload sound model call may fail in scenarios, and we'd still want
- // to reload the sound model.
+ // We leave the sound model loaded but not started, this helps us when we start
+ // back.
+ // Also clear the internal state once the recognition has been stopped.
internalClearStateLocked();
return status;
}
@@ -303,11 +293,6 @@
mRequested = false;
int status = updateRecognitionLocked(false /* don't notify for synchronous calls */);
- status = mModule.unloadSoundModel(mCurrentSoundModelHandle);
- if (status != SoundTrigger.STATUS_OK) {
- Slog.w(TAG, "unloadSoundModel call failed with " + status);
- }
-
internalClearStateLocked();
}
}
@@ -456,6 +441,7 @@
} catch (RemoteException e) {
Slog.w(TAG, "RemoteException in onError", e);
} finally {
+ internalClearSoundModelLocked();
internalClearStateLocked();
if (mModule != null) {
mModule.detach();
@@ -535,8 +521,6 @@
mRequested = false;
mKeyphraseId = INVALID_VALUE;
- mCurrentSoundModelHandle = INVALID_VALUE;
- mCurrentSoundModelUuid = null;
mRecognitionConfig = null;
mActiveListener = null;
@@ -550,6 +534,11 @@
}
}
+ private void internalClearSoundModelLocked() {
+ mCurrentSoundModelHandle = INVALID_VALUE;
+ mCurrentSoundModel = null;
+ }
+
class MyCallStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String arg1) {
@@ -581,7 +570,7 @@
pw.print(" keyphrase ID="); pw.println(mKeyphraseId);
pw.print(" sound model handle="); pw.println(mCurrentSoundModelHandle);
pw.print(" sound model UUID=");
- pw.println(mCurrentSoundModelUuid == null ? "null" : mCurrentSoundModelUuid);
+ pw.println(mCurrentSoundModel == null ? "null" : mCurrentSoundModel.uuid);
pw.print(" current listener=");
pw.println(mActiveListener == null ? "null" : mActiveListener.asBinder());
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index a49c204f..2240c44 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -640,6 +640,7 @@
if (mIconBitmap == null) {
out.writeInt(0);
} else {
+ out.writeInt(1);
mIconBitmap.writeToParcel(out, flags);
}
out.writeInt(mIconTint);
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 6fe10dc..1891976 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -160,11 +160,27 @@
*/
public static final int OUTGOING_CANCELED = 44;
+ /**
+ * The call, which was an IMS call, disconnected because it merged with another call.
+ */
+ public static final int IMS_MERGED_SUCCESSFULLY = 45;
+
+ //*********************************************************************************************
+ // When adding a disconnect type:
+ // 1) Please assign the new type the next id value below.
+ // 2) Increment the next id value below to a new value.
+ // 3) Update MAXIMUM_VALID_VALUE to the new disconnect type.
+ // 4) Update toString() with the newly added disconnect type.
+ // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
+ //
+ // NextId: 46
+ //*********************************************************************************************
+
/** Smallest valid value for call disconnect codes. */
public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
/** Largest valid value for call disconnect codes. */
- public static final int MAXIMUM_VALID_VALUE = OUTGOING_CANCELED;
+ public static final int MAXIMUM_VALID_VALUE = IMS_MERGED_SUCCESSFULLY;
/** Private constructor to avoid class instantiation. */
private DisconnectCause() {
@@ -262,6 +278,8 @@
return "OUTGOING_FAILURE";
case OUTGOING_CANCELED:
return "OUTGOING_CANCELED";
+ case IMS_MERGED_SUCCESSFULLY:
+ return "IMS_MERGED_SUCCESSFULLY";
default:
return "INVALID: " + cause;
}
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 560af45..15fa340 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -290,81 +290,102 @@
/**
* Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
+ * message identifier and RAN type. The RAN type specify this message ID
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
+ * enable the same message identifier, they must both disable it for the
+ * device to stop receiving those messages.
*
* @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #disableCellBroadcast(int)
+ * @see #disableCellBroadcast(int, int)
*/
- boolean enableCellBroadcast(int messageIdentifier);
+ boolean enableCellBroadcast(int messageIdentifier, int ranType);
/**
* Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
+ * message identifier and RAN type. The RAN type specify this message ID
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
+ * enable the same message identifier, they must both disable it for the
+ * device to stop receiving those messages.
*
* @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
* @param subId for which the broadcast has to be enabled
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #disableCellBroadcast(int)
+ * @see #disableCellBroadcast(int, int)
*/
- boolean enableCellBroadcastForSubscriber(in int subId, int messageIdentifier);
+ boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType);
/**
* Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
+ * message identifier and RAN type. The RAN type specify this message ID
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
+ * enable the same message identifier, they must both disable it for the
+ * device to stop receiving those messages.
*
* @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #enableCellBroadcast(int)
+ * @see #enableCellBroadcast(int, int)
*/
- boolean disableCellBroadcast(int messageIdentifier);
+ boolean disableCellBroadcast(int messageIdentifier, int ranType);
/**
* Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier. Note that if two different clients enable the same
- * message identifier, they must both disable it for the device to stop
- * receiving those messages.
+ * message identifier and RAN type. The RAN type specify this message ID
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients
+ * enable the same message identifier, they must both disable it for the
+ * device to stop receiving those messages.
*
* @param messageIdentifier Message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
* @param subId for which the broadcast has to be disabled
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #enableCellBroadcast(int)
+ * @see #enableCellBroadcast(int, int)
*/
- boolean disableCellBroadcastForSubscriber(in int subId, int messageIdentifier);
+ boolean disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType);
/*
* Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
- * a message identifier range, they must both disable it for the device
- * to stop receiving those messages.
+ * message identifier range and RAN type. The RAN type specify this message
+ * ID range belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different
+ * clients enable a message identifier range, they must both disable it for
+ * the device to stop receiving those messages.
*
* @param startMessageId first message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
* @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #disableCellBroadcastRange(int, int)
+ * @see #disableCellBroadcastRange(int, int, int)
*/
- boolean enableCellBroadcastRange(int startMessageId, int endMessageId);
+ boolean enableCellBroadcastRange(int startMessageId, int endMessageId, int ranType);
/*
* Enable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
+ * message identifier range and RAN type. The RAN type specify this message ID range
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable
* a message identifier range, they must both disable it for the device
* to stop receiving those messages.
*
@@ -373,15 +394,20 @@
* @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
* @param subId for which the broadcast has to be enabled
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
- * @see #disableCellBroadcastRange(int, int)
+ * @see #disableCellBroadcastRange(int, int, int)
*/
- boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId);
+ boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId,
+ int ranType);
/**
* Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
+ * message identifier range and RAN type. The RAN type specify this message ID range
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable
* a message identifier range, they must both disable it for the device
* to stop receiving those messages.
*
@@ -389,29 +415,36 @@
* C.R1001-G (3GPP2)
* @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or
* C.R1001-G (3GPP2)
- * @return true if successful, false otherwise
- *
- * @see #enableCellBroadcastRange(int, int)
- */
- boolean disableCellBroadcastRange(int startMessageId, int endMessageId);
-
- /**
- * Disable reception of cell broadcast (SMS-CB) messages with the given
- * message identifier range. Note that if two different clients enable
- * a message identifier range, they must both disable it for the device
- * to stop receiving those messages.
- *
- * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) or
- * C.R1001-G (3GPP2)
- * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or
- * C.R1001-G (3GPP2)
- * @param subId for which the broadcast has to be disabled
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
* @return true if successful, false otherwise
*
* @see #enableCellBroadcastRange(int, int, int)
*/
+ boolean disableCellBroadcastRange(int startMessageId, int endMessageId, int ranType);
+
+ /**
+ * Disable reception of cell broadcast (SMS-CB) messages with the given
+ * message identifier range and RAN type. The RAN type specify this message ID range
+ * belong to 3GPP (GSM) or 3GPP2(CDMA). Note that if two different clients enable
+ * a message identifier range, they must both disable it for the device
+ * to stop receiving those messages.
+ *
+ * @param startMessageId first message identifier as specified in TS 23.041 (3GPP) or
+ * C.R1001-G (3GPP2)
+ * @param endMessageId last message identifier as specified in TS 23.041 (3GPP) or
+ * C.R1001-G (3GPP2)
+ * @param subId for which the broadcast has to be disabled
+ * @param ranType as defined in class SmsManager, the value can be one of these:
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_GSM
+ * android.telephony.SmsMessage.CELL_BROADCAST_RAN_TYPE_CDMA
+ * @return true if successful, false otherwise
+ *
+ * @see #enableCellBroadcastRange(int, int, int, int)
+ */
boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId,
- int endMessageId);
+ int endMessageId, int ranType);
/**
* Returns the premium SMS send permission for the specified package.
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml
new file mode 100644
index 0000000..3dff196
--- /dev/null
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable30.xml
@@ -0,0 +1,28 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="48dp"
+ android:width="48dp"
+ android:viewportHeight="48"
+ android:viewportWidth="48" >
+
+ <group>
+ <path
+ android:name="plus1"
+ android:pathData="M20 16h-4v8h-8v4h8v8h4v-8h8v-4h-8zm9-3.84v3.64l5-1v21.2h4v-26z"
+ android:fillColor="#ff00ff00"/>
+ </group>
+</vector>
diff --git a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
index 1cd6533..5a2e5a7 100644
--- a/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
+++ b/tests/VectorDrawableTest/src/com/android/test/dynamic/VectorDrawablePerformance.java
@@ -57,6 +57,7 @@
R.drawable.vector_drawable27,
R.drawable.vector_drawable28,
R.drawable.vector_drawable29,
+ R.drawable.vector_drawable30,
};
@Override