Merge "Removed some left over log spam."
diff --git a/api/current.txt b/api/current.txt
index e50eba1..c700501 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5686,10 +5686,13 @@
method public android.graphics.drawable.Drawable peekFastDrawable();
method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
- method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public void setResource(int) throws java.io.IOException;
+ method public int setResource(int, int) throws java.io.IOException;
method public void setStream(java.io.InputStream) throws java.io.IOException;
- method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public void setWallpaperOffsetSteps(float, float);
method public void setWallpaperOffsets(android.os.IBinder, float, float);
method public void suggestDesiredDimensions(int, int);
@@ -5700,6 +5703,8 @@
field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+ field public static final int FLAG_SET_LOCK = 2; // 0x2
+ field public static final int FLAG_SET_SYSTEM = 1; // 0x1
field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
}
@@ -8429,6 +8434,7 @@
field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -13574,6 +13580,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -13933,6 +13940,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14011,6 +14019,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -22760,6 +22769,7 @@
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
method public deprecated int getNetworkPreference();
method public static deprecated android.net.Network getProcessDefaultNetwork();
+ method public int getRestrictBackgroundStatus();
method public boolean isActiveNetworkMetered();
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
@@ -22794,6 +22804,9 @@
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
+ field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+ field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+ field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
field public static final int TYPE_BLUETOOTH = 7; // 0x7
field public static final int TYPE_DUMMY = 8; // 0x8
field public static final int TYPE_ETHERNET = 9; // 0x9
@@ -22820,6 +22833,9 @@
method public abstract void onNetworkActive();
}
+ public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
+ }
+
public class Credentials {
ctor public Credentials(int, int, int);
method public int getGid();
@@ -35616,6 +35632,7 @@
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
+ field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -35626,6 +35643,8 @@
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
+ field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
+ field public static final java.lang.String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
@@ -44092,6 +44111,30 @@
method public abstract android.view.View getFullScreenView(int, android.content.Context);
}
+ public class ServiceWorkerClient {
+ ctor public ServiceWorkerClient();
+ method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerController {
+ ctor public ServiceWorkerController();
+ method public static android.webkit.ServiceWorkerController getInstance();
+ method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient);
+ }
+
+ public abstract class ServiceWorkerWebSettings {
+ ctor public ServiceWorkerWebSettings();
+ method public abstract boolean getAllowContentAccess();
+ method public abstract boolean getAllowFileAccess();
+ method public abstract boolean getBlockNetworkLoads();
+ method public abstract int getCacheMode();
+ method public abstract void setAllowContentAccess(boolean);
+ method public abstract void setAllowFileAccess(boolean);
+ method public abstract void setBlockNetworkLoads(boolean);
+ method public abstract void setCacheMode(int);
+ }
+
public class SslErrorHandler extends android.os.Handler {
method public void cancel();
method public void proceed();
diff --git a/api/system-current.txt b/api/system-current.txt
index 2d358bf..7444db1 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5818,12 +5818,15 @@
method public android.graphics.drawable.Drawable peekFastDrawable();
method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
- method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public void setDisplayOffset(android.os.IBinder, int, int);
method public void setDisplayPadding(android.graphics.Rect);
method public void setResource(int) throws java.io.IOException;
+ method public int setResource(int, int) throws java.io.IOException;
method public void setStream(java.io.InputStream) throws java.io.IOException;
- method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public boolean setWallpaperComponent(android.content.ComponentName);
method public void setWallpaperOffsetSteps(float, float);
method public void setWallpaperOffsets(android.os.IBinder, float, float);
@@ -5835,6 +5838,8 @@
field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+ field public static final int FLAG_SET_LOCK = 2; // 0x2
+ field public static final int FLAG_SET_SYSTEM = 1; // 0x1
field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
}
@@ -8730,6 +8735,7 @@
field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -13974,6 +13980,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -14333,6 +14340,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14411,6 +14419,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -24348,6 +24357,7 @@
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
method public deprecated int getNetworkPreference();
method public static deprecated android.net.Network getProcessDefaultNetwork();
+ method public int getRestrictBackgroundStatus();
method public boolean isActiveNetworkMetered();
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
@@ -24382,6 +24392,9 @@
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
+ field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+ field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+ field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
field public static final int TYPE_BLUETOOTH = 7; // 0x7
field public static final int TYPE_DUMMY = 8; // 0x8
field public static final int TYPE_ETHERNET = 9; // 0x9
@@ -24408,6 +24421,9 @@
method public abstract void onNetworkActive();
}
+ public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
+ }
+
public class Credentials {
ctor public Credentials(int, int, int);
method public int getGid();
@@ -46576,6 +46592,30 @@
method public abstract android.view.View getFullScreenView(int, android.content.Context);
}
+ public class ServiceWorkerClient {
+ ctor public ServiceWorkerClient();
+ method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerController {
+ ctor public ServiceWorkerController();
+ method public static android.webkit.ServiceWorkerController getInstance();
+ method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient);
+ }
+
+ public abstract class ServiceWorkerWebSettings {
+ ctor public ServiceWorkerWebSettings();
+ method public abstract boolean getAllowContentAccess();
+ method public abstract boolean getAllowFileAccess();
+ method public abstract boolean getBlockNetworkLoads();
+ method public abstract int getCacheMode();
+ method public abstract void setAllowContentAccess(boolean);
+ method public abstract void setAllowFileAccess(boolean);
+ method public abstract void setBlockNetworkLoads(boolean);
+ method public abstract void setCacheMode(int);
+ }
+
public class SslErrorHandler extends android.os.Handler {
ctor public SslErrorHandler();
method public void cancel();
@@ -46588,12 +46628,18 @@
method public abstract void deleteKey(android.net.Uri, android.webkit.ValueCallback<java.lang.Boolean>);
method public abstract void enableTokenBinding();
method public static android.webkit.TokenBindingService getInstance();
- method public abstract void getKey(android.net.Uri, java.lang.String, android.webkit.ValueCallback<java.security.KeyPair>);
+ method public abstract void getKey(android.net.Uri, java.lang.String[], android.webkit.ValueCallback<android.webkit.TokenBindingService.TokenBindingKey>);
field public static final java.lang.String KEY_ALGORITHM_ECDSAP256 = "ECDSAP256";
field public static final java.lang.String KEY_ALGORITHM_RSA2048_PKCS_1_5 = "RSA2048_PKCS_1.5";
field public static final java.lang.String KEY_ALGORITHM_RSA2048_PSS = "RSA2048PSS";
}
+ public static abstract class TokenBindingService.TokenBindingKey {
+ ctor public TokenBindingService.TokenBindingKey();
+ method public abstract java.lang.String getAlgorithm();
+ method public abstract java.security.KeyPair getKeyPair();
+ }
+
public final class URLUtil {
ctor public URLUtil();
method public static java.lang.String composeSearchUrl(java.lang.String, java.lang.String, java.lang.String);
@@ -47215,6 +47261,7 @@
method public abstract android.webkit.WebViewProvider createWebView(android.webkit.WebView, android.webkit.WebView.PrivateAccess);
method public abstract android.webkit.CookieManager getCookieManager();
method public abstract android.webkit.GeolocationPermissions getGeolocationPermissions();
+ method public abstract android.webkit.ServiceWorkerController getServiceWorkerController();
method public abstract android.webkit.WebViewFactoryProvider.Statics getStatics();
method public abstract android.webkit.TokenBindingService getTokenBindingService();
method public abstract android.webkit.WebIconDatabase getWebIconDatabase();
diff --git a/api/test-current.txt b/api/test-current.txt
index bcdf5c1..8067480 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5688,10 +5688,13 @@
method public android.graphics.drawable.Drawable peekFastDrawable();
method public void sendWallpaperCommand(android.os.IBinder, java.lang.String, int, int, int, android.os.Bundle);
method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
- method public void setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public void setResource(int) throws java.io.IOException;
+ method public int setResource(int, int) throws java.io.IOException;
method public void setStream(java.io.InputStream) throws java.io.IOException;
- method public void setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean) throws java.io.IOException;
+ method public int setStream(java.io.InputStream, android.graphics.Rect, boolean, int) throws java.io.IOException;
method public void setWallpaperOffsetSteps(float, float);
method public void setWallpaperOffsets(android.os.IBinder, float, float);
method public void suggestDesiredDimensions(int, int);
@@ -5702,6 +5705,8 @@
field public static final java.lang.String COMMAND_SECONDARY_TAP = "android.wallpaper.secondaryTap";
field public static final java.lang.String COMMAND_TAP = "android.wallpaper.tap";
field public static final java.lang.String EXTRA_LIVE_WALLPAPER_COMPONENT = "android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT";
+ field public static final int FLAG_SET_LOCK = 2; // 0x2
+ field public static final int FLAG_SET_SYSTEM = 1; // 0x1
field public static final java.lang.String WALLPAPER_PREVIEW_META_DATA = "android.wallpaper.preview";
}
@@ -8434,6 +8439,7 @@
field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ field public static final java.lang.String ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
field public static final java.lang.String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED";
field public static final java.lang.String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
@@ -13582,6 +13588,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AF;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
@@ -13941,6 +13948,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
@@ -14019,6 +14027,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_CAPTURE_INTENT;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_EFFECT_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
@@ -22768,6 +22777,7 @@
method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
method public deprecated int getNetworkPreference();
method public static deprecated android.net.Network getProcessDefaultNetwork();
+ method public int getRestrictBackgroundStatus();
method public boolean isActiveNetworkMetered();
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
@@ -22802,6 +22812,9 @@
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
+ field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+ field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+ field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
field public static final int TYPE_BLUETOOTH = 7; // 0x7
field public static final int TYPE_DUMMY = 8; // 0x8
field public static final int TYPE_ETHERNET = 9; // 0x9
@@ -22828,6 +22841,9 @@
method public abstract void onNetworkActive();
}
+ public static abstract class ConnectivityManager.RestrictBackgroundStatus implements java.lang.annotation.Annotation {
+ }
+
public class Credentials {
ctor public Credentials(int, int, int);
method public int getGid();
@@ -35630,6 +35646,7 @@
field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
+ field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -35640,6 +35657,8 @@
field public static final java.lang.String EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME = "android.telecom.extra.CHANGE_DEFAULT_DIALER_PACKAGE_NAME";
field public static final java.lang.String EXTRA_INCOMING_CALL_ADDRESS = "android.telecom.extra.INCOMING_CALL_ADDRESS";
field public static final java.lang.String EXTRA_INCOMING_CALL_EXTRAS = "android.telecom.extra.INCOMING_CALL_EXTRAS";
+ field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telecom.extra.NOTIFICATION_COUNT";
+ field public static final java.lang.String EXTRA_NOTIFICATION_PHONE_NUMBER = "android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
field public static final java.lang.String EXTRA_OUTGOING_CALL_EXTRAS = "android.telecom.extra.OUTGOING_CALL_EXTRAS";
field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecom.extra.PHONE_ACCOUNT_HANDLE";
field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecom.extra.START_CALL_WITH_SPEAKERPHONE";
@@ -44108,6 +44127,30 @@
method public abstract android.view.View getFullScreenView(int, android.content.Context);
}
+ public class ServiceWorkerClient {
+ ctor public ServiceWorkerClient();
+ method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerController {
+ ctor public ServiceWorkerController();
+ method public static android.webkit.ServiceWorkerController getInstance();
+ method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient);
+ }
+
+ public abstract class ServiceWorkerWebSettings {
+ ctor public ServiceWorkerWebSettings();
+ method public abstract boolean getAllowContentAccess();
+ method public abstract boolean getAllowFileAccess();
+ method public abstract boolean getBlockNetworkLoads();
+ method public abstract int getCacheMode();
+ method public abstract void setAllowContentAccess(boolean);
+ method public abstract void setAllowFileAccess(boolean);
+ method public abstract void setBlockNetworkLoads(boolean);
+ method public abstract void setCacheMode(int);
+ }
+
public class SslErrorHandler extends android.os.Handler {
method public void cancel();
method public void proceed();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 93122dd..37b861e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -83,6 +83,7 @@
import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.LocaleList;
import android.util.Log;
import android.util.LogPrinter;
import android.util.Pair;
@@ -128,7 +129,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.TimeZone;
@@ -3300,6 +3300,17 @@
}
r.activity.performResume();
+ // If there is a pending relaunch that was requested when the activity was paused,
+ // it will put the activity into paused state when it finally happens. Since the
+ // activity resumed before being relaunched, we don't want that to happen, so we
+ // need to clear the request to relaunch paused.
+ for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
+ final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
+ if (relaunching.token == r.token && relaunching.startsNotResumed) {
+ relaunching.startsNotResumed = false;
+ }
+ }
+
EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED,
UserHandle.myUserId(), r.activity.getComponentName().getClassName());
@@ -3528,6 +3539,7 @@
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
+ if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
@@ -4167,6 +4179,7 @@
synchronized (mResourcesManager) {
for (int i=0; i<mRelaunchingActivities.size(); i++) {
ActivityClientRecord r = mRelaunchingActivities.get(i);
+ if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + this + ", trying: " + r);
if (r.token == token) {
target = r;
if (pendingResults != null) {
@@ -4197,14 +4210,19 @@
}
if (target == null) {
+ if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: target is null, fromServer:"
+ + fromServer);
target = new ActivityClientRecord();
target.token = token;
target.pendingResults = pendingResults;
target.pendingIntents = pendingNewIntents;
target.mPreserveWindow = preserveWindow;
if (!fromServer) {
- ActivityClientRecord existing = mActivities.get(token);
+ final ActivityClientRecord existing = mActivities.get(token);
+ if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: " + existing);
if (existing != null) {
+ if (DEBUG_ORDER) Slog.d(TAG, "requestRelaunchActivity: paused= "
+ + existing.paused);;
target.startsNotResumed = existing.paused;
target.overrideConfig = existing.overrideConfig;
}
@@ -4227,8 +4245,8 @@
target.pendingConfigChanges |= configChanges;
target.relaunchSeq = getLifecycleSeq();
}
- if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this
- + " operation received seq: " + target.relaunchSeq);
+ if (DEBUG_ORDER) Slog.d(TAG, "relaunchActivity " + ActivityThread.this + ", target "
+ + target + " operation received seq: " + target.relaunchSeq);
}
private void handleRelaunchActivity(ActivityClientRecord tmp) {
@@ -4887,9 +4905,9 @@
TimeZone.setDefault(null);
/*
- * Initialize the default locale in this process for the reasons we set the time zone.
+ * Initialize the default locales in this process for the reasons we set the time zone.
*/
- Locale.setDefault(data.config.locale);
+ LocaleList.setDefault(data.config.getLocales());
/*
* Update the system configuration since its preloaded and might not
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index ccba250..7a0e7f6 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -28,37 +28,47 @@
/**
* Set the wallpaper.
+ *
+ * If 'extras' is non-null, on successful return it will contain:
+ * EXTRA_SET_WALLPAPER_ID : integer ID that the new wallpaper will have
+ *
+ * 'which' is some combination of:
+ * FLAG_SET_SYSTEM
+ * FLAG_SET_LOCK
*/
- ParcelFileDescriptor setWallpaper(String name, in String callingPackage);
+ ParcelFileDescriptor setWallpaper(String name, in String callingPackage,
+ out Bundle extras, int which);
/**
- * Set the live wallpaper.
+ * Set the live wallpaper. This only affects the system wallpaper.
*/
void setWallpaperComponentChecked(in ComponentName name, in String callingPackage);
/**
- * Set the live wallpaper.
+ * Set the live wallpaper. This only affects the system wallpaper.
*/
void setWallpaperComponent(in ComponentName name);
/**
- * Get the wallpaper.
+ * Get the system wallpaper.
*/
ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
out Bundle outParams);
/**
- * Get information about a live wallpaper.
+ * If the current system wallpaper is a live wallpaper component, return the
+ * information about that wallpaper. Otherwise, if it is a static image,
+ * simply return null.
*/
WallpaperInfo getWallpaperInfo();
/**
- * Clear the wallpaper.
+ * Clear the system wallpaper.
*/
void clearWallpaper(in String callingPackage);
/**
- * Return whether there is a wallpaper set with the given name.
+ * Return whether the current system wallpaper has the given name.
*/
boolean hasNamedWallpaper(String name);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 7184337..24a3470 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -545,7 +545,7 @@
* returning the resulting activity or till the timeOut period expires.
* If the timeOut expires before the activity is started, return null.
*
- * @param timeOut Time to wait before the activity is created.
+ * @param timeOut Time to wait in milliseconds before the activity is created.
*
* @return Activity
*/
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 3187984..260216c 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -27,6 +27,7 @@
import android.hardware.display.DisplayManagerGlobal;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
+import android.util.LocaleList;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
@@ -34,7 +35,6 @@
import android.view.DisplayAdjustments;
import java.lang.ref.WeakReference;
-import java.util.Locale;
/** @hide */
public class ResourcesManager {
@@ -284,8 +284,9 @@
}
// set it for java, this also affects newly created Resources
- if (config.locale != null) {
- Locale.setDefault(config.locale);
+ final LocaleList localeList = config.getLocales();
+ if (!localeList.isEmpty()) {
+ LocaleList.setDefault(localeList);
}
Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 5b5bba4..f103576 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.IntDef;
import android.annotation.RawRes;
import android.annotation.SystemApi;
import android.content.ComponentName;
@@ -60,6 +61,8 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
/**
@@ -144,7 +147,33 @@
* and y arguments are the location of the drop.
*/
public static final String COMMAND_DROP = "android.home.drop";
-
+
+ /**
+ * Extra passed back from setWallpaper() giving the new wallpaper's assigned ID.
+ * @hide
+ */
+ public static final String EXTRA_NEW_WALLPAPER_ID = "android.service.wallpaper.extra.ID";
+
+ // flags for which kind of wallpaper to set
+
+ /** @hide */
+ @IntDef(flag = true, value = {
+ FLAG_SET_SYSTEM,
+ FLAG_SET_LOCK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SetWallpaperFlags {}
+
+ /**
+ * Flag: use the supplied imagery as the general system wallpaper.
+ */
+ public static final int FLAG_SET_SYSTEM = 1 << 0;
+
+ /**
+ * Flag: use the supplied imagery as the lock-screen wallpaper.
+ */
+ public static final int FLAG_SET_LOCK = 1 << 1;
+
private final Context mContext;
/**
@@ -717,20 +746,41 @@
* wallpaper.
*/
public void setResource(@RawRes int resid) throws IOException {
+ setResource(resid, FLAG_SET_SYSTEM);
+ }
+
+ /**
+ * Version of {@link #setResource(int)} that takes an optional Bundle for returning
+ * metadata about the operation to the caller.
+ *
+ * @param resid
+ * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+ *
+ * @see #FLAG_SET_LOCK
+ * @see #FLAG_SET_SYSTEM
+ *
+ * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+ *
+ * @throws IOException
+ */
+ public int setResource(@RawRes int resid, @SetWallpaperFlags int which)
+ throws IOException {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
- return;
+ return 0;
}
+ final Bundle result = new Bundle();
try {
Resources resources = mContext.getResources();
/* Set the wallpaper to the default values */
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(
- "res:" + resources.getResourceName(resid), mContext.getOpPackageName());
+ "res:" + resources.getResourceName(resid),
+ mContext.getOpPackageName(), result, which);
if (fd != null) {
FileOutputStream fos = null;
try {
fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- setWallpaper(resources.openRawResource(resid), fos);
+ copyStreamToWallpaperFile(resources.openRawResource(resid), fos);
} finally {
IoUtils.closeQuietly(fos);
}
@@ -738,6 +788,7 @@
} catch (RemoteException e) {
// Ignore
}
+ return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
/**
@@ -753,7 +804,7 @@
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#SET_WALLPAPER}.
*
- * @param bitmap The bitmap to save.
+ * @param bitmap The bitmap to be used as the new system wallpaper.
*
* @throws IOException If an error occurs when attempting to set the wallpaper
* to the provided image.
@@ -775,42 +826,72 @@
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#SET_WALLPAPER}.
*
- * @param fullImage A bitmap that will supply the wallpaper imagery.
+ * @param fullImage A bitmap that will supply the wallpaper imagery.
* @param visibleCropHint The rectangular subregion of {@code fullImage} that should be
* displayed as wallpaper. Passing {@code null} for this parameter means that
* the full image should be displayed if possible given the image's and device's
- * aspect ratios, etc.
+ * aspect ratios, etc.
* @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
* image for restore to a future device; {@code false} otherwise.
*
+ * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+ *
* @throws IOException If an error occurs when attempting to set the wallpaper
* to the provided image.
* @throws IllegalArgumentException If the {@code visibleCropHint} rectangle is
* empty or invalid.
*/
- public void setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup)
+ public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup)
+ throws IOException {
+ return setBitmap(fullImage, visibleCropHint, allowBackup, FLAG_SET_SYSTEM);
+ }
+
+ /**
+ /**
+ * Version of {@link #setBitmap(Bitmap, Rect, boolean)} that allows the caller
+ * to specify which of the supported wallpaper categories to set.
+ *
+ * @param fullImage A bitmap that will supply the wallpaper imagery.
+ * @param visibleCropHint The rectangular subregion of {@code fullImage} that should be
+ * displayed as wallpaper. Passing {@code null} for this parameter means that
+ * the full image should be displayed if possible given the image's and device's
+ * aspect ratios, etc.
+ * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+ * image for restore to a future device; {@code false} otherwise.
+ * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+ *
+ * @see #FLAG_SET_LOCK_WALLPAPER
+ * @see #FLAG_SET_SYSTEM_WALLPAPER
+ *
+ * @return An integer ID assigned to the newly active wallpaper; or zero on failure.
+ *
+ * @throws IOException
+ */
+ public int setBitmap(Bitmap fullImage, Rect visibleCropHint,
+ boolean allowBackup, @SetWallpaperFlags int which)
throws IOException {
validateRect(visibleCropHint);
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
- return;
+ return 0;
}
+ final Bundle result = new Bundle();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
- mContext.getOpPackageName());
- if (fd == null) {
- return;
- }
- FileOutputStream fos = null;
- try {
- fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
- } finally {
- IoUtils.closeQuietly(fos);
+ mContext.getOpPackageName(), result, which);
+ if (fd != null) {
+ FileOutputStream fos = null;
+ try {
+ fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+ fullImage.compress(Bitmap.CompressFormat.PNG, 90, fos);
+ } finally {
+ IoUtils.closeQuietly(fos);
+ }
}
} catch (RemoteException e) {
// Ignore
}
+ return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
private final void validateRect(Rect rect) {
@@ -843,7 +924,7 @@
setStream(bitmapData, null, true);
}
- private void setWallpaper(InputStream data, FileOutputStream fos)
+ private void copyStreamToWallpaperFile(InputStream data, FileOutputStream fos)
throws IOException {
byte[] buffer = new byte[32768];
int amt;
@@ -877,29 +958,55 @@
* @throws IllegalArgumentException If the {@code visibleCropHint} rectangle is
* empty or invalid.
*/
- public void setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup)
+ public int setStream(InputStream bitmapData, Rect visibleCropHint, boolean allowBackup)
throws IOException {
+ return setStream(bitmapData, visibleCropHint, allowBackup, FLAG_SET_SYSTEM);
+ }
+
+ /**
+ * Version of {@link #setStream(InputStream, Rect, boolean)} that allows the caller
+ * to specify which of the supported wallpaper categories to set.
+ *
+ * @param bitmapData A stream containing the raw data to install as a wallpaper.
+ * @param visibleCropHint The rectangular subregion of the streamed image that should be
+ * displayed as wallpaper. Passing {@code null} for this parameter means that
+ * the full image should be displayed if possible given the image's and device's
+ * aspect ratios, etc.
+ * @param allowBackup {@code true} if the OS is permitted to back up this wallpaper
+ * image for restore to a future device; {@code false} otherwise.
+ * @param which Flags indicating which wallpaper(s) to configure with the new imagery.
+ *
+ * @see #FLAG_SET_LOCK_WALLPAPER
+ * @see #FLAG_SET_SYSTEM_WALLPAPER
+ *
+ * @throws IOException
+ */
+ public int setStream(InputStream bitmapData, Rect visibleCropHint,
+ boolean allowBackup, @SetWallpaperFlags int which)
+ throws IOException {
validateRect(visibleCropHint);
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
- return;
+ return 0;
}
+ final Bundle result = new Bundle();
try {
ParcelFileDescriptor fd = sGlobals.mService.setWallpaper(null,
- mContext.getOpPackageName());
- if (fd == null) {
- return;
- }
- FileOutputStream fos = null;
- try {
- fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
- setWallpaper(bitmapData, fos);
- } finally {
- IoUtils.closeQuietly(fos);
+ mContext.getOpPackageName(), result, which);
+ if (fd != null) {
+ FileOutputStream fos = null;
+ try {
+ fos = new ParcelFileDescriptor.AutoCloseOutputStream(fd);
+ copyStreamToWallpaperFile(bitmapData, fos);
+ } finally {
+ IoUtils.closeQuietly(fos);
+ }
}
} catch (RemoteException e) {
// Ignore
}
+
+ return result.getInt(EXTRA_NEW_WALLPAPER_ID, 0);
}
/**
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1e7512d..381ea90 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -41,6 +41,7 @@
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Environment;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -3186,6 +3187,38 @@
public static final String
ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
+ /**
+ * Activity Action: Give access to a standard storage directory after obtaining the user's
+ * approval.
+ * <p>
+ * When invoked, the system will ask the user to grant access to the requested directory (and
+ * its descendants).
+ * <p>
+ * To gain access to descendant (child, grandchild, etc) documents, use
+ * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)} and
+ * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} with the returned URI.
+ * <p>
+ * Input: full path to a standard directory, in the form of
+ * {@code STORAGE_ROOT + STANDARD_DIRECTORY}, where {@code STORAGE_ROOT} is the physical path of
+ * a storage container, and {@code STANDARD_DIRECTORY} is one of
+ * {@link Environment#DIRECTORY_MUSIC}, {@link Environment#DIRECTORY_PODCASTS},
+ * {@link Environment#DIRECTORY_RINGTONES}, {@link Environment#DIRECTORY_ALARMS},
+ * {@link Environment#DIRECTORY_NOTIFICATIONS}, {@link Environment#DIRECTORY_PICTURES},
+ * {@link Environment#DIRECTORY_MOVIES}, {@link Environment#DIRECTORY_DOWNLOADS},
+ * {@link Environment#DIRECTORY_DCIM}, or {@link Environment#DIRECTORY_DOCUMENTS}
+ * <p>
+ * For example, to open the "Pictures" folder in the default external storage, the intent's data
+ * would be: {@code Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
+ * Environment.DIRECTORY_PICTURES))}.
+ * <p>
+ * Output: The URI representing the requested directory tree.
+ *
+ * @see DocumentsContract
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String
+ ACTION_OPEN_EXTERNAL_DIRECTORY = "android.intent.action.OPEN_EXTERNAL_DIRECTORY";
+
/** {@hide} */
public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index bb0a04f..2695dfd 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -743,6 +743,26 @@
new Key<int[]>("android.control.availableModes", int[].class);
/**
+ * <p>Range of boosts for {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} supported
+ * by this camera device.</p>
+ * <p>Devices support post RAW sensitivity boost will advertise
+ * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost} key for controling
+ * post RAW sensitivity boost.</p>
+ * <p>This key will be <code>null</code> for devices that do not support any RAW format
+ * outputs. For devices that do support RAW format outputs, this key will always
+ * present, and if a device does not support post RAW sensitivity boost, it will
+ * list <code>(100, 100)</code> in this key.</p>
+ * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+ * @see CaptureRequest#SENSOR_SENSITIVITY
+ */
+ @PublicKey
+ public static final Key<android.util.Range<Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE =
+ new Key<android.util.Range<Integer>>("android.control.postRawSensitivityBoostRange", new TypeReference<android.util.Range<Integer>>() {{ }});
+
+ /**
* <p>List of edge enhancement modes for {@link CaptureRequest#EDGE_MODE android.edge.mode} that are supported by this camera
* device.</p>
* <p>Full-capability camera devices must always support OFF; camera devices that support
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 67835a0..c3cae65 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1590,6 +1590,41 @@
new Key<Integer>("android.control.videoStabilizationMode", int.class);
/**
+ * <p>The amount of additional sesnsitivity boost applied to output images
+ * after RAW sensor data is captured.</p>
+ * <p>Some camera devices support additional digital sensitivity boosting in the
+ * camera processing pipeline after sensor RAW image is captured.
+ * Such a boost will be applied to YUV/JPEG format output images but will not
+ * have effect on RAW output formats like RAW_SENSOR, RAW10, RAW12 or RAW_OPAQUE.</p>
+ * <p>This key is optional. Applications can assume there is no boost applied
+ * after RAW is captured if this key is not available.
+ * When this key is available, the sensitivity boost value must be within
+ * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost}.</p>
+ * <p>If the camera device cannot apply the exact boost requested, it will reduce the
+ * boost to the nearest supported value.
+ * The final boost value used will be available in the output capture result.</p>
+ * <p>For devices that support post RAW sensitivity boost, the YUV/JPEG output images
+ * of such device will have the total sensitivity of
+ * <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} * android.control.ispSensitivity / 100</code>
+ * The sensitivity of RAW format images will always be <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</code></p>
+ * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+ * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+ * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_MODE
+ * @see CaptureRequest#CONTROL_MODE
+ * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+ * @see CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE
+ * @see CaptureRequest#SENSOR_SENSITIVITY
+ */
+ @PublicKey
+ public static final Key<Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST =
+ new Key<Integer>("android.control.postRawSensitivityBoost", int.class);
+
+ /**
* <p>Operation mode for edge
* enhancement.</p>
* <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -2244,6 +2279,8 @@
* requested, it will reduce the gain to the nearest supported
* value. The final sensitivity used will be available in the
* output capture result.</p>
+ * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+ * OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: ISO arithmetic units</p>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</p>
@@ -2252,6 +2289,8 @@
* Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
+ * @see CaptureRequest#CONTROL_AE_MODE
+ * @see CaptureRequest#CONTROL_MODE
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
* @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3c2d503..7b9d1a3 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2097,6 +2097,41 @@
new Key<Integer>("android.control.videoStabilizationMode", int.class);
/**
+ * <p>The amount of additional sesnsitivity boost applied to output images
+ * after RAW sensor data is captured.</p>
+ * <p>Some camera devices support additional digital sensitivity boosting in the
+ * camera processing pipeline after sensor RAW image is captured.
+ * Such a boost will be applied to YUV/JPEG format output images but will not
+ * have effect on RAW output formats like RAW_SENSOR, RAW10, RAW12 or RAW_OPAQUE.</p>
+ * <p>This key is optional. Applications can assume there is no boost applied
+ * after RAW is captured if this key is not available.
+ * When this key is available, the sensitivity boost value must be within
+ * {@link CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST android.control.postRawSensitivityBoost}.</p>
+ * <p>If the camera device cannot apply the exact boost requested, it will reduce the
+ * boost to the nearest supported value.
+ * The final boost value used will be available in the output capture result.</p>
+ * <p>For devices that support post RAW sensitivity boost, the YUV/JPEG output images
+ * of such device will have the total sensitivity of
+ * <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} * android.control.ispSensitivity / 100</code>
+ * The sensitivity of RAW format images will always be <code>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</code></p>
+ * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+ * OFF; otherwise the auto-exposure algorithm will override this value.</p>
+ * <p><b>Units</b>: ISO arithmetic units, the same as {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</p>
+ * <p><b>Range of valid values:</b><br>
+ * {@link CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE android.control.postRawSensitivityBoostRange}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AE_MODE
+ * @see CaptureRequest#CONTROL_MODE
+ * @see CaptureRequest#CONTROL_POST_RAW_SENSITIVITY_BOOST
+ * @see CameraCharacteristics#CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE
+ * @see CaptureRequest#SENSOR_SENSITIVITY
+ */
+ @PublicKey
+ public static final Key<Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST =
+ new Key<Integer>("android.control.postRawSensitivityBoost", int.class);
+
+ /**
* <p>Operation mode for edge
* enhancement.</p>
* <p>Edge enhancement improves sharpness and details in the captured image. OFF means
@@ -3086,6 +3121,8 @@
* requested, it will reduce the gain to the nearest supported
* value. The final sensitivity used will be available in the
* output capture result.</p>
+ * <p>This control is only effective if {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} is set to
+ * OFF; otherwise the auto-exposure algorithm will override this value.</p>
* <p><b>Units</b>: ISO arithmetic units</p>
* <p><b>Range of valid values:</b><br>
* {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</p>
@@ -3094,6 +3131,8 @@
* Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
*
+ * @see CaptureRequest#CONTROL_AE_MODE
+ * @see CaptureRequest#CONTROL_MODE
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
* @see CameraCharacteristics#SENSOR_MAX_ANALOG_SENSITIVITY
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 5d969b1..c4ee347 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -25,6 +25,8 @@
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.PointerIcon;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
/** @hide */
interface IInputManager {
@@ -59,6 +61,11 @@
String keyboardLayoutDescriptor);
void removeKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
String keyboardLayoutDescriptor);
+ KeyboardLayout getKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
+ in InputMethodInfo imeInfo, in InputMethodSubtype imeSubtype);
+ void setKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
+ in InputMethodInfo imeInfo, in InputMethodSubtype imeSubtype,
+ String keyboardLayoutDescriptor);
// Registers an input devices changed listener.
void registerInputDevicesChangedListener(IInputDevicesChangedListener listener);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 9972f49..cbe3412 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,7 +16,7 @@
package android.hardware.input;
-import android.view.PointerIcon;
+import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
@@ -40,6 +40,9 @@
import android.util.SparseArray;
import android.view.InputDevice;
import android.view.InputEvent;
+import android.view.PointerIcon;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -643,6 +646,51 @@
}
}
+
+ /**
+ * Gets the keyboard layout for the specified input device and IME subtype.
+ *
+ * @param identifier The identifier for the input device.
+ * @param inputMethodInfo The input method.
+ * @param inputMethodSubtype The input method subtype.
+ *
+ * @return The associated {@link KeyboardLayout}, or null if one has not been set.
+ *
+ * @hide
+ */
+ public KeyboardLayout getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
+ InputMethodInfo inputMethodInfo, InputMethodSubtype inputMethodSubtype) {
+ try {
+ return mIm.getKeyboardLayoutForInputDevice(
+ identifier, inputMethodInfo, inputMethodSubtype);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not set keyboard layout.", ex);
+ return null;
+ }
+ }
+
+ /**
+ * Sets the keyboard layout for the specified input device and IME subtype pair.
+ *
+ * @param identifier The identifier for the input device.
+ * @param inputMethodInfo The input method with which to associate the keyboard layout.
+ * @param inputMethodSubtype The input method subtype which which to associate the keyboard
+ * layout.
+ * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to set
+ *
+ * @hide
+ */
+ public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
+ InputMethodInfo inputMethodInfo, InputMethodSubtype inputMethodSubtype,
+ String keyboardLayoutDescriptor) {
+ try {
+ mIm.setKeyboardLayoutForInputDevice(identifier, inputMethodInfo,
+ inputMethodSubtype, keyboardLayoutDescriptor);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not set keyboard layout.", ex);
+ }
+ }
+
/**
* Gets the TouchCalibration applied to the specified input device's coordinates.
*
diff --git a/core/java/android/hardware/input/TouchCalibration.java b/core/java/android/hardware/input/TouchCalibration.java
index 025fad0..15503ed 100644
--- a/core/java/android/hardware/input/TouchCalibration.java
+++ b/core/java/android/hardware/input/TouchCalibration.java
@@ -123,4 +123,10 @@
Float.floatToIntBits(mYScale) ^
Float.floatToIntBits(mYOffset);
}
+
+ @Override
+ public String toString() {
+ return String.format("[%f, %f, %f, %f, %f, %f]",
+ mXScale, mXYMix, mXOffset, mYXMix, mYScale, mYOffset);
+ }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index c4f0847..5584cde 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -16,7 +16,7 @@
package android.net;
import static com.android.internal.util.Preconditions.checkNotNull;
-
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -49,6 +49,8 @@
import libcore.net.event.NetworkEventDispatcher;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -512,6 +514,7 @@
private final Context mContext;
private INetworkManagementService mNMService;
+ private INetworkPolicyManager mNPManager;
/**
* Tests if a given integer represents a valid network type.
@@ -3025,4 +3028,58 @@
return NetworkUtils.bindProcessToNetworkForHostResolution(
network == null ? NETID_UNSET : network.netId);
}
+
+ /**
+ * Device is not restricting metered network activity while application is running on
+ * background.
+ */
+ public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1;
+
+ /**
+ * Device is restricting metered network activity while application is running on background,
+ * but application is allowed to bypass it.
+ * <p>
+ * In this state, application should take action to mitigate metered network access.
+ * For example, a music streaming application should switch to a low-bandwidth bitrate.
+ */
+ public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2;
+
+ /**
+ * Device is restricting metered network activity while application is running on background.
+ * In this state, application should not try to use the network while running on background,
+ * because it would be denied.
+ */
+ public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3;
+
+ @IntDef(flag = false, value = {
+ RESTRICT_BACKGROUND_STATUS_DISABLED,
+ RESTRICT_BACKGROUND_STATUS_WHITELISTED,
+ RESTRICT_BACKGROUND_STATUS_ENABLED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RestrictBackgroundStatus {
+ }
+
+ private INetworkPolicyManager getNetworkPolicyManager() {
+ synchronized (this) {
+ if (mNPManager != null) {
+ return mNPManager;
+ }
+ mNPManager = INetworkPolicyManager.Stub.asInterface(ServiceManager
+ .getService(Context.NETWORK_POLICY_SERVICE));
+ return mNPManager;
+ }
+ }
+
+ /**
+ * Determines if the calling application is subject to metered network restrictions while
+ * running on background.
+ */
+ public @RestrictBackgroundStatus int getRestrictBackgroundStatus() {
+ try {
+ return getNetworkPolicyManager().getRestrictBackgroundByCaller();
+ } catch (RemoteException e) {
+ return RESTRICT_BACKGROUND_STATUS_DISABLED;
+ }
+ }
}
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 06aa616..a57fac3 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -56,6 +56,12 @@
void addRestrictBackgroundWhitelistedUid(int uid);
void removeRestrictBackgroundWhitelistedUid(int uid);
int[] getRestrictBackgroundWhitelistedUids();
+ /** Gets the restrict background status based on the caller's UID:
+ 1 - disabled
+ 2 - whitelisted
+ 3 - enabled
+ */
+ int getRestrictBackgroundByCaller();
void setDeviceIdleMode(boolean enabled);
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 2ca9ab8a..ba215bb 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -390,7 +390,7 @@
* type.
*/
public static String DIRECTORY_MUSIC = "Music";
-
+
/**
* Standard directory in which to place any audio files that should be
* in the list of podcasts that the user can select (not as regular
@@ -479,6 +479,37 @@
public static String DIRECTORY_DOCUMENTS = "Documents";
/**
+ * List of standard storage directories.
+ * <p>
+ * Each of its values have its own constant:
+ * <ul>
+ * <li>{@link #DIRECTORY_MUSIC}
+ * <li>{@link #DIRECTORY_PODCASTS}
+ * <li>{@link #DIRECTORY_ALARMS}
+ * <li>{@link #DIRECTORY_RINGTONES}
+ * <li>{@link #DIRECTORY_NOTIFICATIONS}
+ * <li>{@link #DIRECTORY_PICTURES}
+ * <li>{@link #DIRECTORY_MOVIES}
+ * <li>{@link #DIRECTORY_DOWNLOADS}
+ * <li>{@link #DIRECTORY_DCIM}
+ * <li>{@link #DIRECTORY_DOCUMENTS}
+ * </ul>
+ * @hide
+ */
+ public static final String[] STANDARD_DIRECTORIES = {
+ DIRECTORY_MUSIC,
+ DIRECTORY_PODCASTS,
+ DIRECTORY_RINGTONES,
+ DIRECTORY_ALARMS,
+ DIRECTORY_NOTIFICATIONS,
+ DIRECTORY_PICTURES,
+ DIRECTORY_MOVIES,
+ DIRECTORY_DOWNLOADS,
+ DIRECTORY_DCIM,
+ DIRECTORY_DOCUMENTS
+ };
+
+ /**
* Get a top-level shared/external storage directory for placing files of a
* particular type. This is where the user will typically place and manage
* their own files, so you should be careful about what you put here to
@@ -495,13 +526,13 @@
* </p>
* {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
* public_picture}
- *
+ *
* @param type The type of storage directory to return. Should be one of
* {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS},
* {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS},
* {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES},
- * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, or
- * {@link #DIRECTORY_DCIM}. May not be null.
+ * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS},
+ * {@link #DIRECTORY_DCIM}, or {@link #DIRECTORY_DOCUMENTS}. May not be null.
* @return Returns the File path for the directory. Note that this directory
* may not yet exist, so you must make sure it exists before using
* it such as with {@link File#mkdirs File.mkdirs()}.
@@ -657,7 +688,7 @@
/**
* Returns the current state of the primary shared/external storage media.
- *
+ *
* @see #getExternalStorageDirectory()
* @return one of {@link #MEDIA_UNKNOWN}, {@link #MEDIA_REMOVED},
* {@link #MEDIA_UNMOUNTED}, {@link #MEDIA_CHECKING},
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index a401ac2..88cc8a2 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -62,7 +62,7 @@
* All client apps must hold a valid URI permission grant to access documents,
* typically issued when a user makes a selection through
* {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT},
- * or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}.
+ * {@link Intent#ACTION_OPEN_DOCUMENT_TREE}, or {@link Intent#ACTION_OPEN_EXTERNAL_DIRECTORY}.
*
* @see DocumentsProvider
*/
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index ebe3f47..4f58626 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -70,6 +70,10 @@
}
public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
+ if (si == null) {
+ mParseError = "Service not available";
+ return;
+ }
if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
mParseError = "Service does not require permission "
+ Manifest.permission.BIND_VOICE_INTERACTION;
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 1a5de7e..1703ed1 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -186,8 +186,8 @@
/**
* Initiate the drag operation itself
*/
- boolean performDrag(IWindow window, IBinder dragToken, float touchX, float touchY,
- float thumbCenterX, float thumbCenterY, in ClipData data);
+ boolean performDrag(IWindow window, IBinder dragToken, int touchSource,
+ float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data);
/**
* Report the result of a drop action targeted to the given window.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b5b0baa..fff141a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24,6 +24,7 @@
import android.annotation.FloatRange;
import android.annotation.IdRes;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -20058,7 +20059,7 @@
root.getLastTouchPoint(shadowSize);
okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, mAttachInfo.mDragToken,
- shadowSize.x, shadowSize.y,
+ root.getLastTouchSource(), shadowSize.x, shadowSize.y,
shadowTouchPoint.x, shadowTouchPoint.y, data);
if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
}
@@ -21563,6 +21564,11 @@
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
+ /** @hide */
+ @IntDef({UNSPECIFIED, EXACTLY, AT_MOST})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MeasureSpecMode {}
+
/**
* Measure specification mode: The parent has not imposed any constraint
* on the child. It can be whatever size it wants.
@@ -21603,7 +21609,8 @@
* @param mode the mode of the measure specification
* @return the measure specification based on size and mode
*/
- public static int makeMeasureSpec(int size, int mode) {
+ public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
+ @MeasureSpecMode int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
@@ -21632,7 +21639,9 @@
* {@link android.view.View.MeasureSpec#AT_MOST} or
* {@link android.view.View.MeasureSpec#EXACTLY}
*/
+ @MeasureSpecMode
public static int getMode(int measureSpec) {
+ //noinspection ResourceType
return (measureSpec & MODE_MASK);
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 7b53697..27e2ea3 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1659,10 +1659,9 @@
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
- final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
- PointF point = getLocalPoint();
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
+ final PointF point = getLocalPoint();
if (isTransformedTouchPointInView(x, y, child, point)) {
final PointerIcon pointerIcon = child.getPointerIcon(event, point.x, point.y);
if (pointerIcon != null) {
@@ -1678,6 +1677,22 @@
return super.getPointerIcon(event, x, y);
}
+ private int getAndVerifyPreorderedIndex(int childrenCount, int i, boolean customOrder) {
+ final int childIndex;
+ if (customOrder) {
+ final int childIndex1 = getChildDrawingOrder(childrenCount, i);
+ if (childIndex1 >= childrenCount) {
+ throw new IndexOutOfBoundsException("getChildDrawingOrder() "
+ + "returned invalid index " + childIndex1
+ + " (child count is " + childrenCount + ")");
+ }
+ childIndex = childIndex1;
+ } else {
+ childIndex = i;
+ }
+ return childIndex;
+ }
+
@SuppressWarnings({"ConstantConditions"})
@Override
protected boolean dispatchHoverEvent(MotionEvent event) {
@@ -1705,9 +1720,10 @@
final View[] children = mChildren;
HoverTarget lastHoverTarget = null;
for (int i = childrenCount - 1; i >= 0; i--) {
- int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
+ final int childIndex = getAndVerifyPreorderedIndex(
+ childrenCount, i, customOrder);
+ final View child = getAndVerifyPreorderedView(
+ preorderedList, children, childIndex);
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -1989,9 +2005,8 @@
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
- int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -2138,10 +2153,10 @@
&& isChildrenDrawingOrderEnabled();
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
- final int childIndex = customOrder
- ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
+ final int childIndex = getAndVerifyPreorderedIndex(
+ childrenCount, i, customOrder);
+ final View child = getAndVerifyPreorderedView(
+ preorderedList, children, childIndex);
// If there is a view that has accessibility focus we want it
// to get the event first and if not handled we will perform a
@@ -2319,7 +2334,7 @@
* Resets the cancel next up flag.
* Returns true if the flag was previously set.
*/
- private static boolean resetCancelNextUpFlag(View view) {
+ private static boolean resetCancelNextUpFlag(@NonNull View view) {
if ((view.mPrivateFlags & PFLAG_CANCEL_NEXT_UP_EVENT) != 0) {
view.mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
return true;
@@ -2372,7 +2387,7 @@
* Gets the touch target for specified child view.
* Returns null if not found.
*/
- private TouchTarget getTouchTarget(View child) {
+ private TouchTarget getTouchTarget(@NonNull View child) {
for (TouchTarget target = mFirstTouchTarget; target != null; target = target.next) {
if (target.child == child) {
return target;
@@ -2385,8 +2400,8 @@
* Adds a touch target for specified child to the beginning of the list.
* Assumes the target child is not already present.
*/
- private TouchTarget addTouchTarget(View child, int pointerIdBits) {
- TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
+ private TouchTarget addTouchTarget(@NonNull View child, int pointerIdBits) {
+ final TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
target.next = mFirstTouchTarget;
mFirstTouchTarget = target;
return target;
@@ -2448,7 +2463,7 @@
* Returns true if a child view can receive pointer events.
* @hide
*/
- private static boolean canViewReceivePointerEvents(View child) {
+ private static boolean canViewReceivePointerEvents(@NonNull View child) {
return (child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|| child.getAnimation() != null;
}
@@ -2894,7 +2909,7 @@
for (int i=0; i<childrenCount; i++) {
int childIndex;
try {
- childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
} catch (IndexOutOfBoundsException e) {
childIndex = i;
if (mContext.getApplicationInfo().targetSdkVersion
@@ -2939,9 +2954,10 @@
throw e;
}
}
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
- ViewStructure cstructure = structure.newChild(i);
+
+ final View child = getAndVerifyPreorderedView(
+ preorderedList, children, childIndex);
+ final ViewStructure cstructure = structure.newChild(i);
child.dispatchProvideStructure(cstructure);
}
}
@@ -2949,6 +2965,21 @@
}
}
+ private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList, View[] children,
+ int childIndex) {
+ final View child;
+ if (preorderedList != null) {
+ child = preorderedList.get(childIndex);
+ if (child == null) {
+ throw new RuntimeException("Invalid preorderedList contained null child at index "
+ + childIndex);
+ }
+ } else {
+ child = children[childIndex];
+ }
+ return child;
+ }
+
/** @hide */
@Override
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
@@ -3386,9 +3417,9 @@
transientIndex = -1;
}
}
- int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
- final View child = (preorderedList == null)
- ? children[childIndex] : preorderedList.get(childIndex);
+
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
}
@@ -3508,21 +3539,21 @@
* children.
*/
ArrayList<View> buildOrderedChildList() {
- final int count = mChildrenCount;
- if (count <= 1 || !hasChildWithZ()) return null;
+ final int childrenCount = mChildrenCount;
+ if (childrenCount <= 1 || !hasChildWithZ()) return null;
if (mPreSortedChildren == null) {
- mPreSortedChildren = new ArrayList<View>(count);
+ mPreSortedChildren = new ArrayList<>(childrenCount);
} else {
- mPreSortedChildren.ensureCapacity(count);
+ mPreSortedChildren.ensureCapacity(childrenCount);
}
- final boolean useCustomOrder = isChildrenDrawingOrderEnabled();
- for (int i = 0; i < mChildrenCount; i++) {
+ final boolean customOrder = isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < childrenCount; i++) {
// add next child (in child order) to end of list
- int childIndex = useCustomOrder ? getChildDrawingOrder(mChildrenCount, i) : i;
- View nextChild = mChildren[childIndex];
- float currentZ = nextChild.getZ();
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View nextChild = mChildren[childIndex];
+ final float currentZ = nextChild.getZ();
// insert ahead of any Views with greater Z
int insertIndex = i;
@@ -6059,6 +6090,7 @@
}
break;
}
+ //noinspection ResourceType
return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
}
@@ -7481,7 +7513,11 @@
private TouchTarget() {
}
- public static TouchTarget obtain(View child, int pointerIdBits) {
+ public static TouchTarget obtain(@NonNull View child, int pointerIdBits) {
+ if (child == null) {
+ throw new IllegalArgumentException("child must be non-null");
+ }
+
final TouchTarget target;
synchronized (sRecycleLock) {
if (sRecycleBin == null) {
@@ -7499,6 +7535,10 @@
}
public void recycle() {
+ if (child == null) {
+ throw new IllegalStateException("already recycled once");
+ }
+
synchronized (sRecycleLock) {
if (sRecycledCount < MAX_RECYCLED) {
next = sRecycleBin;
@@ -7528,7 +7568,11 @@
private HoverTarget() {
}
- public static HoverTarget obtain(View child) {
+ public static HoverTarget obtain(@NonNull View child) {
+ if (child == null) {
+ throw new IllegalArgumentException("child must be non-null");
+ }
+
final HoverTarget target;
synchronized (sRecycleLock) {
if (sRecycleBin == null) {
@@ -7536,7 +7580,7 @@
} else {
target = sRecycleBin;
sRecycleBin = target.next;
- sRecycledCount--;
+ sRecycledCount--;
target.next = null;
}
}
@@ -7545,6 +7589,10 @@
}
public void recycle() {
+ if (child == null) {
+ throw new IllegalStateException("already recycled once");
+ }
+
synchronized (sRecycleLock) {
if (sRecycledCount < MAX_RECYCLED) {
next = sRecycleBin;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1bb0311..131ad4c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -339,6 +339,7 @@
volatile Object mLocalDragState;
final PointF mDragPoint = new PointF();
final PointF mLastTouchPoint = new PointF();
+ int mLastTouchSource;
private boolean mProfileRendering;
private Choreographer.FrameCallback mRenderProfiler;
@@ -4122,6 +4123,7 @@
if (event.isTouchEvent()) {
mLastTouchPoint.x = event.getRawX();
mLastTouchPoint.y = event.getRawY();
+ mLastTouchSource = event.getSource();
}
return FORWARD;
}
@@ -5475,6 +5477,10 @@
outLocation.y = (int) mLastTouchPoint.y;
}
+ public int getLastTouchSource() {
+ return mLastTouchSource;
+ }
+
public void setDragFocus(View newDragTarget) {
if (mCurrentDragView != newDragTarget) {
mCurrentDragView = newDragTarget;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4a1142f..6e38b32 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -441,12 +441,6 @@
public int getCameraLensCoverState();
/**
- * Switch the keyboard layout for the given device.
- * Direction should be +1 or -1 to go to the next or previous keyboard layout.
- */
- public void switchKeyboardLayout(int deviceId, int direction);
-
- /**
* Switch the input method, to be precise, input method subtype.
*
* @param forwardDirection {@code true} to rotate in a forward direction.
diff --git a/core/java/android/webkit/ServiceWorkerClient.java b/core/java/android/webkit/ServiceWorkerClient.java
new file mode 100644
index 0000000..85de698
--- /dev/null
+++ b/core/java/android/webkit/ServiceWorkerClient.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+
+public class ServiceWorkerClient {
+
+ /**
+ * Notify the host application of a resource request and allow the
+ * application to return the data. If the return value is null, the
+ * Service Worker will continue to load the resource as usual.
+ * Otherwise, the return response and data will be used.
+ * NOTE: This method is called on a thread other than the UI thread
+ * so clients should exercise caution when accessing private data
+ * or the view system.
+ *
+ * @param request Object containing the details of the request.
+ * @return A {@link android.webkit.WebResourceResponse} containing the
+ * response information or null if the WebView should load the
+ * resource itself.
+ * @see {@link WebViewClient#shouldInterceptRequest()}
+ */
+ public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
+ return null;
+ }
+}
+
diff --git a/core/java/android/webkit/ServiceWorkerController.java b/core/java/android/webkit/ServiceWorkerController.java
new file mode 100644
index 0000000..9115558
--- /dev/null
+++ b/core/java/android/webkit/ServiceWorkerController.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * Manages Service Workers used by WebView.
+ */
+public abstract class ServiceWorkerController {
+
+ /**
+ * Returns the default ServiceWorkerController instance. At present there is
+ * only one ServiceWorkerController instance for all WebView instances,
+ * however this restriction may be relaxed in the future.
+ *
+ * @return The default ServiceWorkerController instance.
+ */
+ @NonNull
+ public static ServiceWorkerController getInstance() {
+ return WebViewFactory.getProvider().getServiceWorkerController();
+ }
+
+ /**
+ * Gets the settings for all service workers.
+ *
+ * @return The current ServiceWorkerWebSettings
+ */
+ @NonNull
+ public abstract ServiceWorkerWebSettings getServiceWorkerWebSettings();
+
+ /**
+ * Sets the client to capture service worker related callbacks.
+ */
+ public abstract void setServiceWorkerClient(@Nullable ServiceWorkerClient client);
+}
+
diff --git a/core/java/android/webkit/ServiceWorkerWebSettings.java b/core/java/android/webkit/ServiceWorkerWebSettings.java
new file mode 100644
index 0000000..8b104d1c
--- /dev/null
+++ b/core/java/android/webkit/ServiceWorkerWebSettings.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+/**
+ * Manages settings state for all Service Workers. These settings are not tied to
+ * the lifetime of any WebView because service workers can outlive WebView instances.
+ * The settings are similar to {@link WebSettings} but only settings relevant to
+ * Service Workers are supported.
+ */
+// This is an abstract base class: concrete ServiceWorkerControllers must
+// create a class derived from this, and return an instance of it in the
+// ServiceWorkerController.getServiceWorkerWebSettings() method implementation.
+public abstract class ServiceWorkerWebSettings {
+
+ /**
+ * Overrides the way the cache is used, see {@link WebSettings#setCacheMode}.
+ *
+ * @param mode the mode to use
+ */
+ public abstract void setCacheMode(int mode);
+
+ /**
+ * Gets the current setting for overriding the cache mode.
+ *
+ * @return the current setting for overriding the cache mode
+ * @see #setCacheMode
+ */
+ public abstract int getCacheMode();
+
+ /**
+ * Enables or disables content URL access from Service Workers, see
+ * {@link WebSettings#setAllowContentAccess}.
+ */
+ public abstract void setAllowContentAccess(boolean allow);
+
+ /**
+ * Gets whether Service Workers support content URL access.
+ *
+ * @see #setAllowContentAccess
+ */
+ public abstract boolean getAllowContentAccess();
+
+ /**
+ * Enables or disables file access within Service Workers, see
+ * {@link WebSettings#setAllowFileAccess}.
+ */
+ public abstract void setAllowFileAccess(boolean allow);
+
+ /**
+ * Gets whether Service Workers support file access.
+ *
+ * @see #setAllowFileAccess
+ */
+ public abstract boolean getAllowFileAccess();
+
+ /**
+ * Sets whether the Service Workers should not load resources from the network,
+ * see {@link WebSettings#setBlockNetworkLoads}.
+ *
+ * @param flag whether the Service Workers should not load any resources from the
+ * network
+ */
+ public abstract void setBlockNetworkLoads(boolean flag);
+
+ /**
+ * Gets whether Service Workers are prohibited from loading any resources from the network.
+ *
+ * @return true if the Service Workers are not allowed to load any resources from the network
+ * @see #setBlockNetworkLoads
+ */
+ public abstract boolean getBlockNetworkLoads();
+}
+
diff --git a/core/java/android/webkit/TokenBindingService.java b/core/java/android/webkit/TokenBindingService.java
index f11ce51..f7caac7 100644
--- a/core/java/android/webkit/TokenBindingService.java
+++ b/core/java/android/webkit/TokenBindingService.java
@@ -38,6 +38,21 @@
public static final String KEY_ALGORITHM_ECDSAP256 = "ECDSAP256";
/**
+ * Provides the KeyPair information.
+ */
+ public static abstract class TokenBindingKey {
+ /**
+ * The public, private key pair.
+ */
+ public abstract KeyPair getKeyPair();
+
+ /**
+ * The algorithm that is used to generate the key pair.
+ */
+ public abstract String getAlgorithm();
+ }
+
+ /**
* Returns the default TokenBinding service instance. At present there is
* only one token binding service instance for all WebView instances,
* however this restriction may be relaxed in the future.
@@ -59,16 +74,25 @@
/**
* Retrieves the key pair for a given origin from the internal
* TokenBinding key store asynchronously.
- * Will create a key pair if one does not exist.
+ *
+ * The user can provide a list of acceptable algorithms for the retrieved
+ * key pair. If a key pair exists and it is in the list of algorithms, then
+ * the key is returned. If it is not in the list, no key is returned.
+ *
+ * If no key pair exists, WebView chooses an algorithm from the list, in
+ * the order given, to generate a key.
+ *
+ * The user can pass a null if any algorithm is acceptable.
*
* @param origin The origin for the server.
- * @param algorithm The algorithm for generating the token binding key.
+ * @param algorithm The list of algorithms. Can be null. An
+ * IllegalArgumentException is thrown if array is empty.
* @param callback The callback that will be called when key is available.
* Cannot be null.
*/
public abstract void getKey(Uri origin,
- String algorithm,
- ValueCallback<KeyPair> callback);
+ String[] algorithm,
+ ValueCallback<TokenBindingKey> callback);
/**
* Deletes specified key (for use when associated cookie is cleared).
*
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 054eafc..b04b4c0 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -295,15 +295,27 @@
Application initialApplication = AppGlobals.getInitialApplication();
Context webViewContext = null;
- Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "initialApplication.createPackageContext()");
+ Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "PackageManager.getApplicationInfo()");
try {
// Construct a package context to load the Java code into the current app.
// This is done as early as possible since by constructing a package context we
// register the WebView package as a dependency for the current application so that
// when the WebView package is updated this application will be killed.
- webViewContext = initialApplication.createPackageContext(
- sPackageInfo.packageName,
- Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ ApplicationInfo applicationInfo =
+ initialApplication.getPackageManager().getApplicationInfo(
+ sPackageInfo.packageName, PackageManager.GET_SHARED_LIBRARY_FILES
+ | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
+ // make sure that we fetch the current provider even if its not installed
+ // for the current user
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW,
+ "initialApplication.createApplicationContext");
+ try {
+ webViewContext = initialApplication.createApplicationContext(applicationInfo,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
+ }
} catch (PackageManager.NameNotFoundException e) {
throw new MissingWebViewPackageException(e);
} finally {
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 2b66a83..8359a10 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -111,6 +111,14 @@
TokenBindingService getTokenBindingService();
/**
+ * Gets the ServiceWorkerController instance for this WebView implementation. The
+ * implementation must return the same instance on subsequent calls.
+ *
+ * @return the ServiceWorkerController instance
+ */
+ ServiceWorkerController getServiceWorkerController();
+
+ /**
* Gets the singleton WebIconDatabase instance for this WebView implementation. The
* implementation must return the same instance on subsequent calls.
*
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeHandle.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeHandle.java
new file mode 100644
index 0000000..975021e8
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeHandle.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.inputmethod;
+
+import android.text.TextUtils;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.Objects;
+
+public class InputMethodSubtypeHandle {
+ private final String mInputMethodId;
+ private final int mSubtypeId;
+
+ public InputMethodSubtypeHandle(InputMethodInfo info, InputMethodSubtype subtype) {
+ mInputMethodId = info.getId();
+ if (subtype != null) {
+ mSubtypeId = subtype.hashCode();
+ } else {
+ mSubtypeId = 0;
+ }
+ }
+
+ public InputMethodSubtypeHandle(String inputMethodId, int subtypeId) {
+ mInputMethodId = inputMethodId;
+ mSubtypeId = subtypeId;
+ }
+
+ public String getInputMethodId() {
+ return mInputMethodId;
+ }
+
+ public int getSubtypeId() {
+ return mSubtypeId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof InputMethodSubtypeHandle)) {
+ return false;
+ }
+ InputMethodSubtypeHandle other = (InputMethodSubtypeHandle) o;
+ return TextUtils.equals(mInputMethodId, other.getInputMethodId())
+ && mSubtypeId == other.getSubtypeId();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(mInputMethodId) * 31 + mSubtypeId;
+ }
+
+ @Override
+ public String toString() {
+ return "InputMethodSubtypeHandle{mInputMethodId=" + mInputMethodId
+ + ", mSubtypeId=" + mSubtypeId + "}";
+ }
+}
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
index 5b776ac..3f6ebb9 100644
--- a/core/java/com/android/internal/os/KernelCpuSpeedReader.java
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -16,8 +16,11 @@
package com.android.internal.os;
import android.text.TextUtils;
+import android.system.OsConstants;
import android.util.Slog;
+import libcore.io.Libcore;
+
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -29,7 +32,7 @@
*
* freq time
*
- * where time is measured in 1/100 seconds.
+ * where time is measured in jiffies.
*/
public class KernelCpuSpeedReader {
private static final String TAG = "KernelCpuSpeedReader";
@@ -38,6 +41,9 @@
private final long[] mLastSpeedTimes;
private final long[] mDeltaSpeedTimes;
+ // How long a CPU jiffy is in milliseconds.
+ private final long mJiffyMillis;
+
/**
* @param cpuNumber The cpu (cpu0, cpu1, etc) whose state to read.
*/
@@ -46,6 +52,8 @@
cpuNumber);
mLastSpeedTimes = new long[numSpeedSteps];
mDeltaSpeedTimes = new long[numSpeedSteps];
+ long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
+ mJiffyMillis = 1000/jiffyHz;
}
/**
@@ -62,8 +70,7 @@
splitter.setString(line);
Long.parseLong(splitter.next());
- // The proc file reports time in 1/100 sec, so convert to milliseconds.
- long time = Long.parseLong(splitter.next()) * 10;
+ long time = Long.parseLong(splitter.next()) * mJiffyMillis;
if (time < mLastSpeedTimes[speedIndex]) {
// The stats reset when the cpu hotplugged. That means that the time
// we read is offset from 0, so the time is the delta.
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index bf97f1f..d831902 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -67,10 +67,10 @@
static final int PROCESS_STAT_UTIME = 2;
static final int PROCESS_STAT_STIME = 3;
- /** Stores user time and system time in 100ths of a second. */
+ /** Stores user time and system time in jiffies. */
private final long[] mProcessStatsData = new long[4];
- /** Stores user time and system time in 100ths of a second. Used for
+ /** Stores user time and system time in jiffies. Used for
* public API to retrieve CPU use for a process. Must lock while in use. */
private final long[] mSinglePidStatsData = new long[4];
diff --git a/core/res/res/drawable/ic_notification_alert.xml b/core/res/res/drawable/ic_notification_alert.xml
index d17dfc1..c8514ac 100644
--- a/core/res/res/drawable/ic_notification_alert.xml
+++ b/core/res/res/drawable/ic_notification_alert.xml
@@ -20,14 +20,14 @@
android:viewportHeight="24.0">
<path
android:pathData="M18.4,2.2L17.0,3.6c2.0,1.4 3.3,3.7 3.5,6.4l2.0,0.0C22.3,6.8 20.8,4.0 18.4,2.2z"
- android:fillColor="#231F20"/>
+ android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M7.1,3.6L5.7,2.2C3.3,4.0 1.7,6.8 1.5,10.0l2.0,0.0C3.7,7.3 5.0,5.0 7.1,3.6z"
- android:fillColor="#231F20"/>
+ android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M18.5,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.5,3.5C13.5,2.7 12.8,2.0 12.0,2.0s-1.5,0.7 -1.5,1.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.5,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.5,10.5zM13.0,16.5l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,16.5zM13.0,12.5l-2.0,0.0l0.0,-6.0l2.0,0.0L13.0,12.5z"
- android:fillColor="#231F20"/>
+ android:fillColor="#FFFFFFFF"/>
<path
android:pathData="M12.0,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0L10.0,20.0C10.0,21.1 10.9,22.0 12.0,22.0z"
- android:fillColor="#231F20"/>
+ android:fillColor="#FFFFFFFF"/>
</vector>
diff --git a/core/res/res/drawable/ic_notification_block.xml b/core/res/res/drawable/ic_notification_block.xml
index 27690740..572e97b 100644
--- a/core/res/res/drawable/ic_notification_block.xml
+++ b/core/res/res/drawable/ic_notification_block.xml
@@ -20,6 +20,6 @@
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="#FFFFFFFF"
android:pathData="M12.0,2.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0zM4.0,12.0c0.0,-4.42 3.58,-8.0 8.0,-8.0 1.85,0.0 3.5,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4.0,13.85 4.0,12.0zm8.0,8.0c-1.85,0.0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20.0,10.15 20.0,12.0c0.0,4.42 -3.58,8.0 -8.0,8.0z"/>
</vector>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index eebdd61..d7f7b10 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -492,17 +492,17 @@
current device state, to send as an e-mail message. It will take a little
time from starting the bug report until it is ready to be sent; please be
patient.</string>
- <!-- Title in the bugreport dialog for the interactive workflow. [CHAR LIMIT=20] -->
+ <!-- Title in the bugreport dialog for the interactive workflow. Should fit in one line. [CHAR LIMIT=30] -->
<string name="bugreport_option_interactive_title">Interactive report</string>
<!-- Summary in the bugreport dialog for the interactive workflow. [CHAR LIMIT=NONE] -->
<string name="bugreport_option_interactive_summary">Use this under most circumstances.
It allows you to track progress of the report and enter more details about the problem.
It might omit some less-used sections that take a long time to report.</string>
- <!-- Title in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
+ <!-- Title in the bugreport dialog for the full workflow. Should fit in one line. [CHAR LIMIT=30] -->
<string name="bugreport_option_full_title">Full report</string>
- <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=20] -->
- <string name="bugreport_option_full_summary">Use this option for minimal interference when
- your device is unresponsive or too slow, or when you need all sections.
+ <!-- Summary in the bugreport dialog for the full workflow. [CHAR LIMIT=NONE] -->
+ <string name="bugreport_option_full_summary">Use this option for minimal system interference when
+ your device is unresponsive or too slow, or when you need all report sections.
Does not take a screenshot or allow you to enter more details.</string>
<!-- Toast message informing user in how many seconds a bugreport screenshot will be taken -->
<plurals name="bugreport_countdown">
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 77d2ada..5a08887 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -78,10 +78,10 @@
<shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
<!-- Germany: 4-5 digits plus 1232xxx (premium codes from http://www.vodafone.de/infofaxe/537.pdf and http://premiumdienste.eplus.de/pdf/kodex.pdf), plus EU. To keep the premium regex from being too large, it only includes payment processors that have been used by SMS malware, with the regular pattern matching the other premium short codes. -->
- <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215|47529" />
+ <shortcode country="de" pattern="\\d{4,5}|1232\\d{3}" premium="11(?:111|833)|1232(?:013|021|060|075|286|358)|118(?:44|80|86)|20[25]00|220(?:21|22|88|99)|221(?:14|21)|223(?:44|53|77)|224[13]0|225(?:20|59|90)|226(?:06|10|20|26|30|40|56|70)|227(?:07|33|39|66|76|78|79|88|99)|228(?:08|11|66|77)|23300|30030|3[12347]000|330(?:33|55|66)|33(?:233|331|366|533)|34(?:34|567)|37000|40(?:040|123|444|[3568]00)|41(?:010|414)|44(?:000|044|344|44[24]|544)|50005|50100|50123|50555|51000|52(?:255|783)|54(?:100|2542)|55(?:077|[24]00|222|333|55|[12369]55)|56(?:789|886)|60800|6[13]000|66(?:[12348]66|566|766|777|88|999)|68888|70(?:07|123|777)|76766|77(?:007|070|222|444|[567]77)|80(?:008|123|888)|82(?:002|[378]00|323|444|472|474|488|727)|83(?:005|[169]00|333|830)|84(?:141|300|32[34]|343|488|499|777|888)|85888|86(?:188|566|640|644|650|677|868|888)|870[24]9|871(?:23|[49]9)|872(?:1[0-8]|49|99)|87499|875(?:49|55|99)|876(?:0[1367]|1[1245678]|54|99)|877(?:00|99)|878(?:15|25|3[567]|8[12])|87999|880(?:08|44|55|77|99)|88688|888(?:03|10|8|89)|8899|90(?:009|999)|99999" free="116\\d{3}|81214|81215|47529|70296" />
<!-- Denmark: see http://iprs.webspacecommerce.com/Denmark-Premium-Rate-Numbers -->
- <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}" />
+ <shortcode country="dk" pattern="\\d{4,5}" premium="1\\d{3}" free="116\\d{3}|4665" />
<!-- Estonia: short codes 3-5 digits starting with 1, plus premium 7 digit numbers starting with 90, plus EU.
http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
@@ -102,7 +102,7 @@
<!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
visual voicemail code for EE: 887 -->
- <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|887" />
+ <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|887|83669|34664|40406" />
<!-- Georgia: 4 digits, known premium codes listed -->
<shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
@@ -114,6 +114,9 @@
http://clients.txtnation.com/entries/209633-hungary-premium-sms-short-code-regulations -->
<shortcode country="hu" pattern="[01](?:\\d{3}|\\d{9})" premium="0691227910|1784" free="116\\d{3}" />
+ <!-- Indonesia -->
+ <shortcode country="id" free="99477|6006|46645" />
+
<!-- Ireland: 5 digits, 5xxxx (50xxx=free, 5[12]xxx=standard), plus EU:
http://www.comreg.ie/_fileupload/publications/ComReg1117.pdf -->
<shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" />
@@ -123,7 +126,7 @@
<!-- Italy: 5 digits (premium=4xxxx), plus EU:
http://clients.txtnation.com/attachments/token/di5kfblvubttvlw/?name=Italy_CASP_EN.pdf -->
- <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}" />
+ <shortcode country="it" pattern="\\d{5}" premium="4\\d{4}" free="116\\d{3}|4112503" />
<!-- Japan: 8083 used by SOFTBANK_DCB_2 -->
<shortcode country="jp" free="8083" />
@@ -137,6 +140,9 @@
<!-- Kazakhstan: 4 digits, known premium codes listed: http://smscoin.net/info/pricing-kazakhstan/ -->
<shortcode country="kz" pattern="\\d{4}" premium="335[02]|4161|444[469]|77[2359]0|8444|919[3-5]|968[2-5]" />
+ <!-- Kuwait -->
+ <shortcode country="kw" free="1378|50420|94006" />
+
<!-- Lithuania: 3-5 digits, known premium codes listed, plus EU -->
<shortcode country="lt" pattern="\\d{3,5}" premium="13[89]1|1394|16[34]5" free="116\\d{3}" />
@@ -148,13 +154,13 @@
<shortcode country="lv" pattern="\\d{4}" premium="18(?:19|63|7[1-4])" free="116\\d{3}" />
<!-- Mexico: 4-5 digits (not confirmed), known premium codes listed -->
- <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" />
+ <shortcode country="mx" pattern="\\d{4,5}" premium="53035|7766" free="46645" />
<!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf -->
- <shortcode country="my" pattern="\\d{5}" premium="32298|33776" />
+ <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099" />
<!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
- <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}" />
+ <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223" />
<!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
<shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" />
@@ -163,10 +169,10 @@
<shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" />
<!-- Philippines -->
- <shortcode country="ph" free="2147" />
+ <shortcode country="ph" free="2147|5495|5496" />
<!-- Poland: 4-5 digits (not confirmed), known premium codes listed, plus EU -->
- <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}|8012" />
+ <shortcode country="pl" pattern="\\d{4,5}" premium="74240|79(?:10|866)|92525" free="116\\d{3}|8012|80921" />
<!-- Portugal: 5 digits, plus EU:
http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
@@ -210,4 +216,7 @@
visual voicemail code for T-Mobile: 122 -->
<shortcode country="us" pattern="\\d{5,6}" premium="20433|21(?:344|472)|22715|23(?:333|847)|24(?:15|28)0|25209|27(?:449|606|663)|28498|305(?:00|83)|32(?:340|941)|33(?:166|786|849)|34746|35(?:182|564)|37975|38(?:135|146|254)|41(?:366|463)|42335|43(?:355|500)|44(?:578|711|811)|45814|46(?:157|173|327|654)|46666|47553|48(?:221|277|669)|50(?:844|920)|51(?:062|368)|52944|54(?:723|892)|55928|56483|57370|59(?:182|187|252|342)|60339|61(?:266|982)|62478|64(?:219|898)|65(?:108|500)|69(?:208|388)|70877|71851|72(?:078|087|465)|73(?:288|588|882|909|997)|74(?:034|332|815)|76426|79213|81946|83177|84(?:103|685)|85797|86(?:234|236|666)|89616|90(?:715|842|938)|91(?:362|958)|94719|95297|96(?:040|666|835|969)|97(?:142|294|688)|99(?:689|796|807)" free="122|87902" />
+ <!-- Vietnam -->
+ <shortcode country="vn" free="5001" />
+
</shortcodes>
diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h
index 88fecce..d8801b8 100644
--- a/include/androidfw/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -1128,7 +1128,6 @@
// configuration. (eg. Hant, Latn, etc.). Interpreted in conjunction with
// the locale field.
char localeScript[4];
- bool localeScriptWasProvided;
// A single BCP-47 variant subtag. Will vary in length between 4 and 8
// chars. Interpreted in conjunction with the locale field.
@@ -1152,6 +1151,10 @@
uint32_t screenConfig2;
};
+ // If true, it means that the script of the locale was explicitly provided.
+ // If false, it means that the script was automatically computed.
+ bool localeScriptWasProvided;
+
void copyFromDeviceNoSwap(const ResTable_config& o);
void copyFromDtoH(const ResTable_config& o);
diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp
index 99cd173..b8ef9ea4 100644
--- a/libs/androidfw/DisplayEventDispatcher.cpp
+++ b/libs/androidfw/DisplayEventDispatcher.cpp
@@ -103,7 +103,7 @@
int32_t vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
- ALOGE("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
+ ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
diff --git a/libs/hwui/Texture.cpp b/libs/hwui/Texture.cpp
index 92de894..5046d37 100644
--- a/libs/hwui/Texture.cpp
+++ b/libs/hwui/Texture.cpp
@@ -41,9 +41,7 @@
void Texture::setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture, bool force,
GLenum renderTarget) {
- if (mFirstWrap || force || wrapS != mWrapS || wrapT != mWrapT) {
- mFirstWrap = false;
-
+ if (force || wrapS != mWrapS || wrapT != mWrapT) {
mWrapS = wrapS;
mWrapT = wrapT;
@@ -59,9 +57,7 @@
void Texture::setFilterMinMag(GLenum min, GLenum mag, bool bindTexture, bool force,
GLenum renderTarget) {
- if (mFirstFilter || force || min != mMinFilter || mag != mMagFilter) {
- mFirstFilter = false;
-
+ if (force || min != mMinFilter || mag != mMagFilter) {
mMinFilter = min;
mMagFilter = mag;
@@ -92,14 +88,21 @@
return true;
}
+void Texture::resetCachedParams() {
+ mWrapS = GL_REPEAT;
+ mWrapT = GL_REPEAT;
+ mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+ mMagFilter = GL_LINEAR;
+}
+
void Texture::upload(GLint internalformat, uint32_t width, uint32_t height,
GLenum format, GLenum type, const void* pixels) {
GL_CHECKPOINT();
- mCaches.textureState().activateTexture(0);
bool needsAlloc = updateSize(width, height, internalformat);
if (!mId) {
glGenTextures(1, &mId);
needsAlloc = true;
+ resetCachedParams();
}
mCaches.textureState().bindTexture(GL_TEXTURE_2D, mId);
if (needsAlloc) {
@@ -207,10 +210,12 @@
// If the texture had mipmap enabled but not anymore,
// force a glTexImage2D to discard the mipmap levels
bool needsAlloc = canMipMap && mipMap && !bitmap.hasHardwareMipMap();
+ bool setDefaultParams = false;
if (!mId) {
glGenTextures(1, &mId);
needsAlloc = true;
+ setDefaultParams = true;
}
GLint format, type;
@@ -245,11 +250,8 @@
}
}
- if (mFirstFilter) {
+ if (setDefaultParams) {
setFilter(GL_NEAREST);
- }
-
- if (mFirstWrap) {
setWrap(GL_CLAMP_TO_EDGE);
}
}
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 4e8e6dc..9749f73 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -149,26 +149,22 @@
// Returns true if the size changed, false if it was the same
bool updateSize(uint32_t width, uint32_t height, GLint format);
+ void resetCachedParams();
GLuint mId = 0;
uint32_t mWidth = 0;
uint32_t mHeight = 0;
GLint mFormat = 0;
- /**
- * Last wrap modes set on this texture.
+ /* See GLES spec section 3.8.14
+ * "In the initial state, the value assigned to TEXTURE_MIN_FILTER is
+ * NEAREST_MIPMAP_LINEAR and the value for TEXTURE_MAG_FILTER is LINEAR.
+ * s, t, and r wrap modes are all set to REPEAT."
*/
- GLenum mWrapS = GL_CLAMP_TO_EDGE;
- GLenum mWrapT = GL_CLAMP_TO_EDGE;
-
- /**
- * Last filters set on this texture.
- */
- GLenum mMinFilter = GL_NEAREST;
- GLenum mMagFilter = GL_NEAREST;
-
- bool mFirstFilter = true;
- bool mFirstWrap = true;
+ GLenum mWrapS = GL_REPEAT;
+ GLenum mWrapT = GL_REPEAT;
+ GLenum mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
+ GLenum mMagFilter = GL_LINEAR;
Caches& mCaches;
}; // struct Texture
diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp
index 98c94df..54f38e8 100644
--- a/libs/hwui/renderstate/OffscreenBufferPool.cpp
+++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp
@@ -41,6 +41,7 @@
, texture(caches) {
uint32_t width = computeIdealDimension(viewportWidth);
uint32_t height = computeIdealDimension(viewportHeight);
+ caches.textureState().activateTexture(0);
texture.resize(width, height, GL_RGBA);
texture.blend = true;
texture.setWrap(GL_CLAMP_TO_EDGE);
diff --git a/packages/DocumentsUI/res/drawable/cabinet.png b/packages/DocumentsUI/res/drawable/cabinet.png
new file mode 100644
index 0000000..da44023
--- /dev/null
+++ b/packages/DocumentsUI/res/drawable/cabinet.png
Binary files differ
diff --git a/packages/DocumentsUI/res/layout/dialog_create_dir.xml b/packages/DocumentsUI/res/layout/dialog_file_name.xml
similarity index 100%
rename from packages/DocumentsUI/res/layout/dialog_create_dir.xml
rename to packages/DocumentsUI/res/layout/dialog_file_name.xml
diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml
index 1b5911d..223d729 100644
--- a/packages/DocumentsUI/res/layout/fragment_directory.xml
+++ b/packages/DocumentsUI/res/layout/fragment_directory.xml
@@ -36,8 +36,8 @@
android:background="@color/material_grey_50"
android:visibility="gone"/>
- <!-- The empty directory view -->
- <LinearLayout
+ <!-- The empty container view -->
+ <FrameLayout
android:id="@android:id/empty"
android:gravity="center"
android:layout_width="match_parent"
@@ -45,21 +45,34 @@
android:orientation="vertical"
android:visibility="gone">
- <TextView
- android:id="@+id/message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/empty"
- style="@android:style/TextAppearance.Material.Subhead" />
+ <LinearLayout
+ android:id="@+id/content"
+ android:gravity="center"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
- <Button
- android:id="@+id/button_retry"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/button_retry"
- style="?android:attr/buttonBarPositiveButtonStyle" />
+ <ImageView
+ android:id="@+id/artwork"
+ android:src="@drawable/cabinet"
+ android:adjustViewBounds="true"
+ android:layout_height="250dp"
+ android:layout_width="fill_parent"
+ android:alpha="1"
+ android:layout_centerVertical="true"
+ android:layout_marginBottom="25dp"
+ android:scaleType="fitCenter"
+ android:contentDescription="@null" />
- </LinearLayout>
+ <TextView
+ android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/empty"
+ style="@android:style/TextAppearance.Material.Subhead" />
+
+ </LinearLayout>
+ </FrameLayout>
<!-- This FrameLayout works around b/24189541 -->
<FrameLayout
diff --git a/packages/DocumentsUI/res/menu/mode_directory.xml b/packages/DocumentsUI/res/menu/mode_directory.xml
index 4ff396f..6f9bfb5 100644
--- a/packages/DocumentsUI/res/menu/mode_directory.xml
+++ b/packages/DocumentsUI/res/menu/mode_directory.xml
@@ -48,4 +48,9 @@
android:title="@string/menu_move"
android:showAsAction="never"
android:visible="false" />
+ <item
+ android:id="@+id/menu_rename"
+ android:title="@string/menu_rename"
+ android:showAsAction="never"
+ android:visible="false" />
</menu>
diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml
index 05c43b2..8ac228e 100644
--- a/packages/DocumentsUI/res/values/strings.xml
+++ b/packages/DocumentsUI/res/values/strings.xml
@@ -123,6 +123,8 @@
<!-- Text shown when a directory of documents is empty [CHAR LIMIT=24] -->
<string name="empty">No items</string>
+ <!-- Text shown when a file search returns no items [CHAR LIMIT=32] -->
+ <string name="no_results">No matches in %1$s</string>
<!-- Toast shown when no app can be found to open the selected document [CHAR LIMIT=48] -->
<string name="toast_no_application">Can\'t open file</string>
@@ -176,7 +178,7 @@
<item quantity="other">Couldn\'t delete <xliff:g id="count" example="2">%1$d</xliff:g> files</item>
</plurals>
<!-- Second line for notifications saying that more information will be shown after touching [CHAR LIMIT=48] -->
- <string name="notification_touch_for_details">Touch to view details</string>
+ <string name="notification_touch_for_details">Tap to view details</string>
<!-- Label of a dialog button for retrying a failed operation [CHAR LIMIT=24] -->
<string name="retry">Retry</string>
<!-- Contents of the copying failure alert dialog. [CHAR LIMIT=48] -->
@@ -190,4 +192,8 @@
</plurals>
<!-- Toast shown when a user tries to paste files into an unsupported location. -->
<string name="clipboard_files_cannot_paste">Cannot paste the selected files in this location.</string>
+ <!-- Menu item that renames the selected document [CHAR LIMIT=24] -->
+ <string name="menu_rename">Rename</string>
+ <!-- Toast shown when renaming document failed with an error [CHAR LIMIT=48] -->
+ <string name="rename_error">Failed to rename document</string>
</resources>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 0fb8daf..f43b81c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -437,7 +437,7 @@
DirectoryFragment.get(getFragmentManager()).onUserModeChanged();
}
- void setPending(boolean pending) {
+ public void setPending(boolean pending) {
final SaveFragment save = SaveFragment.get(getFragmentManager());
if (save != null) {
save.setPending(pending);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index f3c3f2f..df036b9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -63,7 +63,7 @@
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
- final View view = dialogInflater.inflate(R.layout.dialog_create_dir, null, false);
+ final View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
final EditText editText = (EditText) view.findViewById(android.R.id.text1);
builder.setTitle(R.string.menu_create_dir);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index ba96b0e..809db31 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -28,6 +28,7 @@
import static com.android.internal.util.Preconditions.checkState;
import static com.google.common.base.Preconditions.checkArgument;
+import android.annotation.StringRes;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Fragment;
@@ -92,6 +93,7 @@
import com.android.documentsui.RecentLoader;
import com.android.documentsui.RecentsProvider;
import com.android.documentsui.RecentsProvider.StateColumns;
+import com.android.documentsui.dirlist.RenameDocumentFragment;
import com.android.documentsui.RootsCache;
import com.android.documentsui.Shared;
import com.android.documentsui.Snackbars;
@@ -131,6 +133,7 @@
private static final int LOADER_ID = 42;
private static final int DELETE_UNDO_TIMEOUT = 5000;
private static final int DELETE_JOB_DELAY = 5500;
+ private static final int EMPTY_REVEAL_DURATION = 250;
private static final String EXTRA_TYPE = "type";
private static final String EXTRA_ROOT = "root";
@@ -167,63 +170,6 @@
private MessageBar mMessageBar;
private View mProgressBar;
- public static void showDirectory(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
- show(fm, TYPE_NORMAL, root, doc, null, anim);
- }
-
- public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) {
- show(fm, TYPE_SEARCH, root, null, query, anim);
- }
-
- public static void showRecentsOpen(FragmentManager fm, int anim) {
- show(fm, TYPE_RECENT_OPEN, null, null, null, anim);
- }
-
- private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc,
- String query, int anim) {
- final Bundle args = new Bundle();
- args.putInt(EXTRA_TYPE, type);
- args.putParcelable(EXTRA_ROOT, root);
- args.putParcelable(EXTRA_DOC, doc);
- args.putString(EXTRA_QUERY, query);
-
- final FragmentTransaction ft = fm.beginTransaction();
- switch (anim) {
- case ANIM_SIDE:
- args.putBoolean(EXTRA_IGNORE_STATE, true);
- break;
- case ANIM_DOWN:
- args.putBoolean(EXTRA_IGNORE_STATE, true);
- ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen);
- break;
- case ANIM_UP:
- ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up);
- break;
- }
-
- final DirectoryFragment fragment = new DirectoryFragment();
- fragment.setArguments(args);
-
- ft.replace(R.id.container_directory, fragment);
- ft.commitAllowingStateLoss();
- }
-
- private static String buildStateKey(RootInfo root, DocumentInfo doc) {
- final StringBuilder builder = new StringBuilder();
- builder.append(root != null ? root.authority : "null").append(';');
- builder.append(root != null ? root.rootId : "null").append(';');
- builder.append(doc != null ? doc.documentId : "null");
- return builder.toString();
- }
-
- public static @Nullable DirectoryFragment get(FragmentManager fm) {
- // TODO: deal with multiple directories shown at once
- Fragment fragment = fm.findFragmentById(R.id.container_directory);
- return fragment instanceof DirectoryFragment
- ? (DirectoryFragment) fragment
- : null;
- }
-
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -614,6 +560,7 @@
private Selection mSelected = new Selection();
private ActionMode mActionMode;
private int mNoDeleteCount = 0;
+ private int mNoRenameCount = -1;
private Menu mMenu;
@Override
@@ -637,6 +584,9 @@
if ((docFlags & Document.FLAG_SUPPORTS_DELETE) == 0) {
mNoDeleteCount += selected ? 1 : -1;
}
+ if ((docFlags & Document.FLAG_SUPPORTS_RENAME) != 0) {
+ mNoRenameCount += selected ? 1 : -1;
+ }
}
@Override
@@ -675,6 +625,7 @@
mSelectionManager.clearSelection();
mSelected.clear();
mNoDeleteCount = 0;
+ mNoRenameCount = -1;
}
@Override
@@ -692,10 +643,19 @@
return true;
}
+ boolean canRenameSelection() {
+ return mNoRenameCount == 0 && mSelectionManager.getSelection().size() == 1;
+ }
+
+ boolean canDeleteSelection() {
+ return mNoDeleteCount == 0;
+ }
+
private void updateActionMenu() {
checkNotNull(mMenu);
+
// Delegate update logic to our owning action, since specialized logic is desired.
- mTuner.updateActionMenu(mMenu, mType, mNoDeleteCount == 0);
+ mTuner.updateActionMenu(mMenu, mType, canDeleteSelection(), canRenameSelection());
Menus.disableHiddenItems(mMenu);
}
@@ -735,6 +695,7 @@
case R.id.menu_copy_to_clipboard:
if (!selection.isEmpty()) {
copySelectionToClipboard(selection);
+ mode.finish();
}
return true;
@@ -742,6 +703,11 @@
selectAllFiles();
return true;
+ case R.id.menu_rename:
+ renameDocuments(selection);
+ mode.finish();
+ return true;
+
default:
if (DEBUG) Log.d(TAG, "Unhandled menu item selected: " + item);
return false;
@@ -889,6 +855,19 @@
}.execute(selected);
}
+ private void renameDocuments(Selection selected) {
+ // Batch renaming not supported
+ // Rename option is only available in menu when 1 document selected
+ checkArgument(selected.size() == 1);
+
+ new GetDocumentsTask() {
+ @Override
+ void onDocumentsReady(List<DocumentInfo> docs) {
+ RenameDocumentFragment.show(getFragmentManager(), docs.get(0));
+ }
+ }.execute(selected);
+ }
+
@Override
public void initDocumentHolder(DocumentHolder holder) {
holder.addEventListener(mItemEventListener);
@@ -917,25 +896,43 @@
return mTuner.isDocumentEnabled(docMimeType, docFlags);
}
- void showEmptyView() {
- mEmptyView.setVisibility(View.VISIBLE);
- mRecView.setVisibility(View.GONE);
- TextView msg = (TextView) mEmptyView.findViewById(R.id.message);
- msg.setText(R.string.empty);
- // No retry button for the empty view.
- mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE);
+ private void showEmptyDirectory() {
+ showEmptyView(R.string.empty);
}
- void showErrorView() {
- mEmptyView.setVisibility(View.VISIBLE);
- mRecView.setVisibility(View.GONE);
- TextView msg = (TextView) mEmptyView.findViewById(R.id.message);
- msg.setText(R.string.query_error);
- // TODO: Enable this once the retry button does something.
- mEmptyView.findViewById(R.id.button_retry).setVisibility(View.GONE);
+ private void showNoResults(RootInfo root) {
+ CharSequence msg = getContext().getResources().getText(R.string.no_results);
+ showEmptyView(String.format(String.valueOf(msg), root.title));
}
- void showRecyclerView() {
+ // Shows an error indicating documents couldn't be queried.
+ private void showQueryError() {
+ showEmptyView(R.string.query_error);
+ }
+
+ private void showEmptyView(@StringRes int id) {
+ showEmptyView(getContext().getResources().getText(id));
+ }
+
+ private void showEmptyView(CharSequence msg) {
+ View content = mEmptyView.findViewById(R.id.content);
+ TextView msgView = (TextView) mEmptyView.findViewById(R.id.message);
+ msgView.setText(msg);
+
+ content.animate().cancel(); // cancel any ongoing animations
+
+ content.setAlpha(0);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecView.setVisibility(View.GONE);
+
+ // fade in the content, so it looks purdy like
+ content.animate()
+ .alpha(1f)
+ .setDuration(EMPTY_REVEAL_DURATION)
+ .setListener(null);
+ }
+
+ private void showDirectory() {
mEmptyView.setVisibility(View.GONE);
mRecView.setVisibility(View.VISIBLE);
}
@@ -1300,16 +1297,20 @@
mProgressBar.setVisibility(model.isLoading() ? View.VISIBLE : View.GONE);
if (model.isEmpty()) {
- showEmptyView();
+ if (getDisplayState().currentSearch != null) {
+ showNoResults(getDisplayState().stack.root);
+ } else {
+ showEmptyDirectory();
+ }
} else {
- showRecyclerView();
+ showDirectory();
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onModelUpdateFailed(Exception e) {
- showErrorView();
+ showQueryError();
}
}
@@ -1419,4 +1420,62 @@
}
}
}
+
+ public static void showDirectory(
+ FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
+ show(fm, TYPE_NORMAL, root, doc, null, anim);
+ }
+
+ public static void showSearch(FragmentManager fm, RootInfo root, String query, int anim) {
+ show(fm, TYPE_SEARCH, root, null, query, anim);
+ }
+
+ public static void showRecentsOpen(FragmentManager fm, int anim) {
+ show(fm, TYPE_RECENT_OPEN, null, null, null, anim);
+ }
+
+ private static void show(FragmentManager fm, int type, RootInfo root, DocumentInfo doc,
+ String query, int anim) {
+ final Bundle args = new Bundle();
+ args.putInt(EXTRA_TYPE, type);
+ args.putParcelable(EXTRA_ROOT, root);
+ args.putParcelable(EXTRA_DOC, doc);
+ args.putString(EXTRA_QUERY, query);
+
+ final FragmentTransaction ft = fm.beginTransaction();
+ switch (anim) {
+ case ANIM_SIDE:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ break;
+ case ANIM_DOWN:
+ args.putBoolean(EXTRA_IGNORE_STATE, true);
+ ft.setCustomAnimations(R.animator.dir_down, R.animator.dir_frozen);
+ break;
+ case ANIM_UP:
+ ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_up);
+ break;
+ }
+
+ final DirectoryFragment fragment = new DirectoryFragment();
+ fragment.setArguments(args);
+
+ ft.replace(R.id.container_directory, fragment);
+ ft.commitAllowingStateLoss();
+ }
+
+ private static String buildStateKey(RootInfo root, DocumentInfo doc) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(root != null ? root.authority : "null").append(';');
+ builder.append(root != null ? root.rootId : "null").append(';');
+ builder.append(doc != null ? doc.documentId : "null");
+ return builder.toString();
+ }
+
+ public static @Nullable DirectoryFragment get(FragmentManager fm) {
+ // TODO: deal with multiple directories shown at once
+ Fragment fragment = fm.findFragmentById(R.id.container_directory);
+ return fragment instanceof DirectoryFragment
+ ? (DirectoryFragment) fragment
+ : null;
+ }
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index ef6d2c9..a295ab2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -58,7 +58,8 @@
}
- public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete);
+ public abstract void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+ boolean canRename);
// Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
// A folder is enabled such that it may be double clicked, even in settings
@@ -129,7 +130,8 @@
}
@Override
- public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+ boolean canRename) {
boolean copyEnabled = dirType != DirectoryFragment.TYPE_RECENT_OPEN;
boolean moveEnabled =
@@ -141,6 +143,7 @@
final MenuItem delete = menu.findItem(R.id.menu_delete);
final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+ final MenuItem rename = menu.findItem(R.id.menu_rename);
open.setVisible(true);
share.setVisible(false);
@@ -149,6 +152,7 @@
copyTo.setEnabled(copyEnabled);
moveTo.setVisible(moveEnabled);
moveTo.setEnabled(moveEnabled);
+ rename.setVisible(false);
}
}
@@ -162,7 +166,8 @@
}
@Override
- public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+ boolean canRename) {
checkArgument(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
boolean moveEnabled =
@@ -174,6 +179,7 @@
final MenuItem delete = menu.findItem(R.id.menu_delete);
final MenuItem copyTo = menu.findItem(R.id.menu_copy_to);
final MenuItem moveTo = menu.findItem(R.id.menu_move_to);
+ final MenuItem rename = menu.findItem(R.id.menu_rename);
open.setVisible(false);
delete.setVisible(canDelete);
@@ -181,6 +187,7 @@
copyTo.setEnabled(true);
moveTo.setVisible(moveEnabled);
moveTo.setEnabled(moveEnabled);
+ rename.setVisible(false);
}
}
@@ -194,12 +201,17 @@
}
@Override
- public void updateActionMenu(Menu menu, int dirType, boolean canDelete) {
+ public void updateActionMenu(Menu menu, int dirType, boolean canDelete,
+ boolean canRename) {
MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard);
MenuItem paste = menu.findItem(R.id.menu_paste_from_clipboard);
copy.setEnabled(dirType != DirectoryFragment.TYPE_RECENT_OPEN);
+ MenuItem rename = menu.findItem(R.id.menu_rename);
+ rename.setVisible(true);
+ rename.setEnabled(canRename);
+
menu.findItem(R.id.menu_share).setVisible(true);
menu.findItem(R.id.menu_delete).setVisible(canDelete);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
new file mode 100644
index 0000000..71708c1
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/RenameDocumentFragment.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui.dirlist;
+
+import static com.android.documentsui.Shared.TAG;
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
+import android.support.design.widget.Snackbar;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+
+import com.android.documentsui.BaseActivity;
+import com.android.documentsui.DocumentsApplication;
+import com.android.documentsui.model.DocumentInfo;
+import com.android.documentsui.R;
+import com.android.documentsui.Snackbars;
+/**
+ * Dialog to rename file or directory.
+ */
+class RenameDocumentFragment extends DialogFragment {
+ private static final String TAG_RENAME_DOCUMENT = "rename_document";
+ private DocumentInfo mDocument;
+
+ public static void show(FragmentManager fm, DocumentInfo document) {
+ final RenameDocumentFragment dialog = new RenameDocumentFragment();
+ dialog.mDocument = document;
+ dialog.show(fm, TAG_RENAME_DOCUMENT);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Context context = getActivity();
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
+ View view = dialogInflater.inflate(R.layout.dialog_file_name, null, false);
+
+ final EditText editText = (EditText) view.findViewById(android.R.id.text1);
+ editText.setText(mDocument.displayName);
+
+ builder.setTitle(R.string.menu_rename);
+ builder.setView(view);
+
+ builder.setPositiveButton(
+ android.R.string.ok,
+ new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ renameDocuments(editText.getText().toString());
+ }
+ });
+
+ builder.setNegativeButton(android.R.string.cancel, null);
+
+ final AlertDialog dialog = builder.create();
+
+ editText.setOnEditorActionListener(
+ new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(
+ TextView view, int actionId, @Nullable KeyEvent event) {
+ if (event != null
+ && event.getKeyCode() == KeyEvent.KEYCODE_ENTER
+ && event.hasNoModifiers()) {
+ renameDocuments(editText.getText().toString());
+ dialog.dismiss();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ return dialog;
+ }
+
+ private void renameDocuments(String newDisplayName) {
+ BaseActivity activity = (BaseActivity) getActivity();
+
+ new RenameDocumentsTask(activity, newDisplayName).execute(mDocument);
+ }
+
+ private class RenameDocumentsTask extends AsyncTask<DocumentInfo, Void, DocumentInfo> {
+ private final BaseActivity mActivity;
+ private final String mNewDisplayName;
+
+ public RenameDocumentsTask(BaseActivity activity, String newDisplayName) {
+ mActivity = activity;
+ mNewDisplayName = newDisplayName;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ mActivity.setPending(true);
+ }
+
+ @Override
+ protected DocumentInfo doInBackground(DocumentInfo... document) {
+ checkArgument(document.length == 1);
+ final ContentResolver resolver = mActivity.getContentResolver();
+ ContentProviderClient client = null;
+
+ try {
+ client = DocumentsApplication.acquireUnstableProviderOrThrow(
+ resolver, document[0].derivedUri.getAuthority());
+ Uri newUri = DocumentsContract.renameDocument(
+ client, document[0].derivedUri, mNewDisplayName);
+ return DocumentInfo.fromUri(resolver, newUri);
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to rename file", e);
+ return null;
+ } finally {
+ ContentProviderClient.releaseQuietly(client);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(DocumentInfo result) {
+ if (result == null) {
+ Snackbars.makeSnackbar(mActivity, R.string.rename_error, Snackbar.LENGTH_SHORT)
+ .show();
+ }
+
+ mActivity.setPending(false);
+ }
+ }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 83df18c..4b5499a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -239,6 +239,10 @@
return (flags & Document.FLAG_SUPPORTS_DELETE) != 0;
}
+ public boolean isRenameSupported() {
+ return (flags & Document.FLAG_SUPPORTS_RENAME) != 0;
+ }
+
public boolean isGridTitlesHidden() {
return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0;
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
index 1b8bd4e..6c9c5d9 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/SearchViewUiTest.java
@@ -223,7 +223,8 @@
assertFalse(mDocsList.exists());
assertTrue(mMessageTextView.exists());
- assertEquals(mContext.getString(R.string.empty), mMessageTextView.getText());
+ String msg = String.valueOf(mContext.getString(R.string.no_results));
+ assertEquals(String.format(msg, "TEST_ROOT_0"), mMessageTextView.getText());
assertSearchTextField(false, query);
}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index a47d350..cc48786 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
@@ -660,7 +660,7 @@
this.documentId = getDocumentIdForFile(file);
this.mimeType = Document.MIME_TYPE_DIR;
this.streamTypes = new ArrayList<String>();
- this.flags = Document.FLAG_DIR_SUPPORTS_CREATE;
+ this.flags = Document.FLAG_DIR_SUPPORTS_CREATE | Document.FLAG_SUPPORTS_RENAME;
this.parentId = null;
this.rootInfo = rootInfo;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 409f6a7..c7d17dc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -18,6 +18,7 @@
import android.app.Activity;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
+import android.auditing.SecurityLog;
import android.content.Context;
import android.os.UserHandle;
import android.util.AttributeSet;
@@ -423,6 +424,11 @@
}
public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) {
+ if (SecurityLog.isLoggingEnabled()) {
+ SecurityLog.writeEvent(SecurityLog.TAG_DEVICE_UNLOCK_ATTEMPT,
+ (success ? 1 : 0),
+ mCurrentSecuritySelection.name());
+ }
KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
if (success) {
monitor.clearFailedUnlockAttempts();
diff --git a/packages/Shell/res/values/strings.xml b/packages/Shell/res/values/strings.xml
index 1459d53..d992bc3 100644
--- a/packages/Shell/res/values/strings.xml
+++ b/packages/Shell/res/values/strings.xml
@@ -21,6 +21,10 @@
<string name="bugreport_in_progress_title">Bug report is being generated</string>
<!-- Title of notification indicating a bugreport has been successfully captured. [CHAR LIMIT=50] -->
<string name="bugreport_finished_title">Bug report captured</string>
+ <!-- Title of notification indicating a bugreport is being updated before it can be shared. [CHAR LIMIT=50] -->
+ <string name="bugreport_updating_title">Adding details to the bug report</string>
+ <!-- Content notification indicating a bugreport is being updated before it can be shared, asking the user to wait [CHAR LIMIT=50] -->
+ <string name="bugreport_updating_wait">Please wait\u2026</string>
<!-- Text of notification indicating that swipe left will share the captured bugreport. [CHAR LIMIT=100] -->
<string name="bugreport_finished_text" product="watch">Swipe left to share your bug report</string>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 874a946d..5b83796 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -464,6 +464,7 @@
+ info + ")");
return;
}
+ Log.v(TAG, "Sending 'Progress' notification for pid " + info.pid + ": " + percentText);
NotificationManager.from(mContext).notify(TAG, info.pid, notification);
}
@@ -852,7 +853,7 @@
}
/**
- * Sends a notitication indicating the bugreport has finished so use can share it.
+ * Sends a notification indicating the bugreport has finished so use can share it.
*/
private static void sendBugreportNotification(Context context, BugreportInfo info) {
final Intent shareIntent = new Intent(INTENT_BUGREPORT_SHARE);
@@ -878,10 +879,30 @@
builder.setContentInfo(info.name);
}
+ Log.v(TAG, "Sending 'Share' notification for pid " + info.pid + ": " + title);
NotificationManager.from(context).notify(TAG, info.pid, builder.build());
}
/**
+ * Sends a notification indicating the bugreport is being updated so the user can wait until it
+ * finishes - at this point there is nothing to be done other than waiting, hence it has no
+ * pending action.
+ */
+ private static void sendBugreportBeingUpdatedNotification(Context context, int pid) {
+ final String title = context.getString(R.string.bugreport_updating_title);
+ final Notification.Builder builder = new Notification.Builder(context)
+ .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+ .setContentTitle(title)
+ .setTicker(title)
+ .setContentText(context.getString(R.string.bugreport_updating_wait))
+ .setLocalOnly(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color));
+ Log.v(TAG, "Sending 'Updating zip' notification for pid " + pid + ": " + title);
+ NotificationManager.from(context).notify(TAG, pid, builder.build());
+ }
+
+ /**
* Sends a zipped bugreport notification.
*/
private static void sendZippedBugreportNotification(final Context context,
@@ -938,11 +959,13 @@
Log.d(TAG, "Not touching zip file since neither title nor description are set");
return;
}
+
// It's not possible to add a new entry into an existing file, so we need to create a new
// zip, copy all entries, then rename it.
+ sendBugreportBeingUpdatedNotification(mContext, info.pid); // ...and that takes time
final File dir = info.bugreportFile.getParentFile();
final File tmpZip = new File(dir, "tmp-" + info.bugreportFile.getName());
- Log.d(TAG, "Writing temporary zip file (" + tmpZip + ")");
+ Log.d(TAG, "Writing temporary zip file (" + tmpZip + ") with title and/or description");
try (ZipFile oldZip = new ZipFile(info.bugreportFile);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(tmpZip))) {
diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index 03451b4..e550d9c 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -99,7 +99,8 @@
android:src="@*android:drawable/ic_notification_block"
android:layout_gravity="center_vertical|start"
android:layout_width="24dp"
- android:layout_height="24dp" />
+ android:layout_height="24dp"
+ android:tint="@color/notification_guts_icon_tint"/>
<SeekBar
android:id="@+id/seekbar"
@@ -121,7 +122,8 @@
android:src="@*android:drawable/ic_notification_alert"
android:layout_gravity="center_vertical|end"
android:layout_width="24dp"
- android:layout_height="24dp"/>
+ android:layout_height="24dp"
+ android:tint="@color/notification_guts_icon_tint" />
</FrameLayout>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e7fd295..b2190ec 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -100,9 +100,11 @@
<color name="current_user_border_color">@color/system_accent_color</color>
<!-- The "inside" of a notification, reached via longpress -->
- <color name="notification_guts_bg_color">@*android:color/material_grey_50</color>
+ <color name="notification_guts_bg_color">#eeeeee</color>
<color name="notification_guts_slider_color">@*android:color/material_deep_teal_500</color>
<color name="notification_guts_secondary_slider_color">#858383</color>
+ <color name="notification_guts_icon_tint">#8a000000</color>
+ <color name="notification_guts_disabled_icon_tint">#4d000000</color>
<color name="assist_orb_color">#ffffff</color>
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9a00b4b..704de97 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -24,6 +24,7 @@
import android.app.SearchManager;
import android.app.StatusBarManager;
import android.app.trust.TrustManager;
+import android.auditing.SecurityLog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -1352,6 +1353,11 @@
* @see #KEYGUARD_DONE
*/
private void handleKeyguardDone(boolean authenticated) {
+ if (SecurityLog.isLoggingEnabled()
+ && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
+ SecurityLog.writeEvent(SecurityLog.TAG_DEVICE_UNLOCK_ATTEMPT,
+ (authenticated ? 1 : 0), "Unknown");
+ }
if (DEBUG) Log.d(TAG, "handleKeyguardDone");
synchronized (this) {
resetKeyguardDonePendingLocked();
@@ -1463,6 +1469,10 @@
* @see #SHOW
*/
private void handleShow(Bundle options) {
+ if (SecurityLog.isLoggingEnabled()
+ && mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
+ SecurityLog.writeEvent(SecurityLog.TAG_DEVICE_LOCKED, "");
+ }
synchronized (KeyguardViewMediator.this) {
if (!mSystemReady) {
if (DEBUG) Log.d(TAG, "ignoring handleShow because system is not ready.");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 3eee087..f8cbf65 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -651,7 +651,7 @@
mDummyStackView.updateLayoutForStack(stack);
final Task toTask = new Task();
final TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView,
- topTask.id, toTask);
+ toTask);
ForegroundThread.getHandler().postAtFrontOfQueue(new Runnable() {
@Override
public void run() {
@@ -721,7 +721,7 @@
// Update the destination rect
Task toTask = new Task();
TaskViewTransform toTransform = getThumbnailTransitionTransform(stack, stackView,
- topTask.id, toTask);
+ toTask);
RectF toTaskRect = toTransform.rect;
Bitmap thumbnail = getThumbnailBitmap(topTask, toTask, toTransform);
if (thumbnail != null) {
@@ -754,14 +754,14 @@
* Returns the transition rect for the given task id.
*/
private TaskViewTransform getThumbnailTransitionTransform(TaskStack stack,
- TaskStackView stackView, int runningTaskId, Task runningTaskOut) {
+ TaskStackView stackView, Task runningTaskOut) {
// Find the running task in the TaskStack
Task launchTask = stack.getLaunchTarget();
if (launchTask != null) {
runningTaskOut.copyFrom(launchTask);
} else {
// If no task is specified or we can not find the task just use the front most one
- launchTask = stack.getStackFrontMostTask();
+ launchTask = stack.getStackFrontMostTask(true /* includeFreeform */);
runningTaskOut.copyFrom(launchTask);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index c73273e..de1daa8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -527,9 +527,9 @@
*/
public void removeTask(Task t, TaskViewAnimation animation) {
if (mStackTaskList.contains(t)) {
- boolean wasFrontMostTask = (getStackFrontMostTask() == t);
+ boolean wasFrontMostTask = (getStackFrontMostTask(false /* includeFreeform */) == t);
removeTaskImpl(mStackTaskList, t);
- Task newFrontMostTask = getStackFrontMostTask();
+ Task newFrontMostTask = getStackFrontMostTask(false /* includeFreeform */);
if (mCb != null) {
// Notify that a task has been removed
mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask, animation);
@@ -616,14 +616,14 @@
/**
* Gets the front-most task in the stack.
*/
- public Task getStackFrontMostTask() {
+ public Task getStackFrontMostTask(boolean includeFreeformTasks) {
ArrayList<Task> stackTasks = mStackTaskList.getTasks();
if (stackTasks.isEmpty()) {
return null;
}
for (int i = stackTasks.size() - 1; i >= 0; i--) {
Task task = stackTasks.get(i);
- if (!task.isFreeformTask()) {
+ if (!task.isFreeformTask() || includeFreeformTasks) {
return task;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index e99509c..93849dc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -110,6 +110,10 @@
public static final float STATE_FOCUSED = 1f;
public static final float STATE_UNFOCUSED = 0f;
+ public interface TaskStackLayoutAlgorithmCallbacks {
+ void onFocusStateChanged(float prevFocusState, float curFocusState);
+ }
+
/**
* The various stack/freeform states.
*/
@@ -210,6 +214,7 @@
Context mContext;
private Interpolator mLinearOutSlowInInterpolator;
private StackState mState = StackState.SPLIT;
+ private TaskStackLayoutAlgorithmCallbacks mCb;
// The task bounds (untransformed) for layout. This rect is anchored at mTaskRoot.
public Rect mTaskRect = new Rect();
@@ -279,8 +284,10 @@
TaskViewTransform mBackOfStackTransform = new TaskViewTransform();
TaskViewTransform mFrontOfStackTransform = new TaskViewTransform();
- public TaskStackLayoutAlgorithm(Context context) {
+ public TaskStackLayoutAlgorithm(Context context, TaskStackLayoutAlgorithmCallbacks cb) {
Resources res = context.getResources();
+ mContext = context;
+ mCb = cb;
mFocusedRange = new Range(res.getFloat(R.integer.recents_layout_focused_range_min),
res.getFloat(R.integer.recents_layout_focused_range_max));
@@ -291,7 +298,6 @@
mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
- mContext = context;
mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.linear_out_slow_in);
@@ -315,8 +321,12 @@
* Sets the focused state.
*/
public void setFocusState(float focusState) {
+ float prevFocusState = mFocusState;
mFocusState = focusState;
updateFrontBackTransforms();
+ if (mCb != null) {
+ mCb.onFocusStateChanged(prevFocusState, focusState);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 809d4ee..fe9c68e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -88,6 +88,7 @@
/* The visual representation of a task stack view */
public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
TaskView.TaskViewCallbacks, TaskStackViewScroller.TaskStackViewScrollerCallbacks,
+ TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks,
ViewPool.ViewPoolConsumer<TaskView, Task> {
private final static String KEY_SAVED_STATE_SUPER = "saved_instance_state_super";
@@ -192,9 +193,8 @@
setStack(stack);
mViewPool = new ViewPool<>(context, this);
mInflater = LayoutInflater.from(context);
- mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context);
- mStackScroller = new TaskStackViewScroller(context, mLayoutAlgorithm);
- mStackScroller.setCallbacks(this);
+ mLayoutAlgorithm = new TaskStackLayoutAlgorithm(context, this);
+ mStackScroller = new TaskStackViewScroller(context, this, mLayoutAlgorithm);
mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
mAnimationHelper = new TaskStackAnimationHelper(context, this);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -623,7 +623,7 @@
*/
void relayoutTaskViewsOnNextFrame(TaskViewAnimation animation) {
mDeferredTaskViewLayoutAnimation = animation;
- postInvalidateOnAnimation();
+ invalidate();
}
/**
@@ -852,17 +852,17 @@
};
if (scrollToTask) {
+ // Cancel any running enter animations at this point when we scroll or change focus
+ if (!mEnterAnimationComplete) {
+ cancelAllTaskViewAnimations();
+ }
+
// TODO: Center the newly focused task view, only if not freeform
float newScroll = mLayoutAlgorithm.getStackScrollForTask(newFocusedTask);
if (Float.compare(newScroll, mStackScroller.getStackScroll()) != 0) {
mStackScroller.animateScroll(mStackScroller.getStackScroll(), newScroll,
focusTaskRunnable);
willScroll = true;
-
- // Cancel any running enter animations at this point when we scroll as well
- if (!mEnterAnimationComplete) {
- cancelAllTaskViewAnimations();
- }
} else {
focusTaskRunnable.run();
}
@@ -902,7 +902,7 @@
*/
public void setRelativeFocusedTask(boolean forward, boolean stackTasksOnly, boolean animated,
boolean cancelWindowAnimations) {
- setRelativeFocusedTask(forward, stackTasksOnly, animated, false, false);
+ setRelativeFocusedTask(forward, stackTasksOnly, animated, cancelWindowAnimations, false);
}
/**
@@ -1427,7 +1427,8 @@
}
// Restore the action button visibility if it is the front most task view
- if (mScreenPinningEnabled && tv.getTask() == mStack.getStackFrontMostTask()) {
+ if (mScreenPinningEnabled && tv.getTask() ==
+ mStack.getStackFrontMostTask(false /* includeFreeform */)) {
tv.showActionButton(false /* fadeIn */, 0 /* fadeInDuration */);
}
}
@@ -1447,6 +1448,16 @@
}
}
+ /**** TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks ****/
+
+ @Override
+ public void onFocusStateChanged(float prevFocusState, float curFocusState) {
+ if (mDeferredTaskViewLayoutAnimation == null) {
+ mUIDozeTrigger.poke();
+ relayoutTaskViewsOnNextFrame(TaskViewAnimation.IMMEDIATE);
+ }
+ }
+
/**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
index 5335b14..4ec051f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
@@ -20,7 +20,9 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.util.FloatProperty;
import android.util.Log;
+import android.util.Property;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.OverScroller;
@@ -37,6 +39,24 @@
void onScrollChanged(float prevScroll, float curScroll, TaskViewAnimation animation);
}
+ /**
+ * A Property wrapper around the <code>stackScroll</code> functionality handled by the
+ * {@link #setStackScroll(float)} and
+ * {@link #getStackScroll()} methods.
+ */
+ private static final Property<TaskStackViewScroller, Float> STACK_SCROLL =
+ new FloatProperty<TaskStackViewScroller>("stackScroll") {
+ @Override
+ public void setValue(TaskStackViewScroller object, float value) {
+ object.setStackScroll(value);
+ }
+
+ @Override
+ public Float get(TaskStackViewScroller object) {
+ return object.getStackScroll();
+ }
+ };
+
Context mContext;
TaskStackLayoutAlgorithm mLayoutAlgorithm;
TaskStackViewScrollerCallbacks mCb;
@@ -51,8 +71,10 @@
private Interpolator mLinearOutSlowInInterpolator;
- public TaskStackViewScroller(Context context, TaskStackLayoutAlgorithm layoutAlgorithm) {
+ public TaskStackViewScroller(Context context, TaskStackViewScrollerCallbacks cb,
+ TaskStackLayoutAlgorithm layoutAlgorithm) {
mContext = context;
+ mCb = cb;
mScroller = new OverScroller(context);
mLayoutAlgorithm = layoutAlgorithm;
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -64,11 +86,6 @@
mStackScrollP = 0f;
}
- /** Sets the callbacks */
- void setCallbacks(TaskStackViewScrollerCallbacks cb) {
- mCb = cb;
- }
-
/** Gets the current stack scroll */
public float getStackScroll() {
return mStackScrollP;
@@ -172,7 +189,7 @@
stopBoundScrollAnimation();
mFinalAnimatedScroll = newScroll;
- mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll);
+ mScrollAnimator = ObjectAnimator.ofFloat(this, STACK_SCROLL, curScroll, newScroll);
mScrollAnimator.setDuration(mContext.getResources().getInteger(
R.integer.recents_animate_task_stack_scroll_duration));
mScrollAnimator.setInterpolator(mLinearOutSlowInInterpolator);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 52e6a9c..93be009 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -652,8 +652,8 @@
@Override
public void setClipToActualHeight(boolean clipToActualHeight) {
- super.setClipToActualHeight(clipToActualHeight);
- getShowingLayout().setClipToActualHeight(clipToActualHeight);
+ super.setClipToActualHeight(clipToActualHeight || isUserLocked());
+ getShowingLayout().setClipToActualHeight(clipToActualHeight || isUserLocked());
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 52326e3..e4cd7d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -29,6 +29,7 @@
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.View;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.SeekBar;
@@ -133,6 +134,10 @@
} catch (PackageManager.NameNotFoundException e) {
// unlikely.
}
+ if (systemApp) {
+ ((ImageView) row.findViewById(R.id.low_importance)).getDrawable().setTint(
+ mContext.getColor(R.color.notification_guts_disabled_icon_tint));
+ }
final int minProgress = systemApp ?
NotificationListenerService.Ranking.IMPORTANCE_LOW
: NotificationListenerService.Ranking.IMPORTANCE_NONE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 9e66584..839b579 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -393,7 +393,7 @@
}
getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
- getRecentsButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
+ getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
// The app shelf, if it exists, follows the visibility of the home button.
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 b2c03c4..ffc836c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -293,7 +293,7 @@
Display mDisplay;
Point mCurrentDisplaySize = new Point();
- StatusBarWindowView mStatusBarWindow;
+ protected StatusBarWindowView mStatusBarWindow;
PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
protected StatusBarWindowManager mStatusBarWindowManager;
@@ -673,8 +673,7 @@
updateDisplaySize(); // populates mDisplayMetrics
updateResources();
- mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
- R.layout.super_status_bar, null);
+ inflateStatusBarWindow(context);
mStatusBarWindow.setService(this);
mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
@Override
@@ -935,6 +934,11 @@
return mStatusBarView;
}
+ protected void inflateStatusBarWindow(Context context) {
+ mStatusBarWindow = (StatusBarWindowView) View.inflate(context,
+ R.layout.super_status_bar, null);
+ }
+
protected void createNavigationBarView(Context context) {
inflateNavigationBarView(context);
mNavigationBarView.setDisabledFlags(mDisabled1);
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 7eb8005..3668ddd 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -751,6 +751,14 @@
rsnScriptReduce(mContext, id, slot, ain, aout, limits);
}
+ native void rsnScriptReduceNew(long con, long id, int slot, long[] ains,
+ long aout, int[] limits);
+ synchronized void nScriptReduceNew(long id, int slot, long ains[], long aout,
+ int[] limits) {
+ validate();
+ rsnScriptReduceNew(mContext, id, slot, ains, aout, limits);
+ }
+
native void rsnScriptInvokeV(long con, long id, int slot, byte[] params);
synchronized void nScriptInvokeV(long id, int slot, byte[] params) {
validate();
diff --git a/rs/java/android/renderscript/Script.java b/rs/java/android/renderscript/Script.java
index ed4c6c7..84f980d 100644
--- a/rs/java/android/renderscript/Script.java
+++ b/rs/java/android/renderscript/Script.java
@@ -284,7 +284,7 @@
}
/**
- * Only intended for use by generated reflected code.
+ * Only intended for use by generated reflected code. (Simple reduction)
*
* @hide
*/
@@ -312,6 +312,46 @@
mRS.nScriptReduce(getID(mRS), slot, in_id, out_id, limits);
}
+ /**
+ * Only intended for use by generated reflected code. (General reduction)
+ *
+ * @hide
+ */
+ protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
+ mRS.validate();
+ if (ains == null || ains.length < 1) {
+ throw new RSIllegalArgumentException(
+ "At least one input is required.");
+ }
+ if (aout == null) {
+ throw new RSIllegalArgumentException(
+ "aout is required to be non-null.");
+ }
+ for (Allocation ain : ains) {
+ mRS.validateObject(ain);
+ }
+
+ long[] in_ids = new long[ains.length];
+ for (int index = 0; index < ains.length; ++index) {
+ in_ids[index] = ains[index].getID(mRS);
+ }
+ long out_id = aout.getID(mRS);
+
+ int[] limits = null;
+ if (sc != null) {
+ limits = new int[6];
+
+ limits[0] = sc.xstart;
+ limits[1] = sc.xend;
+ limits[2] = sc.ystart;
+ limits[3] = sc.yend;
+ limits[4] = sc.zstart;
+ limits[5] = sc.zend;
+ }
+
+ mRS.nScriptReduceNew(getID(mRS), slot, in_ids, out_id, limits);
+ }
+
long[] mInIdsBuffer;
Script(long id, RenderScript rs) {
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 113241d..3954070 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1988,7 +1988,6 @@
if (sizeof(RsAllocation) == sizeof(jlong)) {
in_allocs = (RsAllocation*)in_ptr;
-
} else {
// Convert from 64-bit jlong types to the native pointer type.
@@ -2127,6 +2126,101 @@
}
}
+static void
+nScriptReduceNew(JNIEnv *_env, jobject _this, jlong con, jlong script, jint slot,
+ jlongArray ains, jlong aout, jintArray limits)
+{
+ if (kLogApi) {
+ ALOGD("nScriptReduceNew, con(%p), s(%p), slot(%i) ains(%p) aout(%" PRId64 ")", (RsContext)con, (void *)script, slot, ains, aout);
+ }
+
+ if (ains == nullptr) {
+ ALOGE("At least one input required.");
+ // TODO (b/20758983): Report back to Java and throw an exception
+ return;
+ }
+ jint in_len = _env->GetArrayLength(ains);
+ if (in_len > (jint)RS_KERNEL_MAX_ARGUMENTS) {
+ ALOGE("Too many arguments in kernel launch.");
+ // TODO (b/20758983): Report back to Java and throw an exception
+ return;
+ }
+
+ jlong *in_ptr = _env->GetLongArrayElements(ains, nullptr);
+ if (in_ptr == nullptr) {
+ ALOGE("Failed to get Java array elements");
+ // TODO (b/20758983): Report back to Java and throw an exception
+ return;
+ }
+
+ RsAllocation *in_allocs = nullptr;
+ if (sizeof(RsAllocation) == sizeof(jlong)) {
+ in_allocs = (RsAllocation*)in_ptr;
+ } else {
+ // Convert from 64-bit jlong types to the native pointer type.
+
+ in_allocs = (RsAllocation*)alloca(in_len * sizeof(RsAllocation));
+ if (in_allocs == nullptr) {
+ ALOGE("Failed launching kernel for lack of memory.");
+ // TODO (b/20758983): Report back to Java and throw an exception
+ _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
+ return;
+ }
+
+ for (int index = in_len; --index >= 0;) {
+ in_allocs[index] = (RsAllocation)in_ptr[index];
+ }
+ }
+
+ RsScriptCall sc, *sca = nullptr;
+ uint32_t sc_size = 0;
+
+ jint limit_len = 0;
+ jint *limit_ptr = nullptr;
+
+ if (limits != nullptr) {
+ limit_len = _env->GetArrayLength(limits);
+ limit_ptr = _env->GetIntArrayElements(limits, nullptr);
+ if (limit_ptr == nullptr) {
+ ALOGE("Failed to get Java array elements");
+ // TODO (b/20758983): Report back to Java and throw an exception
+ return;
+ }
+
+ assert(limit_len == 6);
+ UNUSED(limit_len); // As the assert might not be compiled.
+
+ sc.xStart = limit_ptr[0];
+ sc.xEnd = limit_ptr[1];
+ sc.yStart = limit_ptr[2];
+ sc.yEnd = limit_ptr[3];
+ sc.zStart = limit_ptr[4];
+ sc.zEnd = limit_ptr[5];
+ sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
+ sc.arrayStart = 0;
+ sc.arrayEnd = 0;
+ sc.array2Start = 0;
+ sc.array2End = 0;
+ sc.array3Start = 0;
+ sc.array3End = 0;
+ sc.array4Start = 0;
+ sc.array4End = 0;
+
+ sca = ≻
+ sc_size = sizeof(sc);
+ }
+
+ rsScriptReduceNew((RsContext)con, (RsScript)script, slot,
+ in_allocs, in_len, (RsAllocation)aout,
+ sca, sc_size);
+
+ _env->ReleaseLongArrayElements(ains, in_ptr, JNI_ABORT);
+
+ if (limits != nullptr) {
+ _env->ReleaseIntArrayElements(limits, limit_ptr, JNI_ABORT);
+ }
+}
+
// -----------------------------------
static jlong
@@ -2755,6 +2849,7 @@
{"rsnScriptForEach", "(JJI[JJ[B[I)V", (void*)nScriptForEach },
{"rsnScriptReduce", "(JJIJJ[I)V", (void*)nScriptReduce },
+{"rsnScriptReduceNew", "(JJI[JJ[I)V", (void*)nScriptReduceNew },
{"rsnScriptSetVarI", "(JJII)V", (void*)nScriptSetVarI },
{"rsnScriptGetVarI", "(JJI)I", (void*)nScriptGetVarI },
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index df20704..9927fd6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -171,6 +171,7 @@
private static final boolean VDBG = false;
private static final boolean LOGD_RULES = false;
+ private static final boolean LOGD_BLOCKED_NETWORKINFO = true;
// TODO: create better separation between radio types and network types
@@ -955,6 +956,21 @@
}
}
+ private void maybeLogBlockedNetworkInfo(NetworkInfo ni, int uid) {
+ if (ni == null || !LOGD_BLOCKED_NETWORKINFO) return;
+ boolean removed = false;
+ boolean added = false;
+ synchronized (mBlockedAppUids) {
+ if (ni.getDetailedState() == DetailedState.BLOCKED && mBlockedAppUids.add(uid)) {
+ added = true;
+ } else if (ni.isConnected() && mBlockedAppUids.remove(uid)) {
+ removed = true;
+ }
+ }
+ if (added) log("Returning blocked NetworkInfo to uid=" + uid);
+ else if (removed) log("Returning unblocked NetworkInfo to uid=" + uid);
+ }
+
/**
* Return a filtered {@link NetworkInfo}, potentially marked
* {@link DetailedState#BLOCKED} based on
@@ -965,10 +981,6 @@
// network is blocked; clone and override state
info = new NetworkInfo(info);
info.setDetailedState(DetailedState.BLOCKED, null, null);
- if (VDBG) {
- log("returning Blocked NetworkInfo for ifname=" +
- lp.getInterfaceName() + ", uid=" + uid);
- }
}
if (info != null && mLockdownTracker != null) {
info = mLockdownTracker.augmentNetworkInfo(info);
@@ -989,7 +1001,9 @@
enforceAccessPermission();
final int uid = Binder.getCallingUid();
NetworkState state = getUnfilteredActiveNetworkState(uid);
- return getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo, state.linkProperties, uid);
+ maybeLogBlockedNetworkInfo(ni, uid);
+ return ni;
}
@Override
@@ -3974,6 +3988,9 @@
private final HashMap<Messenger, NetworkAgentInfo> mNetworkAgentInfos =
new HashMap<Messenger, NetworkAgentInfo>();
+ @GuardedBy("mBlockedAppUids")
+ private final HashSet<Integer> mBlockedAppUids = new HashSet();
+
// Note: if mDefaultRequest is changed, NetworkMonitor needs to be updated.
private final NetworkRequest mDefaultRequest;
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 798a04a..4a123df 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -742,6 +742,31 @@
}
}
+ public static final class Lifecycle extends SystemService {
+ private InputMethodManagerService mService;
+
+ public Lifecycle(Context context) {
+ super(context);
+ mService = new InputMethodManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ LocalServices.addService(InputMethodManagerInternal.class,
+ new LocalServiceImpl(mService.mHandler));
+ publishBinderService(Context.INPUT_METHOD_SERVICE, mService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+ StatusBarManagerService statusBarService = (StatusBarManagerService) ServiceManager
+ .getService(Context.STATUS_BAR_SERVICE);
+ mService.systemRunning(statusBarService);
+ }
+ }
+ }
+
public InputMethodManagerService(Context context) {
mIPackageManager = AppGlobals.getPackageManager();
mContext = context;
@@ -894,7 +919,6 @@
}
}
}, filter);
- LocalServices.addService(InputMethodManagerInternal.class, new LocalServiceImpl(mHandler));
}
private void resetDefaultImeLocked(Context context) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index adb11a4..8c2090e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20899,7 +20899,9 @@
}
public boolean isUserStopped(int userId) {
- return mUserController.getStartedUserStateLocked(userId) == null;
+ synchronized (this) {
+ return mUserController.getStartedUserStateLocked(userId) == null;
+ }
}
ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index a3c26cb..05702af 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -77,8 +77,8 @@
}
/**
- * Loads the persistent recentTasks for {@code userId} into {@link #mRecentTasks} from
- * persistent storage. Does nothing if they are already loaded.
+ * Loads the persistent recentTasks for {@code userId} into this list from persistent storage.
+ * Does nothing if they are already loaded.
*
* @param userId the user Id
*/
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index ee91b63..573afd6 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.view.Display;
+import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.os.SomeArgs;
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
@@ -67,6 +68,8 @@
import android.os.MessageQueue;
import android.os.Process;
import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCommand;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -97,6 +100,7 @@
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -157,8 +161,7 @@
private final ArrayList<InputDevice>
mTempFullKeyboards = new ArrayList<InputDevice>(); // handler thread only
private boolean mKeyboardLayoutNotificationShown;
- private PendingIntent mKeyboardLayoutIntent;
- private Toast mSwitchedKeyboardLayoutToast;
+ private InputMethodSubtypeHandle mCurrentImeHandle;
// State for vibrator tokens.
private Object mVibratorLock = new Object();
@@ -1297,6 +1300,82 @@
}
@Override // Binder call
+ @Nullable
+ public KeyboardLayout getKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
+ InputMethodInfo imeInfo, InputMethodSubtype imeSubtype) {
+ InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(imeInfo, imeSubtype);
+ String key = getLayoutDescriptor(identifier);
+ final String keyboardLayoutDescriptor;
+ synchronized (mDataStore) {
+ keyboardLayoutDescriptor = mDataStore.getKeyboardLayout(key, handle);
+ }
+
+ if (keyboardLayoutDescriptor == null) {
+ return null;
+ }
+
+ final KeyboardLayout[] result = new KeyboardLayout[1];
+ visitKeyboardLayout(keyboardLayoutDescriptor, new KeyboardLayoutVisitor() {
+ @Override
+ public void visitKeyboardLayout(Resources resources,
+ int keyboardLayoutResId, KeyboardLayout layout) {
+ result[0] = layout;
+ }
+ });
+ if (result[0] == null) {
+ Slog.w(TAG, "Could not get keyboard layout with descriptor '"
+ + keyboardLayoutDescriptor + "'.");
+ }
+ return result[0];
+ }
+
+ @Override
+ public void setKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
+ InputMethodInfo imeInfo, InputMethodSubtype imeSubtype,
+ String keyboardLayoutDescriptor) {
+ if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT,
+ "setKeyboardLayoutForInputDevice()")) {
+ throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission");
+ }
+ if (keyboardLayoutDescriptor == null) {
+ throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
+ }
+ if (imeInfo == null || imeSubtype == null) {
+ throw new IllegalArgumentException("imeInfo and imeSubtype must not be null");
+ }
+ InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(imeInfo, imeSubtype);
+ setKeyboardLayoutForInputDeviceInner(identifier, handle, keyboardLayoutDescriptor);
+ }
+
+ private void setKeyboardLayoutForInputDeviceInner(InputDeviceIdentifier identifier,
+ InputMethodSubtypeHandle imeHandle, String keyboardLayoutDescriptor) {
+ String key = getLayoutDescriptor(identifier);
+ synchronized (mDataStore) {
+ try {
+ if (mDataStore.setKeyboardLayout(key, imeHandle, keyboardLayoutDescriptor)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Set keyboard layout " + keyboardLayoutDescriptor +
+ " for subtype " + imeHandle + " and device " + identifier +
+ " using key " + key);
+ }
+ if (imeHandle.equals(mCurrentImeHandle)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Layout for current subtype changed, switching layout");
+ }
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = identifier;
+ args.arg2 = imeHandle;
+ mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, args).sendToTarget();
+ }
+ mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
+ }
+ } finally {
+ mDataStore.saveIfNeeded();
+ }
+ }
+ }
+
+ @Override // Binder call
public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
String keyboardLayoutDescriptor) {
if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT,
@@ -1315,8 +1394,7 @@
oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor());
}
if (mDataStore.addKeyboardLayout(key, keyboardLayoutDescriptor)
- && !Objects.equal(oldLayout,
- mDataStore.getCurrentKeyboardLayout(key))) {
+ && !Objects.equal(oldLayout, mDataStore.getCurrentKeyboardLayout(key))) {
mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
}
} finally {
@@ -1366,45 +1444,44 @@
Slog.i(TAG, "InputMethodSubtype changed: userId=" + userId
+ " ime=" + inputMethodInfo + " subtype=" + subtype);
}
- }
-
- public void switchKeyboardLayout(int deviceId, int direction) {
- mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, deviceId, direction).sendToTarget();
+ if (inputMethodInfo == null) {
+ Slog.d(TAG, "No InputMethod is running, ignoring change");
+ return;
+ }
+ if (subtype != null && !"keyboard".equals(subtype.getMode())) {
+ Slog.d(TAG, "InputMethodSubtype changed to non-keyboard subtype, ignoring change");
+ return;
+ }
+ InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(inputMethodInfo, subtype);
+ if (!handle.equals(mCurrentImeHandle)) {
+ mCurrentImeHandle = handle;
+ handleSwitchKeyboardLayout(null, handle);
+ }
}
// Must be called on handler.
- private void handleSwitchKeyboardLayout(int deviceId, int direction) {
- final InputDevice device = getInputDevice(deviceId);
- if (device != null) {
- final boolean changed;
- final String keyboardLayoutDescriptor;
-
- String key = getLayoutDescriptor(device.getIdentifier());
- synchronized (mDataStore) {
- try {
- changed = mDataStore.switchKeyboardLayout(key, direction);
- keyboardLayoutDescriptor = mDataStore.getCurrentKeyboardLayout(
- key);
- } finally {
- mDataStore.saveIfNeeded();
+ private void handleSwitchKeyboardLayout(@Nullable InputDeviceIdentifier identifier,
+ InputMethodSubtypeHandle handle) {
+ synchronized (mInputDevicesLock) {
+ for (InputDevice device : mInputDevices) {
+ if (identifier != null && !device.getIdentifier().equals(identifier) ||
+ !device.isFullKeyboard()) {
+ continue;
}
- }
-
- if (changed) {
- if (mSwitchedKeyboardLayoutToast != null) {
- mSwitchedKeyboardLayoutToast.cancel();
- mSwitchedKeyboardLayoutToast = null;
- }
- if (keyboardLayoutDescriptor != null) {
- KeyboardLayout keyboardLayout = getKeyboardLayout(keyboardLayoutDescriptor);
- if (keyboardLayout != null) {
- mSwitchedKeyboardLayoutToast = Toast.makeText(
- mContext, keyboardLayout.getLabel(), Toast.LENGTH_SHORT);
- mSwitchedKeyboardLayoutToast.show();
+ String key = getLayoutDescriptor(device.getIdentifier());
+ boolean changed = false;
+ synchronized (mDataStore) {
+ try {
+ if (mDataStore.switchKeyboardLayout(key, handle)) {
+ changed = true;
+ }
+ } finally {
+ mDataStore.saveIfNeeded();
}
}
-
- reloadKeyboardLayouts();
+ if (changed) {
+ reloadKeyboardLayouts();
+ }
}
}
}
@@ -1616,7 +1693,7 @@
}
@Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump InputManager from from pid="
@@ -1630,8 +1707,48 @@
if (dumpStr != null) {
pw.println(dumpStr);
}
+ pw.println(" Keyboard Layouts:");
+ visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
+ @Override
+ public void visitKeyboardLayout(Resources resources,
+ int keyboardLayoutResId, KeyboardLayout layout) {
+ pw.println(" \"" + layout + "\": " + layout.getDescriptor());
+ }
+ });
+ pw.println();
+ synchronized(mDataStore) {
+ mDataStore.dump(pw, " ");
+ }
}
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
+ (new Shell()).exec(this, in, out, err, args, resultReceiver);
+ }
+
+ public int onShellCommand(Shell shell, String cmd) {
+ if (TextUtils.isEmpty(cmd)) {
+ shell.onHelp();
+ return 1;
+ }
+ if (cmd.equals("setlayout")) {
+ if (!checkCallingPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT,
+ "onShellCommand()")) {
+ throw new SecurityException("Requires SET_KEYBOARD_LAYOUT permission");
+ }
+ InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(
+ shell.getNextArgRequired(), Integer.parseInt(shell.getNextArgRequired()));
+ String descriptor = shell.getNextArgRequired();
+ int vid = Integer.decode(shell.getNextArgRequired());
+ int pid = Integer.decode(shell.getNextArgRequired());
+ InputDeviceIdentifier id = new InputDeviceIdentifier(descriptor, vid, pid);
+ setKeyboardLayoutForInputDeviceInner(id, handle, shell.getNextArgRequired());
+ }
+ return 0;
+ }
+
+
private boolean checkCallingPermission(String permission, String func) {
// Quick check: if the calling permission is me, it's all okay.
if (Binder.getCallingPid() == Process.myPid()) {
@@ -1937,9 +2054,12 @@
case MSG_DELIVER_INPUT_DEVICES_CHANGED:
deliverInputDevicesChanged((InputDevice[])msg.obj);
break;
- case MSG_SWITCH_KEYBOARD_LAYOUT:
- handleSwitchKeyboardLayout(msg.arg1, msg.arg2);
+ case MSG_SWITCH_KEYBOARD_LAYOUT: {
+ SomeArgs args = (SomeArgs)msg.obj;
+ handleSwitchKeyboardLayout((InputDeviceIdentifier)args.arg1,
+ (InputMethodSubtypeHandle)args.arg2);
break;
+ }
case MSG_RELOAD_KEYBOARD_LAYOUTS:
reloadKeyboardLayouts();
break;
@@ -2106,6 +2226,25 @@
}
}
+ private class Shell extends ShellCommand {
+ @Override
+ public int onCommand(String cmd) {
+ return onShellCommand(this, cmd);
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Input manager commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println("");
+ pw.println(" setlayout IME_ID IME_SUPTYPE_HASH_CODE"
+ + " DEVICE_DESCRIPTOR VENDOR_ID PRODUCT_ID KEYBOARD_DESCRIPTOR");
+ pw.println(" Sets a keyboard layout for a given IME subtype and input device pair");
+ }
+ }
+
private final class LocalService extends InputManagerInternal {
@Override
public void setDisplayViewports(
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index f6d7244..e97aca8 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -16,6 +16,7 @@
package com.android.server.input;
+import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
@@ -26,6 +27,8 @@
import android.view.Surface;
import android.hardware.input.TouchCalibration;
+import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
@@ -37,10 +40,13 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -131,9 +137,26 @@
}
return state.getKeyboardLayouts();
}
+ public String getKeyboardLayout(String inputDeviceDescriptor,
+ InputMethodSubtypeHandle imeHandle) {
+ InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
+ if (state == null) {
+ return null;
+ }
+ return state.getKeyboardLayout(imeHandle);
+ }
- public boolean addKeyboardLayout(String inputDeviceDescriptor,
- String keyboardLayoutDescriptor) {
+ public boolean setKeyboardLayout(String inputDeviceDescriptor,
+ InputMethodSubtypeHandle imeHandle, String keyboardLayoutDescriptor) {
+ InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, true);
+ if (state.setKeyboardLayout(imeHandle, keyboardLayoutDescriptor)) {
+ setDirty();
+ return true;
+ }
+ return false;
+ }
+
+ public boolean addKeyboardLayout(String inputDeviceDescriptor, String keyboardLayoutDescriptor) {
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, true);
if (state.addKeyboardLayout(keyboardLayoutDescriptor)) {
setDirty();
@@ -152,9 +175,10 @@
return false;
}
- public boolean switchKeyboardLayout(String inputDeviceDescriptor, int direction) {
+ public boolean switchKeyboardLayout(String inputDeviceDescriptor,
+ InputMethodSubtypeHandle imeHandle) {
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
- if (state != null && state.switchKeyboardLayout(direction)) {
+ if (state != null && state.switchKeyboardLayout(imeHandle)) {
setDirty();
return true;
}
@@ -301,13 +325,26 @@
serializer.endDocument();
}
+ public void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "PersistentDataStore");
+ pw.println(prefix + " mLoaded=" + mLoaded);
+ pw.println(prefix + " mDirty=" + mDirty);
+ pw.println(prefix + " InputDeviceStates:");
+ int i = 0;
+ for (Map.Entry<String, InputDeviceState> entry : mInputDevices.entrySet()) {
+ pw.println(prefix + " " + i++ + ": " + entry.getKey());
+ entry.getValue().dump(pw, prefix + " ");
+ }
+ }
+
private static final class InputDeviceState {
private static final String[] CALIBRATION_NAME = { "x_scale",
"x_ymix", "x_offset", "y_xmix", "y_scale", "y_offset" };
private TouchCalibration[] mTouchCalibration = new TouchCalibration[4];
private String mCurrentKeyboardLayout;
- private ArrayList<String> mKeyboardLayouts = new ArrayList<String>();
+ private List<String> mUnassociatedKeyboardLayouts = new ArrayList<>();
+ private ArrayMap<InputMethodSubtypeHandle, String> mKeyboardLayouts = new ArrayMap<>();
public TouchCalibration getTouchCalibration(int surfaceRotation) {
try {
@@ -345,18 +382,34 @@
}
public String[] getKeyboardLayouts() {
- if (mKeyboardLayouts.isEmpty()) {
+ if (mUnassociatedKeyboardLayouts.isEmpty()) {
return (String[])ArrayUtils.emptyArray(String.class);
}
- return mKeyboardLayouts.toArray(new String[mKeyboardLayouts.size()]);
+ return mUnassociatedKeyboardLayouts.toArray(
+ new String[mUnassociatedKeyboardLayouts.size()]);
+ }
+
+ public String getKeyboardLayout(InputMethodSubtypeHandle handle) {
+ return mKeyboardLayouts.get(handle);
+ }
+
+ public boolean setKeyboardLayout(InputMethodSubtypeHandle imeHandle,
+ String keyboardLayout) {
+ String existingLayout = mKeyboardLayouts.get(imeHandle);
+ if (TextUtils.equals(existingLayout, keyboardLayout)) {
+ return false;
+ }
+ mKeyboardLayouts.put(imeHandle, keyboardLayout);
+ return true;
}
public boolean addKeyboardLayout(String keyboardLayout) {
- int index = Collections.binarySearch(mKeyboardLayouts, keyboardLayout);
+ int index = Collections.binarySearch(
+ mUnassociatedKeyboardLayouts, keyboardLayout);
if (index >= 0) {
return false;
}
- mKeyboardLayouts.add(-index - 1, keyboardLayout);
+ mUnassociatedKeyboardLayouts.add(-index - 1, keyboardLayout);
if (mCurrentKeyboardLayout == null) {
mCurrentKeyboardLayout = keyboardLayout;
}
@@ -364,11 +417,11 @@
}
public boolean removeKeyboardLayout(String keyboardLayout) {
- int index = Collections.binarySearch(mKeyboardLayouts, keyboardLayout);
+ int index = Collections.binarySearch(mUnassociatedKeyboardLayouts, keyboardLayout);
if (index < 0) {
return false;
}
- mKeyboardLayouts.remove(index);
+ mUnassociatedKeyboardLayouts.remove(index);
updateCurrentKeyboardLayoutIfRemoved(keyboardLayout, index);
return true;
}
@@ -376,41 +429,34 @@
private void updateCurrentKeyboardLayoutIfRemoved(
String removedKeyboardLayout, int removedIndex) {
if (Objects.equal(mCurrentKeyboardLayout, removedKeyboardLayout)) {
- if (!mKeyboardLayouts.isEmpty()) {
+ if (!mUnassociatedKeyboardLayouts.isEmpty()) {
int index = removedIndex;
- if (index == mKeyboardLayouts.size()) {
+ if (index == mUnassociatedKeyboardLayouts.size()) {
index = 0;
}
- mCurrentKeyboardLayout = mKeyboardLayouts.get(index);
+ mCurrentKeyboardLayout = mUnassociatedKeyboardLayouts.get(index);
} else {
mCurrentKeyboardLayout = null;
}
}
}
- public boolean switchKeyboardLayout(int direction) {
- final int size = mKeyboardLayouts.size();
- if (size < 2) {
- return false;
+ public boolean switchKeyboardLayout(InputMethodSubtypeHandle imeHandle) {
+ final String layout = mKeyboardLayouts.get(imeHandle);
+ if (layout != null && !TextUtils.equals(mCurrentKeyboardLayout, layout)) {
+ mCurrentKeyboardLayout = layout;
+ return true;
}
- int index = Collections.binarySearch(mKeyboardLayouts, mCurrentKeyboardLayout);
- assert index >= 0;
- if (direction > 0) {
- index = (index + 1) % size;
- } else {
- index = (index + size - 1) % size;
- }
- mCurrentKeyboardLayout = mKeyboardLayouts.get(index);
- return true;
+ return false;
}
public boolean removeUninstalledKeyboardLayouts(Set<String> availableKeyboardLayouts) {
boolean changed = false;
- for (int i = mKeyboardLayouts.size(); i-- > 0; ) {
- String keyboardLayout = mKeyboardLayouts.get(i);
+ for (int i = mUnassociatedKeyboardLayouts.size(); i-- > 0; ) {
+ String keyboardLayout = mUnassociatedKeyboardLayouts.get(i);
if (!availableKeyboardLayouts.contains(keyboardLayout)) {
Slog.i(TAG, "Removing uninstalled keyboard layout " + keyboardLayout);
- mKeyboardLayouts.remove(i);
+ mUnassociatedKeyboardLayouts.remove(i);
updateCurrentKeyboardLayoutIfRemoved(keyboardLayout, i);
changed = true;
}
@@ -428,13 +474,8 @@
throw new XmlPullParserException(
"Missing descriptor attribute on keyboard-layout.");
}
- String current = parser.getAttributeValue(null, "current");
- if (mKeyboardLayouts.contains(descriptor)) {
- throw new XmlPullParserException(
- "Found duplicate keyboard layout.");
- }
- mKeyboardLayouts.add(descriptor);
+ String current = parser.getAttributeValue(null, "current");
if (current != null && current.equals("true")) {
if (mCurrentKeyboardLayout != null) {
throw new XmlPullParserException(
@@ -442,6 +483,32 @@
}
mCurrentKeyboardLayout = descriptor;
}
+
+ String inputMethodId = parser.getAttributeValue(null, "input-method-id");
+ String inputMethodSubtypeId =
+ parser.getAttributeValue(null, "input-method-subtype-id");
+ if (inputMethodId == null && inputMethodSubtypeId != null
+ || inputMethodId != null && inputMethodSubtypeId == null) {
+ throw new XmlPullParserException(
+ "Found an incomplete input method description");
+ }
+
+ if (inputMethodSubtypeId != null) {
+ InputMethodSubtypeHandle handle = new InputMethodSubtypeHandle(
+ inputMethodId, Integer.parseInt(inputMethodSubtypeId));
+ if (mKeyboardLayouts.containsKey(handle)) {
+ throw new XmlPullParserException(
+ "Found duplicate subtype to keyboard layout mapping: "
+ + handle);
+ }
+ mKeyboardLayouts.put(handle, descriptor);
+ } else {
+ if (mUnassociatedKeyboardLayouts.contains(descriptor)) {
+ throw new XmlPullParserException(
+ "Found duplicate unassociated keyboard layout: " + descriptor);
+ }
+ mUnassociatedKeyboardLayouts.add(descriptor);
+ }
} else if (parser.getName().equals("calibration")) {
String format = parser.getAttributeValue(null, "format");
String rotation = parser.getAttributeValue(null, "rotation");
@@ -492,19 +559,31 @@
}
// Maintain invariant that layouts are sorted.
- Collections.sort(mKeyboardLayouts);
+ Collections.sort(mUnassociatedKeyboardLayouts);
// Maintain invariant that there is always a current keyboard layout unless
// there are none installed.
- if (mCurrentKeyboardLayout == null && !mKeyboardLayouts.isEmpty()) {
- mCurrentKeyboardLayout = mKeyboardLayouts.get(0);
+ if (mCurrentKeyboardLayout == null && !mUnassociatedKeyboardLayouts.isEmpty()) {
+ mCurrentKeyboardLayout = mUnassociatedKeyboardLayouts.get(0);
}
}
public void saveToXml(XmlSerializer serializer) throws IOException {
- for (String layout : mKeyboardLayouts) {
+ for (String layout : mUnassociatedKeyboardLayouts) {
serializer.startTag(null, "keyboard-layout");
serializer.attribute(null, "descriptor", layout);
+ serializer.endTag(null, "keyboard-layout");
+ }
+
+ final int N = mKeyboardLayouts.size();
+ for (int i = 0; i < N; i++) {
+ final InputMethodSubtypeHandle handle = mKeyboardLayouts.keyAt(i);
+ final String layout = mKeyboardLayouts.valueAt(i);
+ serializer.startTag(null, "keyboard-layout");
+ serializer.attribute(null, "descriptor", layout);
+ serializer.attribute(null, "input-method-id", handle.getInputMethodId());
+ serializer.attribute(null, "input-method-subtype-id",
+ Integer.toString(handle.getSubtypeId()));
if (layout.equals(mCurrentKeyboardLayout)) {
serializer.attribute(null, "current", "true");
}
@@ -529,6 +608,22 @@
}
}
+ private void dump(final PrintWriter pw, final String prefix) {
+ pw.println(prefix + "CurrentKeyboardLayout=" + mCurrentKeyboardLayout);
+ pw.println(prefix + "UnassociatedKeyboardLayouts=" + mUnassociatedKeyboardLayouts);
+ pw.println(prefix + "TouchCalibration=" + Arrays.toString(mTouchCalibration));
+ pw.println(prefix + "Subtype to Layout Mappings:");
+ final int N = mKeyboardLayouts.size();
+ if (N != 0) {
+ for (int i = 0; i < N; i++) {
+ pw.println(prefix + " " + mKeyboardLayouts.keyAt(i) + ": "
+ + mKeyboardLayouts.valueAt(i));
+ }
+ } else {
+ pw.println(prefix + " <none>");
+ }
+ }
+
private static String surfaceRotationToString(int surfaceRotation) {
switch (surfaceRotation) {
case Surface.ROTATION_0: return "0";
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 38ebc80..1d7d24b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -31,6 +31,9 @@
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_DISABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
+import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
import static android.net.ConnectivityManager.isNetworkTypeMobile;
import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.net.NetworkPolicy.LIMIT_DISABLED;
@@ -124,6 +127,7 @@
import android.os.INetworkManagementService;
import android.os.IPowerManager;
import android.os.Message;
+import android.os.ResultReceiver;
import android.os.MessageQueue.IdleHandler;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
@@ -1873,6 +1877,20 @@
}
@Override
+ public int getRestrictBackgroundByCaller() {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+ final int uid = Binder.getCallingUid();
+ synchronized (mRulesLock) {
+ if (!mRestrictBackground) {
+ return RESTRICT_BACKGROUND_STATUS_DISABLED;
+ }
+ return mRestrictBackgroundWhitelistUids.get(uid)
+ ? RESTRICT_BACKGROUND_STATUS_WHITELISTED
+ : RESTRICT_BACKGROUND_STATUS_ENABLED;
+ }
+ }
+
+ @Override
public boolean getRestrictBackground() {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
@@ -2102,6 +2120,13 @@
}
@Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ String[] args, ResultReceiver resultReceiver) throws RemoteException {
+ (new NetworkPolicyManagerShellCommand(this)).exec(
+ this, in, out, err, args, resultReceiver);
+ }
+
+ @Override
public boolean isUidForeground(int uid) {
mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
new file mode 100644
index 0000000..7b1acca
--- /dev/null
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import java.io.PrintWriter;
+
+import android.content.Intent;
+import android.net.INetworkPolicyManager;
+import android.os.RemoteException;
+import android.os.ShellCommand;
+
+public class NetworkPolicyManagerShellCommand extends ShellCommand {
+
+ final INetworkPolicyManager mInterface;
+
+ NetworkPolicyManagerShellCommand(NetworkPolicyManagerService service) {
+ mInterface = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter pw = getOutPrintWriter();
+ try {
+ switch(cmd) {
+ case "get":
+ return runGet();
+ case "set":
+ return runSet();
+ case "list":
+ return runList();
+ case "add":
+ return runAdd();
+ case "remove":
+ return runRemove();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ } catch (RemoteException e) {
+ pw.println("Remote exception: " + e);
+ }
+ return -1;
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Network policy manager (netpolicy) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println("");
+ pw.println(" get restrict-background");
+ pw.println(" Gets the global restrict background usage status.");
+ pw.println(" set restrict-background BOOLEAN");
+ pw.println(" Sets the global restrict background usage status.");
+ pw.println(" list restrict-background-whitelist");
+ pw.println(" Prints UID that are whitelisted for restrict background usage.");
+ pw.println(" add restrict-background-whitelist UID");
+ pw.println(" Adds a UID to the whitelist for restrict background usage.");
+ pw.println(" remove restrict-background-whitelist UID");
+ pw.println(" Removes a UID from the whitelist for restrict background usage.");
+ }
+
+ private int runGet() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final String type = getNextArg();
+ if (type == null) {
+ pw.println("Error: didn't specify type of data to get");
+ return -1;
+ }
+ switch(type) {
+ case "restrict-background":
+ return getRestrictBackgroundWhitelist();
+ }
+ pw.println("Error: unknown get type '" + type + "'");
+ return -1;
+ }
+
+ private int runSet() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final String type = getNextArg();
+ if (type == null) {
+ pw.println("Error: didn't specify type of data to set");
+ return -1;
+ }
+ switch(type) {
+ case "restrict-background":
+ return setRestrictBackgroundWhitelist();
+ }
+ pw.println("Error: unknown set type '" + type + "'");
+ return -1;
+ }
+
+ private int runList() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final String type = getNextArg();
+ if (type == null) {
+ pw.println("Error: didn't specify type of data to list");
+ return -1;
+ }
+ switch(type) {
+ case "restrict-background-whitelist":
+ return runListRestrictBackgroundWhitelist();
+ }
+ pw.println("Error: unknown list type '" + type + "'");
+ return -1;
+ }
+
+ private int runAdd() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final String type = getNextArg();
+ if (type == null) {
+ pw.println("Error: didn't specify type of data to add");
+ return -1;
+ }
+ switch(type) {
+ case "restrict-background-whitelist":
+ return addRestrictBackgroundWhitelist();
+ }
+ pw.println("Error: unknown add type '" + type + "'");
+ return -1;
+ }
+
+ private int runRemove() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final String type = getNextArg();
+ if (type == null) {
+ pw.println("Error: didn't specify type of data to remove");
+ return -1;
+ }
+ switch(type) {
+ case "restrict-background-whitelist":
+ return removeRestrictBackgroundWhitelist();
+ }
+ pw.println("Error: unknown remove type '" + type + "'");
+ return -1;
+ }
+
+ private int runListRestrictBackgroundWhitelist() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ final int[] uids = mInterface.getRestrictBackgroundWhitelistedUids();
+ pw.print("Restrict background whitelisted UIDs: ");
+ if (uids.length == 0) {
+ pw.println("none");
+ } else {
+ for (int i = 0; i < uids.length; i++) {
+ int uid = uids[i];
+ pw.print(uid);
+ pw.print(' ');
+ }
+ }
+ pw.println();
+ return 0;
+ }
+
+ private int getRestrictBackgroundWhitelist() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.print("Restrict background status: ");
+ pw.println(mInterface.getRestrictBackground() ? "enabled" : "disabled");
+ return 0;
+ }
+
+ private int setRestrictBackgroundWhitelist() throws RemoteException {
+ final int enabled = getNextBooleanArg();
+ if (enabled < 0) {
+ return enabled;
+ }
+ mInterface.setRestrictBackground(enabled > 0);
+ return 0;
+ }
+
+ private int addRestrictBackgroundWhitelist() throws RemoteException {
+ final int uid = getUidFromNextArg();
+ if (uid < 0) {
+ return uid;
+ }
+ mInterface.addRestrictBackgroundWhitelistedUid(uid);
+ return 0;
+ }
+
+ private int removeRestrictBackgroundWhitelist() throws RemoteException {
+ final int uid = getUidFromNextArg();
+ if (uid < 0) {
+ return uid;
+ }
+ mInterface.removeRestrictBackgroundWhitelistedUid(uid);
+ return 0;
+ }
+
+ private int getNextBooleanArg() {
+ final PrintWriter pw = getOutPrintWriter();
+ final String arg = getNextArg();
+ if (arg == null) {
+ pw.println("Error: didn't specify BOOLEAN");
+ return -1;
+ }
+ return Boolean.valueOf(arg) ? 1 : 0;
+ }
+
+ private int getUidFromNextArg() {
+ final PrintWriter pw = getOutPrintWriter();
+ final String arg = getNextArg();
+ if (arg == null) {
+ pw.println("Error: didn't specify UID");
+ return -1;
+ }
+ try {
+ return Integer.parseInt(arg);
+ } catch (NumberFormatException e) {
+ pw.println("Error: UID (" + arg + ") should be a number");
+ return -2;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index f360dc2..f5da52e 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -297,7 +297,6 @@
checkType(guest.service);
if (registerServiceImpl(guest) != null) {
onServiceAdded(guest);
- onServiceAdded(guest);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b1fe68c..2ee74db 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -223,6 +223,8 @@
private WorkerHandler mHandler;
private final HandlerThread mRankingThread = new HandlerThread("ranker",
Process.THREAD_PRIORITY_BACKGROUND);
+ private final HandlerThread mAssistantThread = new HandlerThread("assistant",
+ Process.THREAD_PRIORITY_BACKGROUND);
private Light mNotificationLight;
Light mAttentionLight;
@@ -295,6 +297,7 @@
private static final int MY_UID = Process.myUid();
private static final int MY_PID = Process.myPid();
private RankingHandler mRankingHandler;
+ private Handler mAssistantHandler;
private static class Archive {
final int mBufferSize;
@@ -878,6 +881,7 @@
mHandler = new WorkerHandler();
mRankingThread.start();
+ mAssistantThread.start();
String[] extractorNames;
try {
extractorNames = resources.getStringArray(R.array.config_notificationSignalExtractors);
@@ -886,6 +890,7 @@
}
mUsageStats = new NotificationUsageStats(getContext());
mRankingHandler = new RankingHandlerWorker(mRankingThread.getLooper());
+ mAssistantHandler = new Handler(mAssistantThread.getLooper());
mRankingHelper = new RankingHelper(getContext(),
mRankingHandler,
mUsageStats,
@@ -1957,7 +1962,7 @@
@Override
public void setImportanceFromAssistant(INotificationListener token, String key,
- int importance, CharSequence explanation) {
+ int importance, CharSequence explanation) throws RemoteException {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationList) {
@@ -2249,115 +2254,145 @@
+ " id=" + id + " notification=" + notification);
}
- mHandler.post(new Runnable() {
- @Override
- public void run() {
+ // Sanitize inputs
+ notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
+ Notification.PRIORITY_MAX);
- synchronized (mNotificationList) {
-
- // Sanitize inputs
- notification.priority = clamp(notification.priority, Notification.PRIORITY_MIN,
- Notification.PRIORITY_MAX);
-
- // setup local book-keeping
- final StatusBarNotification n = new StatusBarNotification(
- pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
- user);
- NotificationRecord r = new NotificationRecord(getContext(), n);
- NotificationRecord old = mNotificationsByKey.get(n.getKey());
- if (old != null) {
- // Retain ranking information from previous record
- r.copyRankingInformation(old);
- }
-
- // Handle grouped notifications and bail out early if we
- // can to avoid extracting signals.
- handleGroupedNotificationLocked(r, old, callingUid, callingPid);
- boolean ignoreNotification =
- removeUnusedGroupedNotificationLocked(r, old, callingUid, callingPid);
-
- // This conditional is a dirty hack to limit the logging done on
- // behalf of the download manager without affecting other apps.
- if (!pkg.equals("com.android.providers.downloads")
- || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
- int enqueueStatus = EVENTLOG_ENQUEUE_STATUS_NEW;
- if (ignoreNotification) {
- enqueueStatus = EVENTLOG_ENQUEUE_STATUS_IGNORED;
- } else if (old != null) {
- enqueueStatus = EVENTLOG_ENQUEUE_STATUS_UPDATE;
- }
- EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
- pkg, id, tag, userId, notification.toString(),
- enqueueStatus);
- }
-
- if (ignoreNotification) {
- return;
- }
-
- mRankingHelper.extractSignals(r);
- savePolicyFile();
-
- // blocked apps/topics
- if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
- || !noteNotificationOp(pkg, callingUid)) {
- if (!isSystemNotification) {
- Slog.e(TAG, "Suppressing notification from package " + pkg
- + " by user request.");
- mUsageStats.registerBlocked(r);
- return;
- }
- }
-
- int index = indexOfNotificationLocked(n.getKey());
- if (index < 0) {
- mNotificationList.add(r);
- mUsageStats.registerPostedByApp(r);
- } else {
- old = mNotificationList.get(index);
- mNotificationList.set(index, r);
- mUsageStats.registerUpdatedByApp(r, old);
- // Make sure we don't lose the foreground service state.
- notification.flags |=
- old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
- r.isUpdate = true;
- }
-
- mNotificationsByKey.put(n.getKey(), r);
-
- // Ensure if this is a foreground service that the proper additional
- // flags are set.
- if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
- notification.flags |= Notification.FLAG_ONGOING_EVENT
- | Notification.FLAG_NO_CLEAR;
- }
-
- applyZenModeLocked(r);
- mRankingHelper.sort(mNotificationList);
-
- if (notification.getSmallIcon() != null) {
- StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
- mListeners.notifyPostedLocked(n, oldSbn);
- } else {
- Slog.e(TAG, "Not posting notification without small icon: " + notification);
- if (old != null && !old.isCanceled) {
- mListeners.notifyRemovedLocked(n);
- }
- // ATTENTION: in a future release we will bail out here
- // so that we do not play sounds, show lights, etc. for invalid
- // notifications
- Slog.e(TAG, "WARNING: In a future release this will crash the app: "
- + n.getPackageName());
- }
-
- buzzBeepBlinkLocked(r);
- }
- }
- });
+ // setup local book-keeping
+ final StatusBarNotification n = new StatusBarNotification(
+ pkg, opPkg, id, tag, callingUid, callingPid, 0, notification,
+ user);
+ final NotificationRecord r = new NotificationRecord(getContext(), n);
+ mHandler.post(new EnqueueNotificationRunnable(userId, r));
idOut[0] = id;
}
+ private class EnqueueNotificationRunnable implements Runnable {
+ private final NotificationRecord r;
+ private final int userId;
+
+ EnqueueNotificationRunnable(int userId, NotificationRecord r) {
+ this.userId = userId;
+ this.r = r;
+ };
+
+ @Override
+ public void run() {
+
+ synchronized (mNotificationList) {
+ final StatusBarNotification n = r.sbn;
+ Slog.d(TAG, "EnqueueNotificationRunnable.run for: " + n.getKey());
+ NotificationRecord old = mNotificationsByKey.get(n.getKey());
+ if (old != null) {
+ // Retain ranking information from previous record
+ r.copyRankingInformation(old);
+ }
+
+ final int callingUid = n.getUid();
+ final int callingPid = n.getInitialPid();
+ final Notification notification = n.getNotification();
+ final String pkg = n.getPackageName();
+ final int id = n.getId();
+ final String tag = n.getTag();
+ final boolean isSystemNotification = isUidSystem(callingUid) ||
+ ("android".equals(pkg));
+
+ // Handle grouped notifications and bail out early if we
+ // can to avoid extracting signals.
+ handleGroupedNotificationLocked(r, old, callingUid, callingPid);
+ boolean ignoreNotification =
+ removeUnusedGroupedNotificationLocked(r, old, callingUid, callingPid);
+ Slog.d(TAG, "ignoreNotification is " + ignoreNotification);
+
+ // This conditional is a dirty hack to limit the logging done on
+ // behalf of the download manager without affecting other apps.
+ if (!pkg.equals("com.android.providers.downloads")
+ || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
+ int enqueueStatus = EVENTLOG_ENQUEUE_STATUS_NEW;
+ if (ignoreNotification) {
+ enqueueStatus = EVENTLOG_ENQUEUE_STATUS_IGNORED;
+ } else if (old != null) {
+ enqueueStatus = EVENTLOG_ENQUEUE_STATUS_UPDATE;
+ }
+ EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
+ pkg, id, tag, userId, notification.toString(),
+ enqueueStatus);
+ }
+
+ if (ignoreNotification) {
+ return;
+ }
+
+ mRankingHelper.extractSignals(r);
+
+ // why is this here?
+ savePolicyFile();
+
+ // blocked apps/topics
+ if (r.getImportance() == NotificationListenerService.Ranking.IMPORTANCE_NONE
+ || !noteNotificationOp(pkg, callingUid)) {
+ if (!isSystemNotification) {
+ Slog.e(TAG, "Suppressing notification from package " + pkg
+ + " by user request.");
+ mUsageStats.registerBlocked(r);
+ return;
+ }
+ }
+
+ // tell the assistant about the notification
+ if (mAssistant.isEnabled()) {
+ mAssistant.onNotificationEnqueued(r);
+ // TODO delay the code below here for 100ms or until there is an answer
+ }
+
+
+ int index = indexOfNotificationLocked(n.getKey());
+ if (index < 0) {
+ mNotificationList.add(r);
+ mUsageStats.registerPostedByApp(r);
+ } else {
+ old = mNotificationList.get(index);
+ mNotificationList.set(index, r);
+ mUsageStats.registerUpdatedByApp(r, old);
+ // Make sure we don't lose the foreground service state.
+ notification.flags |=
+ old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
+ r.isUpdate = true;
+ }
+
+ mNotificationsByKey.put(n.getKey(), r);
+
+ // Ensure if this is a foreground service that the proper additional
+ // flags are set.
+ if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+ notification.flags |= Notification.FLAG_ONGOING_EVENT
+ | Notification.FLAG_NO_CLEAR;
+ }
+
+ applyZenModeLocked(r);
+ mRankingHelper.sort(mNotificationList);
+
+ if (notification.getSmallIcon() != null) {
+ StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
+ mListeners.notifyPostedLocked(n, oldSbn);
+ } else {
+ Slog.e(TAG, "Not posting notification without small icon: " + notification);
+ if (old != null && !old.isCanceled) {
+ mListeners.notifyRemovedLocked(n);
+ }
+ // ATTENTION: in a future release we will bail out here
+ // so that we do not play sounds, show lights, etc. for invalid
+ // notifications
+ Slog.e(TAG, "WARNING: In a future release this will crash the app: "
+ + n.getPackageName());
+ }
+
+ buzzBeepBlinkLocked(r);
+ }
+ }
+ }
+
/**
* Ensures that grouped notification receive their special treatment.
*
@@ -3391,6 +3426,30 @@
return true;
}
+ private class TrimCache {
+ StatusBarNotification heavy;
+ StatusBarNotification sbnClone;
+ StatusBarNotification sbnCloneLight;
+
+ TrimCache(StatusBarNotification sbn) {
+ heavy = sbn;
+ }
+
+ StatusBarNotification ForListener(ManagedServiceInfo info) {
+ if (mListeners.getOnNotificationPostedTrim(info) == TRIM_LIGHT) {
+ if (sbnCloneLight == null) {
+ sbnCloneLight = heavy.cloneLight();
+ }
+ return sbnCloneLight;
+ } else {
+ if (sbnClone == null) {
+ sbnClone = heavy.clone();
+ }
+ return sbnClone;
+ }
+ }
+ }
+
public class NotificationAssistant extends ManagedServices {
public NotificationAssistant() {
@@ -3428,6 +3487,46 @@
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
mListeners.unregisterService(removed.service, removed.userid);
}
+
+ public void onNotificationEnqueued(final NotificationRecord r) {
+ final StatusBarNotification sbn = r.sbn;
+ TrimCache trimCache = new TrimCache(sbn);
+
+ // mServices is the list inside ManagedServices of all the assistants,
+ // There should be only one, but it's a list, so while we enforce
+ // singularity elsewhere, we keep it general here, to avoid surprises.
+ for (final ManagedServiceInfo info : NotificationAssistant.this.mServices) {
+ boolean sbnVisible = isVisibleToListener(sbn, info);
+ if (!sbnVisible) {
+ continue;
+ }
+
+ final int importance = r.getImportance();
+ final boolean fromUser = r.isImportanceFromUser();
+ final StatusBarNotification sbnToPost = trimCache.ForListener(info);
+ mAssistantHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ notifyEnqueued(info, sbnToPost, importance, fromUser);
+ }
+ });
+ }
+ }
+
+ private void notifyEnqueued(final ManagedServiceInfo info,
+ final StatusBarNotification sbn, int importance, boolean fromUser) {
+ final INotificationListener assistant = (INotificationListener) info.service;
+ StatusBarNotificationHolder sbnHolder = new StatusBarNotificationHolder(sbn);
+ try {
+ assistant.onNotificationEnqueued(sbnHolder, importance, fromUser);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "unable to notify assistant (enqueued): " + assistant, ex);
+ }
+ }
+
+ public boolean isEnabled() {
+ return !mServices.isEmpty();
+ }
}
public class NotificationListeners extends ManagedServices {
@@ -3476,7 +3575,6 @@
}
}
-
@Override
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
if (mListenersDisablingEffects.remove(removed)) {
@@ -3508,8 +3606,7 @@
*/
public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn) {
// Lazily initialized snapshots of the notification.
- StatusBarNotification sbnClone = null;
- StatusBarNotification sbnCloneLight = null;
+ TrimCache trimCache = new TrimCache(sbn);
for (final ManagedServiceInfo info : mServices) {
boolean sbnVisible = isVisibleToListener(sbn, info);
@@ -3532,16 +3629,7 @@
continue;
}
- final int trim = mListeners.getOnNotificationPostedTrim(info);
-
- if (trim == TRIM_LIGHT && sbnCloneLight == null) {
- sbnCloneLight = sbn.cloneLight();
- } else if (trim == TRIM_FULL && sbnClone == null) {
- sbnClone = sbn.clone();
- }
- final StatusBarNotification sbnToPost =
- (trim == TRIM_FULL) ? sbnClone : sbnCloneLight;
-
+ final StatusBarNotification sbnToPost = trimCache.ForListener(info);
mHandler.post(new Runnable() {
@Override
public void run() {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 0be2edd..490e890 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -15,6 +15,7 @@
*/
package com.android.server.notification;
+import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_DEFAULT;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_LOW;
@@ -88,8 +89,8 @@
private int mAuthoritativeRank;
private String mGlobalSortKey;
private int mPackageVisibility;
- private int mTopicImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
- private int mImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED;
+ private int mTopicImportance = IMPORTANCE_UNSPECIFIED;
+ private int mImportance = IMPORTANCE_UNSPECIFIED;
private CharSequence mImportanceExplanation = null;
private int mSuppressedVisualEffects = 0;
@@ -510,4 +511,8 @@
public String getGroupKey() {
return sbn.getGroupKey();
}
+
+ public boolean isImportanceFromUser() {
+ return mImportance == mTopicImportance;
+ }
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1e057aa..5b9f0b3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -109,7 +109,7 @@
*/
public class UserManagerService extends IUserManager.Stub {
private static final String LOG_TAG = "UserManagerService";
- static final boolean DBG = true; // DO NOT SUBMIT WITH TRUE
+ static final boolean DBG = false; // DO NOT SUBMIT WITH TRUE
private static final boolean DBG_WITH_STACKTRACE = false; // DO NOT SUBMIT WITH TRUE
private static final String TAG_NAME = "name";
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3b61817..0b1354a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3136,15 +3136,6 @@
hideRecentApps(true, false);
}
- // Handle keyboard layout switching.
- // TODO: Deprecate this behavior when we fully migrate to IME subtype-based layout rotation.
- if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_SPACE
- && ((metaState & KeyEvent.META_CTRL_MASK) != 0)) {
- int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
- mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
- return -1;
- }
-
// Handle input method switching.
if (down && repeatCount == 0
&& (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 9a55e7f..2deb0d5 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -34,7 +34,6 @@
*/
public class VrManagerService extends SystemService {
- public static final boolean DEBUG = false;
public static final String TAG = "VrManagerService";
private final Object mLock = new Object();
@@ -88,7 +87,8 @@
synchronized (mLock) {
if (mVrModeEnabled != enabled) {
mVrModeEnabled = enabled;
- if (DEBUG) Slog.d(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
+ // Log mode change event.
+ Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
onVrModeChangedLocked();
}
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 87d0700..39983dd 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -92,6 +92,8 @@
import com.android.internal.R;
import com.android.server.EventLogTags;
+import libcore.io.IoUtils;
+
public class WallpaperManagerService extends IWallpaperManager.Stub {
static final String TAG = "WallpaperManagerService";
static final boolean DEBUG = false;
@@ -170,6 +172,12 @@
WallpaperData mLastWallpaper;
/**
+ * ID of the current wallpaper, changed every time anything sets a wallpaper.
+ * This is used for external detection of wallpaper update activity.
+ */
+ int mWallpaperId;
+
+ /**
* Name of the component used to display bitmap wallpapers from either the gallery or
* built-in wallpapers.
*/
@@ -205,6 +213,11 @@
*/
ComponentName nextWallpaperComponent;
+ /**
+ * The ID of this wallpaper
+ */
+ int wallpaperId;
+
WallpaperConnection connection;
long lastDiedTime;
boolean wallpaperUpdating;
@@ -227,6 +240,13 @@
}
}
+ int makeWallpaperIdLocked() {
+ do {
+ ++mWallpaperId;
+ } while (mWallpaperId == 0);
+ return mWallpaperId;
+ }
+
class WallpaperConnection extends IWallpaperConnection.Stub
implements ServiceConnection {
final WallpaperInfo mInfo;
@@ -333,7 +353,7 @@
public ParcelFileDescriptor setWallpaper(String name) {
synchronized (mLock) {
if (mWallpaper.connection == this) {
- return updateWallpaperBitmapLocked(name, mWallpaper);
+ return updateWallpaperBitmapLocked(name, mWallpaper, null);
}
return null;
}
@@ -848,18 +868,26 @@
}
}
- public ParcelFileDescriptor setWallpaper(String name, String callingPackage) {
+ @Override
+ public ParcelFileDescriptor setWallpaper(String name, String callingPackage, Bundle extras,
+ int which) {
checkPermission(android.Manifest.permission.SET_WALLPAPER);
+
+ if (which == 0) {
+ return null;
+ }
+
if (!isWallpaperSupported(callingPackage)) {
return null;
}
+
synchronized (mLock) {
if (DEBUG) Slog.v(TAG, "setWallpaper");
int userId = UserHandle.getCallingUserId();
WallpaperData wallpaper = getWallpaperSafeLocked(userId);
final long ident = Binder.clearCallingIdentity();
try {
- ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
+ ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper, extras);
if (pfd != null) {
wallpaper.imageWallpaperPending = true;
}
@@ -870,7 +898,8 @@
}
}
- ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
+ ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper,
+ Bundle extras) {
if (name == null) name = "";
try {
File dir = getWallpaperDir(wallpaper.userId);
@@ -888,6 +917,14 @@
return null;
}
wallpaper.name = name;
+ wallpaper.wallpaperId = makeWallpaperIdLocked();
+ if (extras != null) {
+ extras.putInt(WallpaperManager.EXTRA_NEW_WALLPAPER_ID, wallpaper.wallpaperId);
+ }
+ if (DEBUG) {
+ Slog.v(TAG, "updateWallpaperBitmapLocked() : id=" + wallpaper.wallpaperId
+ + " name=" + name);
+ }
return fd;
} catch (FileNotFoundException e) {
Slog.w(TAG, "Error setting wallpaper", e);
@@ -1156,6 +1193,7 @@
out.startDocument(null, true);
out.startTag(null, "wp");
+ out.attribute(null, "id", Integer.toString(wallpaper.wallpaperId));
out.attribute(null, "width", Integer.toString(wallpaper.width));
out.attribute(null, "height", Integer.toString(wallpaper.height));
if (wallpaper.padding.left != 0) {
@@ -1184,13 +1222,7 @@
stream.close();
journal.commit();
} catch (IOException e) {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException ex) {
- // Ignore
- }
+ IoUtils.closeQuietly(stream);
journal.rollback();
}
}
@@ -1259,6 +1291,16 @@
if (type == XmlPullParser.START_TAG) {
String tag = parser.getName();
if ("wp".equals(tag)) {
+ final String idString = parser.getAttributeValue(null, "id");
+ if (idString != null) {
+ final int id = wallpaper.wallpaperId = Integer.parseInt(idString);
+ if (id > mWallpaperId) {
+ mWallpaperId = id;
+ }
+ } else {
+ wallpaper.wallpaperId = makeWallpaperIdLocked();
+ }
+
wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
wallpaper.height = Integer.parseInt(parser
.getAttributeValue(null, "height"));
@@ -1301,19 +1343,21 @@
} catch (IndexOutOfBoundsException e) {
Slog.w(TAG, "failed parsing " + file + " " + e);
}
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- // Ignore
- }
+ IoUtils.closeQuietly(stream);
if (!success) {
wallpaper.width = -1;
wallpaper.height = -1;
wallpaper.padding.set(0, 0, 0, 0);
wallpaper.name = "";
+ } else {
+ if (wallpaper.wallpaperId <= 0) {
+ wallpaper.wallpaperId = makeWallpaperIdLocked();
+ if (DEBUG) {
+ Slog.w(TAG, "Didn't set wallpaper id in loadSettingsLocked(" + userId
+ + "); now " + wallpaper.wallpaperId);
+ }
+ }
}
// We always want to have some reasonable width hint.
@@ -1346,6 +1390,7 @@
synchronized (mLock) {
loadSettingsLocked(0);
wallpaper = mWallpaperMap.get(0);
+ wallpaper.wallpaperId = makeWallpaperIdLocked(); // always bump id at restore
if (wallpaper.nextWallpaperComponent != null
&& !wallpaper.nextWallpaperComponent.equals(mImageWallpaper)) {
if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
@@ -1366,7 +1411,8 @@
if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
success = restoreNamedResourceLocked(wallpaper);
}
- if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
+ if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success
+ + " id=" + wallpaper.wallpaperId);
if (success) {
bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
wallpaper, null);
@@ -1442,16 +1488,10 @@
} catch (IOException e) {
Slog.e(TAG, "IOException while restoring wallpaper ", e);
} finally {
- if (res != null) {
- try {
- res.close();
- } catch (IOException ex) {}
- }
+ IoUtils.closeQuietly(res);
if (fos != null) {
FileUtils.sync(fos);
- try {
- fos.close();
- } catch (IOException ex) {}
+ IoUtils.closeQuietly(fos);
}
}
}
@@ -1474,7 +1514,8 @@
pw.println("Current Wallpaper Service state:");
for (int i = 0; i < mWallpaperMap.size(); i++) {
WallpaperData wallpaper = mWallpaperMap.valueAt(i);
- pw.println(" User " + wallpaper.userId + ":");
+ pw.print(" User "); pw.print(wallpaper.userId);
+ pw.print(": id="); pw.println(wallpaper.wallpaperId);
pw.print(" mWidth=");
pw.print(wallpaper.width);
pw.print(" mHeight=");
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 0622fad..552af03 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -732,7 +732,8 @@
float scaleW = appWidth / thumbWidth;
float unscaledHeight = thumbHeight * scaleW;
getNextAppTransitionStartRect(taskId, mTmpRect);
- float unscaledStartY = mTmpRect.top - (unscaledHeight - thumbHeight) / 2f;
+ final float unscaledStartY = mTmpRect.top - (unscaledHeight - thumbHeight) / 2f;
+ final float toY = appRect.top + mNextAppTransitionInsets.top + -unscaledStartY;
if (mNextAppTransitionScaleUp) {
// Animation up from the thumbnail to the full screen
Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
@@ -744,7 +745,6 @@
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
final float toX = appRect.left + appRect.width() / 2 -
(mTmpRect.left + thumbWidth / 2);
- final float toY = appRect.top + mNextAppTransitionInsets.top + -unscaledStartY;
Animation translate = new TranslateAnimation(0, toX, 0, toY);
translate.setInterpolator(mTouchResponseInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
@@ -764,8 +764,9 @@
Animation alpha = new AlphaAnimation(0f, 1f);
alpha.setInterpolator(mThumbnailFadeInInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
- Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
- mNextAppTransitionInsets.top, 0);
+ final float toX = appRect.left + appRect.width() / 2 -
+ (mTmpRect.left + thumbWidth / 2);
+ Animation translate = new TranslateAnimation(toX, 0, toY, 0);
translate.setInterpolator(mTouchResponseInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 65b91f7..c4653cf 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -28,6 +28,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.hardware.input.InputManager;
import android.os.IBinder;
import android.os.Message;
import android.os.Process;
@@ -36,6 +37,8 @@
import android.view.Display;
import android.view.DragEvent;
import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.PointerIcon;
import android.view.SurfaceControl;
import android.view.View;
import android.view.WindowManager;
@@ -72,6 +75,7 @@
int mUid;
ClipData mData;
ClipDescription mDataDescription;
+ int mTouchSource;
boolean mDragResult;
float mOriginalAlpha;
float mOriginalX, mOriginalY;
@@ -342,6 +346,7 @@
private void cleanUpDragLw() {
broadcastDragEndedLw();
+ restorePointerIconLw();
// stop intercepting input
unregister();
@@ -576,4 +581,21 @@
set.start(); // Will start on the first call to getTransformation.
return set;
}
+
+ private boolean isFromSource(int source) {
+ return (mTouchSource & source) == source;
+ }
+
+ void overridePointerIconLw(int touchSource) {
+ mTouchSource = touchSource;
+ if (isFromSource(InputDevice.SOURCE_MOUSE)) {
+ InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_GRAB);
+ }
+ }
+
+ private void restorePointerIconLw() {
+ if (isFromSource(InputDevice.SOURCE_MOUSE)) {
+ InputManager.getInstance().setPointerIconShape(PointerIcon.STYLE_DEFAULT);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index d8cbbab..a8d974f 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -283,7 +283,7 @@
}
public boolean performDrag(IWindow window, IBinder dragToken,
- float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+ int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
ClipData data) {
if (DEBUG_DRAG) {
Slog.d(TAG_WM, "perform drag: win=" + window + " data=" + data);
@@ -336,6 +336,7 @@
mService.mDragState.mData = data;
mService.mDragState.broadcastDragStartedLw(touchX, touchY);
+ mService.mDragState.overridePointerIconLw(touchSource);
// remember the thumb offsets for later
mService.mDragState.mThumbOffsetX = thumbCenterX;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d2e2639..1021411 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5308,12 +5308,6 @@
// Called by window manager policy. Not exposed externally.
@Override
- public void switchKeyboardLayout(int deviceId, int direction) {
- mInputManager.switchKeyboardLayout(deviceId, direction);
- }
-
- // Called by window manager policy. Not exposed externally.
- @Override
public void switchInputMethod(boolean forwardDirection) {
final InputMethodManagerInternal inputMethodManagerInternal =
LocalServices.getService(InputMethodManagerInternal.class);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 9012b98..761d6e9 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -27,6 +27,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerService.H.*;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
@@ -67,6 +68,7 @@
* surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
*/
class WindowSurfacePlacer {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
private final WindowManagerService mService;
private final WallpaperController mWallpaperControllerLocked;
@@ -160,7 +162,7 @@
if (DEBUG) {
throw new RuntimeException("Recursive call!");
}
- Slog.w(TAG_WM, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+ Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
+ Debug.getCallers(3));
return;
}
@@ -186,11 +188,10 @@
// Wait a little bit for things to settle down, and off we go.
while (!mService.mForceRemoves.isEmpty()) {
WindowState ws = mService.mForceRemoves.remove(0);
- Slog.i(TAG_WM, "Force removing: " + ws);
+ Slog.i(TAG, "Force removing: " + ws);
mService.removeWindowInnerLocked(ws);
}
- Slog.w(TAG_WM,
- "Due to memory failure, waiting a bit for next layout");
+ Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Object tmp = new Object();
synchronized (tmp) {
try {
@@ -209,7 +210,7 @@
if (++mLayoutRepeatCount < 6) {
requestTraversal();
} else {
- Slog.e(TAG_WM, "Performed 6 layouts in a row. Skipping");
+ Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
mLayoutRepeatCount = 0;
}
} else {
@@ -222,7 +223,7 @@
}
} catch (RuntimeException e) {
mInLayout = false;
- Slog.wtf(TAG_WM, "Unhandled exception while laying out windows", e);
+ Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
}
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
@@ -230,18 +231,15 @@
void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
- Slog.v(TAG_WM, "Layouts looping: " + msg +
+ Slog.v(TAG, "Layouts looping: " + msg +
", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
}
}
// "Something has changed! Let's make it correct now."
private void performSurfacePlacementInner(boolean recoveringMemory) {
- if (DEBUG_WINDOW_TRACE) {
- Slog.v(TAG_WM,
- "performSurfacePlacementInner: entry. Called by "
- + Debug.getCallers(3));
- }
+ if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
+ + Debug.getCallers(3));
int i;
boolean updateInputWindowsNeeded = false;
@@ -283,16 +281,16 @@
final int defaultDw = defaultInfo.logicalWidth;
final int defaultDh = defaultInfo.logicalHeight;
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
SurfaceControl.openTransaction();
try {
applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
} catch (RuntimeException e) {
- Slog.wtf(TAG_WM, "Unhandled exception in Window Manager", e);
+ Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
}
@@ -339,7 +337,7 @@
if (mWallpaperMayChange) {
if (DEBUG_WALLPAPER_LIGHT)
- Slog.v(TAG_WM, "Wallpaper may change! Adjusting");
+ Slog.v(TAG, "Wallpaper may change! Adjusting");
defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
defaultDisplay.pendingLayoutChanges);
@@ -374,10 +372,8 @@
mService.mResizingWindows.remove(i);
}
- if (DEBUG_ORIENTATION && mService.mDisplayFrozen)
- Slog.v(TAG_WM,
- "With display frozen, orientationChangeComplete="
- + mOrientationChangeComplete);
+ if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
+ "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
if (mOrientationChangeComplete) {
if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
@@ -435,9 +431,8 @@
// soon as their animations are complete
token.mAppAnimator.clearAnimation();
token.mAppAnimator.animating = false;
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT)
- Slog.v(TAG_WM,
- "performLayout: App token exiting now removed" + token);
+ if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+ "performLayout: App token exiting now removed" + token);
token.removeAppFromTaskLocked();
}
}
@@ -482,7 +477,7 @@
|| Settings.Global.getInt(mService.mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 0) {
if (DEBUG_VISIBILITY || DEBUG_POWER) {
- Slog.v(TAG_WM, "Turning screen on after layout!");
+ Slog.v(TAG, "Turning screen on after layout!");
}
mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
"android.server.wm:TURN_ON");
@@ -491,8 +486,7 @@
}
if (mUpdateRotation) {
- if (DEBUG_ORIENTATION) Slog.d(TAG_WM,
- "Performing post-rotate rotation");
+ if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
if (mService.updateRotationUncheckedLocked(false)) {
mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
} else {
@@ -545,7 +539,7 @@
mService.scheduleAnimationLocked();
- if (DEBUG_WINDOW_TRACE) Slog.e(TAG_WM,
+ if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
"performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
}
@@ -589,7 +583,7 @@
do {
repeats++;
if (repeats > 6) {
- Slog.w(TAG_WM, "Animation repeat aborted after too many iterations");
+ Slog.w(TAG, "Animation repeat aborted after too many iterations");
displayContent.layoutNeeded = false;
break;
}
@@ -605,7 +599,7 @@
if (isDefaultDisplay
&& (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Computing new config from layout");
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
if (mService.updateOrientationFromAppTokensLocked(true)) {
displayContent.layoutNeeded = true;
mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
@@ -621,7 +615,7 @@
performLayoutLockedInner(displayContent, repeats == 1,
false /* updateInputWindows */);
} else {
- Slog.w(TAG_WM, "Layout repeat skipped after too many iterations");
+ Slog.w(TAG, "Layout repeat skipped after too many iterations");
}
// FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
@@ -707,7 +701,7 @@
}
}
- //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - done placing");
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
w.mContentChanged = false;
w.mMovedByResize = false;
@@ -730,7 +724,7 @@
}
if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
if (DEBUG_WALLPAPER_LIGHT)
- Slog.v(TAG_WM, "First draw done in potential wallpaper target " + w);
+ Slog.v(TAG, "First draw done in potential wallpaper target " + w);
mWallpaperMayChange = true;
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
if (DEBUG_LAYOUT_REPEATS) {
@@ -753,7 +747,7 @@
final AppWindowToken atoken = w.mAppToken;
if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
- Slog.d(TAG_WM, "updateWindows: starting " + w
+ Slog.d(TAG, "updateWindows: starting " + w
+ " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
}
@@ -767,11 +761,11 @@
|| winAnimator.mAttrType == TYPE_BASE_APPLICATION)
&& !w.mExiting && !w.mDestroying) {
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
- Slog.v(TAG_WM, "Eval win " + w + ": isDrawn="
+ Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ w.isDrawnLw()
+ ", isAnimating=" + winAnimator.isAnimating());
if (!w.isDrawnLw()) {
- Slog.v(TAG_WM, "Not displayed: s="
+ Slog.v(TAG, "Not displayed: s="
+ winAnimator.mSurfaceController
+ " pv=" + w.mPolicyVisibility
+ " mDrawState=" + winAnimator.drawStateToString()
@@ -786,7 +780,7 @@
if (w.isDrawnLw()) {
atoken.numDrawnWindows++;
if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
- Slog.v(TAG_WM, "tokenMayBeDrawn: " + atoken
+ Slog.v(TAG, "tokenMayBeDrawn: " + atoken
+ " freezingScreen="
+ atoken.mAppAnimator.freezingScreen
+ " mAppFreezing=" + w.mAppFreezing);
@@ -854,8 +848,8 @@
int i;
if (DEBUG_LAYOUT) {
- Slog.v(TAG_WM, "-------------------------------------");
- Slog.v(TAG_WM, "performLayout: needed="
+ Slog.v(TAG, "-------------------------------------");
+ Slog.v(TAG, "performLayout: needed="
+ displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
}
@@ -889,18 +883,18 @@
|| win.isGoneForLayoutLw();
if (DEBUG_LAYOUT && !win.mLayoutAttached) {
- Slog.v(TAG_WM, "1ST PASS " + win
+ Slog.v(TAG, "1ST PASS " + win
+ ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
+ " mLayoutAttached=" + win.mLayoutAttached
+ " screen changed=" + win.isConfigChanged());
final AppWindowToken atoken = win.mAppToken;
- if (gone) Slog.v(TAG_WM, " GONE: mViewVisibility="
+ if (gone) Slog.v(TAG, " GONE: mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled="
+ win.mRelayoutCalled + " hidden="
+ win.mRootToken.hidden + " hiddenRequested="
+ (atoken != null && atoken.hiddenRequested)
+ " mAttachedHidden=" + win.mAttachedHidden);
- else Slog.v(TAG_WM, " VIS: mViewVisibility="
+ else Slog.v(TAG, " VIS: mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled="
+ win.mRelayoutCalled + " hidden="
+ win.mRootToken.hidden + " hiddenRequested="
@@ -920,7 +914,7 @@
win.mAppToken.layoutConfigChanges)))) {
if (!win.mLayoutAttached) {
if (initial) {
- //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
if (win.mAttrs.type == TYPE_DREAM) {
@@ -940,7 +934,7 @@
displayContent.mDimLayerController.updateDimLayer(task);
}
- if (DEBUG_LAYOUT) Slog.v(TAG_WM,
+ if (DEBUG_LAYOUT) Slog.v(TAG,
" LAYOUT: mFrame="
+ win.mFrame + " mContainingFrame="
+ win.mContainingFrame + " mDisplayFrame="
@@ -961,7 +955,7 @@
final WindowState win = windows.get(i);
if (win.mLayoutAttached) {
- if (DEBUG_LAYOUT) Slog.v(TAG_WM,
+ if (DEBUG_LAYOUT) Slog.v(TAG,
"2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
+ win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
// If this view is GONE, then skip it -- keep the current
@@ -975,14 +969,14 @@
if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
|| !win.mHaveFrame || win.mLayoutNeeded) {
if (initial) {
- //Slog.i(TAG_WM, "Window " + this + " clearing mContentChanged - initial");
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
win.mContentChanged = false;
}
win.mLayoutNeeded = false;
win.prelayout();
mService.mPolicy.layoutWindowLw(win, win.mAttachedWindow);
win.mLayoutSeq = seq;
- if (DEBUG_LAYOUT) Slog.v(TAG_WM,
+ if (DEBUG_LAYOUT) Slog.v(TAG,
" LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
+ win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
}
@@ -1013,7 +1007,7 @@
if (!transitionGoodToGo(appsCount)) {
return 0;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "**** GOOD TO GO");
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
int transit = mService.mAppTransition.getAppTransition();
if (mService.mSkipAppTransitionAnimation) {
transit = AppTransition.TRANSIT_UNSET;
@@ -1105,7 +1099,7 @@
// example, when this transition is being done behind
// the lock screen.
if (!mService.mPolicy.allowAppAnimationsLw()) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Animations disallowed by keyguard or dream.");
animLp = null;
}
@@ -1154,7 +1148,7 @@
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now opening app" + wtoken);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
if (!appAnimator.usingTransferredAnimation) {
appAnimator.clearThumbnail();
@@ -1179,14 +1173,14 @@
for (int j = 0; j < windowsCount; j++) {
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
SurfaceControl.openTransaction();
try {
mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
} finally {
SurfaceControl.closeTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG_WM,
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
}
mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
@@ -1231,7 +1225,7 @@
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Now closing app " + wtoken);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
appAnimator.clearThumbnail();
appAnimator.animation = null;
wtoken.inPendingTransaction = false;
@@ -1270,14 +1264,14 @@
}
private boolean transitionGoodToGo(int appsCount) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Checking " + appsCount + " opening apps (frozen="
+ mService.mDisplayFrozen + " timeout="
+ mService.mAppTransition.isTimeout() + ")...");
if (!mService.mAppTransition.isTimeout()) {
for (int i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Check opening app=" + wtoken + ": allDrawn="
+ wtoken.allDrawn + " startingDisplayed="
+ wtoken.startingDisplayed + " startingMoved="
@@ -1293,7 +1287,7 @@
// We also need to wait for the specs to be fetched, if needed.
if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "isFetchingAppTransitionSpecs=true");
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
return false;
}
@@ -1314,7 +1308,7 @@
? null : wallpaperTarget;
final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New wallpaper target=" + wallpaperTarget
+ ", oldWallpaper=" + oldWallpaper
+ ", lower target=" + lowerWallpaperTarget
@@ -1324,7 +1318,7 @@
mService.mAnimateWallpaperWithTarget = false;
if (closingAppHasWallpaper && openingAppHasWallpaper) {
if (DEBUG_APP_TRANSITIONS)
- Slog.v(TAG_WM, "Wallpaper animation!");
+ Slog.v(TAG, "Wallpaper animation!");
switch (transit) {
case AppTransition.TRANSIT_ACTIVITY_OPEN:
case AppTransition.TRANSIT_TASK_OPEN:
@@ -1337,14 +1331,14 @@
transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
break;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New transit: " + AppTransition.appTransitionToString(transit));
} else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
&& !openingApps.contains(oldWallpaper.mAppToken)
&& closingApps.contains(oldWallpaper.mAppToken)) {
// We are transitioning from an activity with a wallpaper to one without.
transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New transit away from wallpaper: "
+ AppTransition.appTransitionToString(transit));
} else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
@@ -1352,7 +1346,7 @@
// We are transitioning from an activity without
// a wallpaper to now showing the wallpaper
transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"New transit into wallpaper: "
+ AppTransition.appTransitionToString(transit));
} else {
@@ -1447,7 +1441,7 @@
int numInteresting = wtoken.numInterestingWindows;
if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
if (DEBUG_VISIBILITY)
- Slog.v(TAG_WM, "allDrawn: " + wtoken
+ Slog.v(TAG, "allDrawn: " + wtoken
+ " interesting=" + numInteresting
+ " drawn=" + wtoken.numDrawnWindows);
wtoken.allDrawn = true;
@@ -1476,7 +1470,7 @@
final AppWindowToken wtoken = win.mAppToken;
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS)
- Slog.v(TAG_WM, "Now animating app in place " + wtoken);
+ Slog.v(TAG, "Now animating app in place " + wtoken);
appAnimator.clearThumbnail();
appAnimator.animation = null;
mService.updateTokenInPlaceLocked(wtoken, transit);
@@ -1502,7 +1496,7 @@
final int taskId = appToken.mTask.mTaskId;
Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
- if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "No thumbnail header bitmap for: " + taskId);
+ if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
return;
}
// This thumbnail animation is very special, we need to have
@@ -1520,7 +1514,7 @@
PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
surfaceControl.setLayerStack(display.getLayerStack());
if (SHOW_TRANSACTIONS) {
- Slog.i(TAG_WM, " THUMBNAIL " + surfaceControl + ": CREATE");
+ Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
}
// Draw the thumbnail onto the surface
@@ -1563,7 +1557,7 @@
openingAppAnimator.thumbnailX = mTmpStartRect.left;
openingAppAnimator.thumbnailY = mTmpStartRect.top;
} catch (Surface.OutOfResourcesException e) {
- Slog.e(TAG_WM, "Can't allocate thumbnail/Canvas surface w="
+ Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
+ dirty.width() + " h=" + dirty.height(), e);
openingAppAnimator.clearThumbnail();
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8114031..c186a12 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -602,7 +602,6 @@
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
- InputMethodManagerService imm = null;
WallpaperManagerService wallpaper = null;
LocationManagerService location = null;
CountryDetectorService countryDetector = null;
@@ -613,14 +612,7 @@
// Bring up services needed for UI.
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
- traceBeginAndSlog("StartInputMethodManagerService");
- try {
- imm = new InputMethodManagerService(context);
- ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
- } catch (Throwable e) {
- reportWtf("starting Input Manager Service", e);
- }
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+ mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
traceBeginAndSlog("StartAccessibilityManagerService");
try {
@@ -1207,7 +1199,6 @@
final ConnectivityService connectivityF = connectivity;
final NetworkScoreService networkScoreF = networkScore;
final WallpaperManagerService wallpaperF = wallpaper;
- final InputMethodManagerService immF = imm;
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
@@ -1304,11 +1295,6 @@
reportWtf("Notifying WallpaperService running", e);
}
try {
- if (immF != null) immF.systemRunning(statusBarF);
- } catch (Throwable e) {
- reportWtf("Notifying InputMethodService running", e);
- }
- try {
if (locationF != null) locationF.systemRunning();
} catch (Throwable e) {
reportWtf("Notifying Location Service running", e);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4253cd4..f2949bf4 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -558,6 +558,7 @@
}
mRealTimeSnapshot = actualRealtime;
mSystemTimeSnapshot = actualSystemTime;
+ postCheckIdleStates(UserHandle.USER_ALL);
}
return actualSystemTime;
}
@@ -602,7 +603,7 @@
|| event.mEventType == Event.SYSTEM_INTERACTION
|| event.mEventType == Event.USER_INTERACTION)) {
if (previouslyIdle) {
- // Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
+ //Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ 0, event.mPackage));
notifyBatteryStats(event.mPackage, userId, false);
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3e30188..497864e8 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -397,27 +397,23 @@
/**
* Broadcast intent action for letting custom component know to show the missed call
- * notification.
- * @hide
+ * notification. If no custom component exists then this is sent to the default dialer which
+ * should post a missed-call notification.
*/
- @SystemApi
public static final String ACTION_SHOW_MISSED_CALLS_NOTIFICATION =
"android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
/**
- * The number of calls associated with the notification.
- * @hide
+ * The number of calls associated with the notification. If the number is zero then the missed
+ * call notification should be dismissed.
*/
- @SystemApi
public static final String EXTRA_NOTIFICATION_COUNT =
"android.telecom.extra.NOTIFICATION_COUNT";
/**
* The number associated with the missed calls. This number is only relevant
* when EXTRA_NOTIFICATION_COUNT is 1.
- * @hide
*/
- @SystemApi
public static final String EXTRA_NOTIFICATION_PHONE_NUMBER =
"android.telecom.extra.NOTIFICATION_PHONE_NUMBER";
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 364a55b..f3a9ea3 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -56,6 +56,7 @@
Maybe<std::string> generateProguardRulesPath;
bool noAutoVersion = false;
bool staticLib = false;
+ bool generateNonFinalIds = false;
bool verbose = false;
bool outputToDirectory = false;
bool autoAddOverlay = false;
@@ -835,7 +836,7 @@
JavaClassGeneratorOptions options;
options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
- if (mOptions.staticLib) {
+ if (mOptions.staticLib || mOptions.generateNonFinalIds) {
options.useFinal = false;
}
@@ -933,6 +934,9 @@
.optionalFlag("--version-name", "Version name to inject into the AndroidManifest.xml "
"if none is present", &versionName)
.optionalSwitch("--static-lib", "Generate a static Android library", &options.staticLib)
+ .optionalSwitch("--non-final-ids", "Generates R.java without the final modifier.\n"
+ "This is implied when --static-lib is specified.",
+ &options.generateNonFinalIds)
.optionalFlag("--private-symbols", "Package name to use when generating R.java for "
"private symbols.\n"
"If not specified, public and private symbols will use the application's "
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 769285f..7b8e29a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -148,7 +148,7 @@
@Override
public boolean performDrag(IWindow window, IBinder dragToken,
- float touchX, float touchY, float thumbCenterX, float thumbCenterY,
+ int touchSource, float touchX, float touchY, float thumbCenterX, float thumbCenterY,
ClipData data)
throws RemoteException {
// pass for now
diff --git a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
deleted file mode 100644
index f29c5c0..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 libcore.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.GregorianCalendar;
-
-/**
- * Delegate used to provide alternate implementation of select methods in {@link ZoneInfo.WallTime}
- */
-public class ZoneInfo_WallTime_Delegate {
-
- @LayoutlibDelegate
- static GregorianCalendar createGregorianCalendar() {
- return new GregorianCalendar();
- }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 87f6106..d106592 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -224,7 +224,6 @@
"libcore.io.MemoryMappedFile#mmapRO",
"libcore.io.MemoryMappedFile#close",
"libcore.io.MemoryMappedFile#bigEndianIterator",
- "libcore.util.ZoneInfo$WallTime#createGregorianCalendar",
};
/**