diff options
298 files changed, 7269 insertions, 2225 deletions
diff --git a/api/current.txt b/api/current.txt index a1f2acf..0d1cee4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3792,7 +3792,6 @@ package android.app { public class ActivityOptions { method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int); - method public static deprecated android.app.ActivityOptions makeLaunchTaskBehindAnimation(); method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String); method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.util.Pair<android.view.View, java.lang.String>...); @@ -5510,7 +5509,6 @@ package android.app.admin { field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION"; field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN"; field public static final java.lang.String EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE = "android.app.extra.PROVISIONING_ADMIN_EXTRAS_BUNDLE"; - field public static final java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "android.app.extra.PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"; @@ -5526,8 +5524,8 @@ package android.app.admin { field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_PORT = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT"; field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE"; field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID"; - field public static int FLAG_MANAGED_CAN_ACCESS_PARENT; - field public static int FLAG_PARENT_CAN_ACCESS_MANAGED; + field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2 + field public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 1; // 0x1 field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0 field public static final int KEYGUARD_DISABLE_FINGERPRINT = 32; // 0x20 @@ -8617,21 +8615,16 @@ package android.content.pm { public class LauncherApps { method public void addCallback(android.content.pm.LauncherApps.Callback); - method public void addCallback(android.content.pm.LauncherApps.Callback, android.os.Handler); - method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback); - method public void addOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback, android.os.Handler); method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(java.lang.String, android.os.UserHandle); method public boolean isActivityEnabled(android.content.ComponentName, android.os.UserHandle); - method public boolean isActivityEnabledForProfile(android.content.ComponentName, android.os.UserHandle); method public boolean isPackageEnabled(java.lang.String, android.os.UserHandle); - method public boolean isPackageEnabledForProfile(java.lang.String, android.os.UserHandle); + method public void registerCallback(android.content.pm.LauncherApps.Callback); + method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler); method public void removeCallback(android.content.pm.LauncherApps.Callback); - method public void removeOnAppsChangedCallback(android.content.pm.LauncherApps.OnAppsChangedCallback); method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle); - method public void showAppDetailsForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); - method public void startActivityForProfile(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle); + method public void unregisterCallback(android.content.pm.LauncherApps.Callback); } public static abstract class LauncherApps.Callback { @@ -8643,10 +8636,6 @@ package android.content.pm { method public abstract void onPackagesUnavailable(java.lang.String[], android.os.UserHandle, boolean); } - public static abstract class LauncherApps.OnAppsChangedCallback extends android.content.pm.LauncherApps.Callback { - ctor public LauncherApps.OnAppsChangedCallback(); - } - public class PackageInfo implements android.os.Parcelable { ctor public PackageInfo(); method public int describeContents(); @@ -8901,6 +8890,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_FAKETOUCH = "android.hardware.faketouch"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_DISTINCT = "android.hardware.faketouch.multitouch.distinct"; field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand"; + field public static final java.lang.String FEATURE_GAMEPAD = "android.hardware.gamepad"; field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen"; field public static final java.lang.String FEATURE_INPUT_METHODS = "android.software.input_methods"; field public static final java.lang.String FEATURE_LEANBACK = "android.software.leanback"; @@ -8917,6 +8907,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_PRINTING = "android.software.print"; field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape"; field public static final java.lang.String FEATURE_SCREEN_PORTRAIT = "android.hardware.screen.portrait"; + field public static final java.lang.String FEATURE_SECURELY_REMOVES_USERS = "android.software.securely_removes_users"; field public static final java.lang.String FEATURE_SENSOR_ACCELEROMETER = "android.hardware.sensor.accelerometer"; field public static final java.lang.String FEATURE_SENSOR_AMBIENT_TEMPERATURE = "android.hardware.sensor.ambient_temperature"; field public static final java.lang.String FEATURE_SENSOR_BAROMETER = "android.hardware.sensor.barometer"; @@ -8941,6 +8932,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND = "android.hardware.touchscreen.multitouch.jazzhand"; field public static final java.lang.String FEATURE_USB_ACCESSORY = "android.hardware.usb.accessory"; field public static final java.lang.String FEATURE_USB_HOST = "android.hardware.usb.host"; + field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot"; field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch"; field public static final java.lang.String FEATURE_WEBVIEW = "android.software.webview"; field public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi"; @@ -12691,7 +12683,7 @@ package android.hardware.camera2 { method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); method public void onCaptureSequenceAborted(android.hardware.camera2.CameraCaptureSession, int); method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraCaptureSession, int, long); - method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long); + method public void onCaptureStarted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, long, long); } public static abstract class CameraCaptureSession.StateCallback { @@ -14055,6 +14047,7 @@ package android.media { field public static final int CONTENT_TYPE_UNKNOWN = 0; // 0x0 field public static final android.os.Parcelable.Creator CREATOR; field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1 + field public static final int FLAG_HW_AV_SYNC = 16; // 0x10 field public static final int USAGE_ALARM = 4; // 0x4 field public static final int USAGE_ASSISTANCE_ACCESSIBILITY = 11; // 0xb field public static final int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12; // 0xc @@ -14428,6 +14421,7 @@ package android.media { field public static final int QUALITY_CIF = 3; // 0x3 field public static final int QUALITY_HIGH = 1; // 0x1 field public static final int QUALITY_HIGH_SPEED_1080P = 2004; // 0x7d4 + field public static final int QUALITY_HIGH_SPEED_2160P = 2005; // 0x7d5 field public static final int QUALITY_HIGH_SPEED_480P = 2002; // 0x7d2 field public static final int QUALITY_HIGH_SPEED_720P = 2003; // 0x7d3 field public static final int QUALITY_HIGH_SPEED_HIGH = 2001; // 0x7d1 @@ -14672,7 +14666,7 @@ package android.media { } public static final class MediaCodec.CodecException extends java.lang.IllegalStateException { - method public int getErrorCode(); + method public java.lang.String getDiagnosticInfo(); method public boolean isRecoverable(); method public boolean isTransient(); } @@ -14680,6 +14674,7 @@ package android.media { public static final class MediaCodec.CryptoException extends java.lang.RuntimeException { ctor public MediaCodec.CryptoException(int, java.lang.String); method public int getErrorCode(); + field public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; // 0x4 field public static final int ERROR_KEY_EXPIRED = 2; // 0x2 field public static final int ERROR_NO_KEY = 1; // 0x1 field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3 @@ -15009,7 +15004,7 @@ package android.media { public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException { ctor public MediaDrm.MediaDrmStateException(int, java.lang.String); - method public int getErrorCode(); + method public java.lang.String getDiagnosticInfo(); } public static abstract interface MediaDrm.OnEventListener { @@ -22508,6 +22503,7 @@ package android.os { field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources"; field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts"; field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media"; + field public static final java.lang.String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam"; field public static final java.lang.String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls"; field public static final java.lang.String DISALLOW_REMOVE_USER = "no_remove_user"; field public static final java.lang.String DISALLOW_SHARE_LOCATION = "no_share_location"; @@ -23704,7 +23700,6 @@ package android.provider { field public static final java.lang.String DURATION = "duration"; field public static final java.lang.String EXTRA_CALL_TYPE_FILTER = "android.provider.extra.CALL_TYPE_FILTER"; field public static final java.lang.String FEATURES = "features"; - field public static final int FEATURES_NONE = 0; // 0x0 field public static final int FEATURES_VIDEO = 1; // 0x1 field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location"; field public static final int INCOMING_TYPE = 1; // 0x1 @@ -27275,6 +27270,7 @@ package android.service.wallpaper { method public android.view.SurfaceHolder getSurfaceHolder(); method public boolean isPreview(); method public boolean isVisible(); + method public void onApplyWindowInsets(android.view.WindowInsets); method public android.os.Bundle onCommand(java.lang.String, int, int, int, android.os.Bundle, boolean); method public void onCreate(android.view.SurfaceHolder); method public void onDesiredSizeChanged(int, int); @@ -28222,7 +28218,6 @@ package android.telecomm { method public int describeContents(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; - field public static final int ROUTE_ALL = 15; // 0xf field public static final int ROUTE_BLUETOOTH = 2; // 0x2 field public static final int ROUTE_EARPIECE = 1; // 0x1 field public static final int ROUTE_SPEAKER = 8; // 0x8 @@ -28239,7 +28234,7 @@ package android.telecomm { method public final void destroy(); method public final int getCapabilities(); method public final java.util.List<android.telecomm.Connection> getConnections(); - method public final android.telecomm.PhoneAccountHandle getPhoneAccount(); + method public final android.telecomm.PhoneAccountHandle getPhoneAccountHandle(); method public final int getState(); method public void onDisconnect(); method public void onHold(); @@ -28314,12 +28309,11 @@ package android.telecomm { } public final class ConnectionRequest implements android.os.Parcelable { - ctor public ConnectionRequest(android.telecomm.PhoneAccountHandle, android.net.Uri, int, android.os.Bundle); + ctor public ConnectionRequest(android.telecomm.PhoneAccountHandle, android.net.Uri, android.os.Bundle); method public int describeContents(); method public android.telecomm.PhoneAccountHandle getAccountHandle(); + method public android.net.Uri getAddress(); method public android.os.Bundle getExtras(); - method public android.net.Uri getHandle(); - method public int getHandlePresentation(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; } @@ -28350,16 +28344,16 @@ package android.telecomm { } public class PhoneAccount implements android.os.Parcelable { - method public static android.telecomm.PhoneAccount.Builder builder(); + method public static android.telecomm.PhoneAccount.Builder builder(android.telecomm.PhoneAccountHandle, java.lang.CharSequence); method public int describeContents(); method public android.telecomm.PhoneAccountHandle getAccountHandle(); + method public android.net.Uri getAddress(); method public int getCapabilities(); - method public android.net.Uri getHandle(); method public android.graphics.drawable.Drawable getIcon(android.content.Context); method public int getIconResId(); method public java.lang.CharSequence getLabel(); method public java.lang.CharSequence getShortDescription(); - method public java.lang.String getSubscriptionNumber(); + method public android.net.Uri getSubscriptionAddress(); method public java.util.List<java.lang.String> getSupportedUriSchemes(); method public boolean supportsUriScheme(java.lang.String); method public void writeToParcel(android.os.Parcel, int); @@ -28372,17 +28366,14 @@ package android.telecomm { } public static class PhoneAccount.Builder { - ctor public PhoneAccount.Builder(); + ctor public PhoneAccount.Builder(android.telecomm.PhoneAccountHandle, java.lang.CharSequence); method public android.telecomm.PhoneAccount build(); - method public android.telecomm.PhoneAccount.Builder withAccountHandle(android.telecomm.PhoneAccountHandle); - method public android.telecomm.PhoneAccount.Builder withCapabilities(int); - method public android.telecomm.PhoneAccount.Builder withHandle(android.net.Uri); - method public android.telecomm.PhoneAccount.Builder withIconResId(int); - method public android.telecomm.PhoneAccount.Builder withLabel(java.lang.CharSequence); - method public android.telecomm.PhoneAccount.Builder withShortDescription(java.lang.CharSequence); - method public android.telecomm.PhoneAccount.Builder withSubscriptionNumber(java.lang.String); - method public android.telecomm.PhoneAccount.Builder withSupportedUriScheme(java.lang.String); - method public android.telecomm.PhoneAccount.Builder withSupportedUriSchemes(java.util.List<java.lang.String>); + method public android.telecomm.PhoneAccount.Builder setAddress(android.net.Uri); + method public android.telecomm.PhoneAccount.Builder setCapabilities(int); + method public android.telecomm.PhoneAccount.Builder setIconResId(int); + method public android.telecomm.PhoneAccount.Builder setShortDescription(java.lang.CharSequence); + method public android.telecomm.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri); + method public android.telecomm.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>); } public class PhoneAccountHandle implements android.os.Parcelable { @@ -28497,11 +28488,11 @@ package android.telecomm { public final class StatusHints implements android.os.Parcelable { ctor public StatusHints(android.content.ComponentName, java.lang.CharSequence, int, android.os.Bundle); method public int describeContents(); - method public android.content.ComponentName getComponentName(); method public android.os.Bundle getExtras(); method public android.graphics.drawable.Drawable getIcon(android.content.Context); method public int getIconResId(); method public java.lang.CharSequence getLabel(); + method public android.content.ComponentName getPackageName(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; } @@ -28895,8 +28886,6 @@ package android.telephony { method public void downloadMultimediaMessage(java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent); method public android.os.Bundle getCarrierConfigValues(); method public static android.telephony.SmsManager getDefault(); - method public static android.telephony.SmsManager getSmsManagerUsingSubId(long); - method public long getSubId(); method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent); method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent); method public void sendMultimediaMessage(android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent); @@ -29048,7 +29037,6 @@ package android.telephony { method public java.lang.String sendEnvelopeWithStatus(java.lang.String); method public boolean setGlobalPreferredNetworkType(); method public void setLine1NumberForDisplay(java.lang.String, java.lang.String); - method public void setLine1NumberForDisplay(long, java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; @@ -34990,12 +34978,18 @@ package android.view { public final class WindowInsets { ctor public WindowInsets(android.view.WindowInsets); + method public android.view.WindowInsets consumeStableInsets(); method public android.view.WindowInsets consumeSystemWindowInsets(); + method public int getStableInsetBottom(); + method public int getStableInsetLeft(); + method public int getStableInsetRight(); + method public int getStableInsetTop(); method public int getSystemWindowInsetBottom(); method public int getSystemWindowInsetLeft(); method public int getSystemWindowInsetRight(); method public int getSystemWindowInsetTop(); method public boolean hasInsets(); + method public boolean hasStableInsets(); method public boolean hasSystemWindowInsets(); method public boolean isConsumed(); method public boolean isRound(); diff --git a/api/removed.txt b/api/removed.txt index 3c16276..c8a3b4b 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -22,14 +22,6 @@ package android.os { } -package android.service.notification { - - public static class NotificationListenerService.Ranking { - method public boolean meetsInterruptionFilter(); - } - -} - package android.view { public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable { diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl index 5f7a17d..27a03b6 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl @@ -54,6 +54,10 @@ interface IAccessibilityServiceConnection { int action, in Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId); + boolean computeClickPointInScreen(int accessibilityWindowId, long accessibilityNodeId, + int interactionId, IAccessibilityInteractionConnectionCallback callback, + long threadId); + AccessibilityWindowInfo getWindow(int windowId); List<AccessibilityWindowInfo> getWindows(); diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index f4e4671..25417ed 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -92,21 +92,27 @@ public class AnimatorInflater { */ public static Animator loadAnimator(Resources resources, Theme theme, int id) throws NotFoundException { + return loadAnimator(resources, theme, id, 1); + } + + /** @hide */ + public static Animator loadAnimator(Resources resources, Theme theme, int id, + float pathErrorScale) throws NotFoundException { XmlResourceParser parser = null; try { parser = resources.getAnimation(id); - return createAnimatorFromXml(resources, theme, parser); + return createAnimatorFromXml(resources, theme, parser, pathErrorScale); } catch (XmlPullParserException ex) { Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + - Integer.toHexString(id)); + Integer.toHexString(id)); rnf.initCause(ex); throw rnf; } catch (IOException ex) { Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + - Integer.toHexString(id)); + Integer.toHexString(id)); rnf.initCause(ex); throw rnf; } finally { @@ -177,7 +183,7 @@ public class AnimatorInflater { } if (animator == null) { animator = createAnimatorFromXml(context.getResources(), - context.getTheme(), parser); + context.getTheme(), parser, 1f); } if (animator == null) { @@ -248,9 +254,11 @@ public class AnimatorInflater { * @param arrayAnimator Incoming typed array for Animator's attributes. * @param arrayObjectAnimator Incoming typed array for Object Animator's * attributes. + * @param pixelSize The relative pixel size, used to calculate the + * maximum error for path animations. */ private static void parseAnimatorFromTypeArray(ValueAnimator anim, - TypedArray arrayAnimator, TypedArray arrayObjectAnimator) { + TypedArray arrayAnimator, TypedArray arrayObjectAnimator, float pixelSize) { long duration = arrayAnimator.getInt(R.styleable.Animator_duration, 300); long startDelay = arrayAnimator.getInt(R.styleable.Animator_startOffset, 0); @@ -303,7 +311,7 @@ public class AnimatorInflater { } if (arrayObjectAnimator != null) { - setupObjectAnimator(anim, arrayObjectAnimator, getFloats); + setupObjectAnimator(anim, arrayObjectAnimator, getFloats, pixelSize); } } @@ -351,9 +359,11 @@ public class AnimatorInflater { * @param anim The target Animator which will be updated. * @param arrayObjectAnimator TypedArray for the ObjectAnimator. * @param getFloats True if the value type is float. + * @param pixelSize The relative pixel size, used to calculate the + * maximum error for path animations. */ private static void setupObjectAnimator(ValueAnimator anim, TypedArray arrayObjectAnimator, - boolean getFloats) { + boolean getFloats, float pixelSize) { ObjectAnimator oa = (ObjectAnimator) anim; String pathData = arrayObjectAnimator.getString(R.styleable.PropertyAnimator_pathData); @@ -370,7 +380,8 @@ public class AnimatorInflater { + " propertyXName or propertyYName is needed for PathData"); } else { Path path = PathParser.createPathFromPathData(pathData); - PathKeyframes keyframeSet = KeyframeSet.ofPath(path); + float error = 0.5f * pixelSize; // max half a pixel error + PathKeyframes keyframeSet = KeyframeSet.ofPath(path, error); Keyframes xKeyframes; Keyframes yKeyframes; if (getFloats) { @@ -487,13 +498,15 @@ public class AnimatorInflater { } } - private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser) + private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, + float pixelSize) throws XmlPullParserException, IOException { - return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0); + return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0, + pixelSize); } private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, - AttributeSet attrs, AnimatorSet parent, int sequenceOrdering) + AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize) throws XmlPullParserException, IOException { Animator anim = null; @@ -513,9 +526,9 @@ public class AnimatorInflater { String name = parser.getName(); if (name.equals("objectAnimator")) { - anim = loadObjectAnimator(res, theme, attrs); + anim = loadObjectAnimator(res, theme, attrs, pixelSize); } else if (name.equals("animator")) { - anim = loadAnimator(res, theme, attrs, null); + anim = loadAnimator(res, theme, attrs, null, pixelSize); } else if (name.equals("set")) { anim = new AnimatorSet(); TypedArray a; @@ -526,7 +539,8 @@ public class AnimatorInflater { } int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER); - createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering); + createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering, + pixelSize); a.recycle(); } else { throw new RuntimeException("Unknown animator name: " + parser.getName()); @@ -556,11 +570,11 @@ public class AnimatorInflater { } - private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs) - throws NotFoundException { + private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs, + float pathErrorScale) throws NotFoundException { ObjectAnimator anim = new ObjectAnimator(); - loadAnimator(res, theme, attrs, anim); + loadAnimator(res, theme, attrs, anim, pathErrorScale); return anim; } @@ -575,7 +589,7 @@ public class AnimatorInflater { * ObjectAnimator */ private static ValueAnimator loadAnimator(Resources res, Theme theme, - AttributeSet attrs, ValueAnimator anim) + AttributeSet attrs, ValueAnimator anim, float pathErrorScale) throws NotFoundException { TypedArray arrayAnimator = null; @@ -601,7 +615,7 @@ public class AnimatorInflater { anim = new ValueAnimator(); } - parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator); + parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale); final int resID = arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0); diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java index fc9bbb1..8d15db2 100644 --- a/core/java/android/animation/KeyframeSet.java +++ b/core/java/android/animation/KeyframeSet.java @@ -154,6 +154,10 @@ class KeyframeSet implements Keyframes { return new PathKeyframes(path); } + public static PathKeyframes ofPath(Path path, float error) { + return new PathKeyframes(path, error); + } + /** * Sets the TypeEvaluator to be used when calculating animated values. This object * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet, diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index ffffb6c..213c7f6 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -520,11 +520,6 @@ public class ActivityOptions { return opts; } - @Deprecated - public static ActivityOptions makeLaunchTaskBehindAnimation() { - return makeTaskLaunchBehind(); - } - /** @hide */ public boolean getLaunchTaskBehind() { return mAnimationType == ANIM_LAUNCH_TASK_BEHIND; diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index 9e80a4b..43fa3f0 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -205,6 +205,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { private boolean mIsStartingTransition; private ArrayList<GhostViewListeners> mGhostViewListeners = new ArrayList<GhostViewListeners>(); + private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>(); public ActivityTransitionCoordinator(Window window, ArrayList<String> allSharedElementNames, @@ -580,6 +581,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { mWindow = null; mSharedElements.clear(); mTransitioningViews.clear(); + mOriginalAlphas.clear(); mResultReceiver = null; mPendingTransition = null; mListener = null; @@ -589,10 +591,28 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { return getWindow().getTransitionBackgroundFadeDuration(); } - protected static void setTransitionAlpha(ArrayList<View> views, float alpha) { + protected void hideViews(ArrayList<View> views) { int count = views.size(); for (int i = 0; i < count; i++) { - views.get(i).setTransitionAlpha(alpha); + View view = views.get(i); + if (!mOriginalAlphas.containsKey(view)) { + mOriginalAlphas.put(view, view.getAlpha()); + } + view.setAlpha(0f); + } + } + + protected void showViews(ArrayList<View> views, boolean setTransitionAlpha) { + int count = views.size(); + for (int i = 0; i < count; i++) { + View view = views.get(i); + Float alpha = mOriginalAlphas.remove(view); + if (alpha != null) { + view.setAlpha(alpha); + } + if (setTransitionAlpha) { + view.setTransitionAlpha(1f); + } } } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index cc5c643..91a0aed 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -2121,9 +2121,7 @@ class ContextImpl extends Context { public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) throws NameNotFoundException { final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; - if ((packageName.equals("system") || packageName.equals("android")) - && user.getIdentifier() == UserHandle.getUserId( - mPackageInfo.getApplicationInfo().uid)) { + if (packageName.equals("system") || packageName.equals("android")) { return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, user, restricted, mDisplay, mOverrideConfiguration); } diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index f432c49..9c7728e 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -112,9 +112,9 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { protected void viewsReady(ArrayMap<String, View> sharedElements) { super.viewsReady(sharedElements); mIsReadyForTransition = true; - setTransitionAlpha(mSharedElements, 0); + hideViews(mSharedElements); if (getViewsTransition() != null) { - setTransitionAlpha(mTransitioningViews, 0); + hideViews(mTransitioningViews); } if (mIsReturning) { sendSharedElementDestination(); @@ -240,7 +240,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { if (!mIsCanceled) { mIsCanceled = true; if (getViewsTransition() == null || mIsViewsTransitionStarted) { - setTransitionAlpha(mSharedElements, 1); + showViews(mSharedElements, true); } else { mTransitioningViews.addAll(mSharedElements); } @@ -300,7 +300,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { // Now start shared element transition ArrayList<View> sharedElementSnapshots = createSnapshots(sharedElementState, mSharedElementNames); - setTransitionAlpha(mSharedElements, 1); + showViews(mSharedElements, true); scheduleSetSharedElementEnd(sharedElementSnapshots); ArrayList<SharedElementOriginalState> originalImageViewState = setSharedElementState(sharedElementState, sharedElementSnapshots); @@ -411,7 +411,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { @Override public void onTransitionStart(Transition transition) { mEnterViewsTransition = transition; - setTransitionAlpha(mTransitioningViews, 1); + showViews(mTransitioningViews, false); super.onTransitionStart(transition); } diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java index a59a927..e85ec63 100644 --- a/core/java/android/app/ExitTransitionCoordinator.java +++ b/core/java/android/app/ExitTransitionCoordinator.java @@ -126,8 +126,8 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { } public void resetViews() { - setTransitionAlpha(mTransitioningViews, 1); - setTransitionAlpha(mSharedElements, 1); + showViews(mTransitioningViews, true); + showViews(mSharedElements, true); mIsHidden = true; if (!mIsReturning && getDecor() != null) { getDecor().suppressLayout(false); @@ -187,7 +187,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { private void hideSharedElements() { moveSharedElementsFromOverlay(); if (!mIsHidden) { - setTransitionAlpha(mSharedElements, 0); + hideViews(mSharedElements); } mSharedElementsHidden = true; finishIfNecessary(); @@ -296,7 +296,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { transition.removeListener(this); exitTransitionComplete(); if (mIsHidden) { - setTransitionAlpha(mTransitioningViews, 1); + showViews(mTransitioningViews, true); } if (mSharedElementBundle != null) { delayCancel(); @@ -323,7 +323,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator { transition.removeListener(this); sharedElementTransitionComplete(); if (mIsHidden) { - setTransitionAlpha(mSharedElements, 1); + showViews(mSharedElements, true); } } }); diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 181eb63..3b5900b 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -16,6 +16,7 @@ package android.app; +import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.app.IWallpaperManagerCallback; @@ -73,6 +74,11 @@ interface IWallpaperManager { int getHeightHint(); /** + * Sets extra padding that we would like the wallpaper to have outside of the display. + */ + void setDisplayPadding(in Rect padding); + + /** * Returns the name of the wallpaper. Private API. */ String getName(); diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 1083943..f9e4895 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -545,8 +545,26 @@ public class Notification implements Parcelable */ public int visibility; + /** + * Notification visibility: Show this notification in its entirety on all lockscreens. + * + * {@see #visibility} + */ public static final int VISIBILITY_PUBLIC = 1; + + /** + * Notification visibility: Show this notification on all lockscreens, but conceal sensitive or + * private information on secure lockscreens. + * + * {@see #visibility} + */ public static final int VISIBILITY_PRIVATE = 0; + + /** + * Notification visibility: Do not reveal any part of this notification on a secure lockscreen. + * + * {@see #visibility} + */ public static final int VISIBILITY_SECRET = -1; /** @@ -824,6 +842,13 @@ public class Notification implements Parcelable public static final String EXTRA_COMPACT_ACTIONS = "android.compactActions"; /** + * {@link #extras} key: the user that built the notification. + * + * @hide + */ + public static final String EXTRA_ORIGINATING_USERID = "android.originatingUserId"; + + /** * Value for {@link #EXTRA_AS_HEADS_UP} that indicates this notification should not be * displayed in the heads up space. * @@ -1862,6 +1887,11 @@ public class Notification implements Parcelable private int mColor = COLOR_DEFAULT; /** + * The user that built the notification originally. + */ + private int mOriginatingUserId; + + /** * Contains extras related to rebuilding during the build phase. */ private Bundle mRebuildBundle = new Bundle(); @@ -2581,7 +2611,7 @@ public class Notification implements Parcelable // Note: This assumes that the current user can read the profile badge of the // originating user. return mContext.getPackageManager().getUserBadgeForDensity( - new UserHandle(mContext.getUserId()), 0); + new UserHandle(mOriginatingUserId), 0); } private Bitmap getProfileBadge() { @@ -2721,9 +2751,9 @@ public class Notification implements Parcelable } else { contentView.setViewVisibility(R.id.text2, View.GONE); if (hasProgress && (mProgressMax != 0 || mProgressIndeterminate)) { + contentView.setViewVisibility(R.id.progress, View.VISIBLE); contentView.setProgressBar( R.id.progress, mProgressMax, mProgress, mProgressIndeterminate); - contentView.setViewVisibility(R.id.progress, View.VISIBLE); showLine2 = true; } else { contentView.setViewVisibility(R.id.progress, View.GONE); @@ -3052,6 +3082,7 @@ public class Notification implements Parcelable */ public void populateExtras(Bundle extras) { // Store original information used in the construction of this object + extras.putInt(EXTRA_ORIGINATING_USERID, mOriginatingUserId); extras.putParcelable(EXTRA_REBUILD_CONTEXT_APPLICATION_INFO, mContext.getApplicationInfo()); extras.putCharSequence(EXTRA_TITLE, mContentTitle); @@ -3283,6 +3314,7 @@ public class Notification implements Parcelable // Extras. Bundle extras = n.extras; + mOriginatingUserId = extras.getInt(EXTRA_ORIGINATING_USERID); mContentTitle = extras.getCharSequence(EXTRA_TITLE); mContentText = extras.getCharSequence(EXTRA_TEXT); mSubText = extras.getCharSequence(EXTRA_SUB_TEXT); @@ -3315,6 +3347,7 @@ public class Notification implements Parcelable * object. */ public Notification build() { + mOriginatingUserId = mContext.getUserId(); mHasThreeLines = hasThreeLines(); Notification n = buildUnstyled(); @@ -3386,8 +3419,16 @@ public class Notification implements Parcelable */ public static abstract class Style { private CharSequence mBigContentTitle; - private CharSequence mSummaryText = null; - private boolean mSummaryTextSet = false; + + /** + * @hide + */ + protected CharSequence mSummaryText = null; + + /** + * @hide + */ + protected boolean mSummaryTextSet = false; protected Builder mBuilder; @@ -3679,6 +3720,11 @@ public class Notification implements Parcelable * @see Notification#bigContentView */ public static class BigTextStyle extends Style { + + private static final int MAX_LINES = 13; + private static final int LINES_CONSUMED_BY_ACTIONS = 3; + private static final int LINES_CONSUMED_BY_SUMMARY = 2; + private CharSequence mBigText; public BigTextStyle() { @@ -3745,6 +3791,7 @@ public class Notification implements Parcelable contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText)); contentView.setViewVisibility(R.id.big_text, View.VISIBLE); + contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines()); contentView.setViewVisibility(R.id.text2, View.GONE); applyTopPadding(contentView); @@ -3756,6 +3803,24 @@ public class Notification implements Parcelable return contentView; } + private int calculateMaxLines() { + int lineCount = MAX_LINES; + boolean hasActions = mBuilder.mActions.size() > 0; + boolean hasSummary = (mSummaryTextSet ? mSummaryText : mBuilder.mSubText) != null; + if (hasActions) { + lineCount -= LINES_CONSUMED_BY_ACTIONS; + } + if (hasSummary) { + lineCount -= LINES_CONSUMED_BY_SUMMARY; + } + + // If we have less top padding at the top, we can fit less lines. + if (!mBuilder.mHasThreeLines) { + lineCount--; + } + return lineCount; + } + /** * @hide */ diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 48ff5b6..8bfe6d3 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.SystemApi; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; @@ -951,6 +952,48 @@ public class WallpaperManager { } /** + * Specify extra padding that the wallpaper should have outside of the display. + * That is, the given padding supplies additional pixels the wallpaper should extend + * outside of the display itself. + * @param padding The number of pixels the wallpaper should extend beyond the display, + * on its left, top, right, and bottom sides. + * @hide + */ + @SystemApi + public void setDisplayPadding(Rect padding) { + try { + if (sGlobals.mService == null) { + Log.w(TAG, "WallpaperService not running"); + } else { + sGlobals.mService.setDisplayPadding(padding); + } + } catch (RemoteException e) { + // Ignore + } + } + + /** + * Apply a raw offset to the wallpaper window. Should only be used in + * combination with {@link #setDisplayPadding(android.graphics.Rect)} when you + * have ensured that the wallpaper will extend outside of the display area so that + * it can be moved without leaving part of the display uncovered. + * @param x The offset, in pixels, to apply to the left edge. + * @param y The offset, in pixels, to apply to the top edge. + * @hide + */ + @SystemApi + public void setDisplayOffset(IBinder windowToken, int x, int y) { + try { + //Log.v(TAG, "Sending new wallpaper display offsets from app..."); + WindowManagerGlobal.getWindowSession().setWallpaperDisplayOffset( + windowToken, x, y); + //Log.v(TAG, "...app returning after sending display offset!"); + } catch (RemoteException e) { + // Ignore. + } + } + + /** * Set the position of the current wallpaper within any larger space, when * that wallpaper is visible behind the given window. The X and Y offsets * are floating point numbers ranging from 0 to 1, representing where the diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 112fc82..5b02313 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -97,8 +97,7 @@ public class DevicePolicyManager { * Provisioning adds a managed profile and sets the mdm as the profile owner who has full * control over the profile * - * <p>This intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} - * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME} and {@link #EXTRA_DEVICE_ADMIN}. + * <p>This intent must contain the extra {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME}. * * <p> When managed provisioning has completed, an intent of the type * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the @@ -142,18 +141,15 @@ public class DevicePolicyManager { = "android.app.extra.deviceAdminPackageName"; /** - * A String extra holding the default name of the profile that is created during managed profile - * provisioning. + * A String extra that, holds the email address of the account which a managed profile is + * created for. Used with {@link #ACTION_PROVISION_MANAGED_PROFILE} and + * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE}. * - * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE} - */ - public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME - = "android.app.extra.PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME"; - - /** - * A bundle key, used in the bundle extra {@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}. The - * corresponding value holds the email address of the account which the managed profile is - * created for. + * <p> If the {@link #ACTION_PROVISION_MANAGED_PROFILE} intent that starts managed provisioning + * contains this extra, it is forwarded in the + * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} intent to the mobile + * device management application that was set as the profile owner during provisioning. + * It is usually used to avoid that the user has to enter their email address twice. */ public static final String KEY_PROVISIONING_EMAIL_ADDRESS = "android.app.key.PROVISIONING_EMAIL_ADDRESS"; @@ -441,13 +437,13 @@ public class DevicePolicyManager { * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from a * managed profile to its parent. */ - public static int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001; + public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001; /** * Flag used by {@link #addCrossProfileIntentFilter} to allow access of certain intents from the * parent to its managed profile. */ - public static int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002; + public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002; /** * Return true if the given administrator component is currently diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index 1bb4eba..9151a16 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -218,6 +218,7 @@ public class BackupManager { */ @SystemApi public boolean isBackupEnabled() { + checkServiceBinder(); if (sService != null) { try { return sService.isBackupEnabled(); diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index fde8b2e..2853c58 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -639,12 +639,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 { * @param authorities the semi-colon separated authorities of the ContentProvider. */ protected final void setAuthorities(String authorities) { - if (authorities.indexOf(';') == -1) { - mAuthority = authorities; - mAuthorities = null; - } else { - mAuthority = null; - mAuthorities = authorities.split(";"); + if (authorities != null) { + if (authorities.indexOf(';') == -1) { + mAuthority = authorities; + mAuthorities = null; + } else { + mAuthority = null; + mAuthorities = authorities.split(";"); + } } } @@ -653,9 +655,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 { if (mAuthority != null) { return mAuthority.equals(authority); } - int length = mAuthorities.length; - for (int i = 0; i < length; i++) { - if (mAuthorities[i].equals(authority)) return true; + if (mAuthorities != null) { + int length = mAuthorities.length; + for (int i = 0; i < length; i++) { + if (mAuthorities[i].equals(authority)) return true; + } } return false; } diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index f9370b3..d49bc50 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -278,21 +278,21 @@ public class LauncherApps { /** - * Adds a callback for changes to packages in current and managed profiles. + * Registers a callback for changes to packages in current and managed profiles. * - * @param callback The callback to add. + * @param callback The callback to register. */ - public void addCallback(Callback callback) { - addCallback(callback, null); + public void registerCallback(Callback callback) { + registerCallback(callback, null); } /** - * Adds a callback for changes to packages in current and managed profiles. + * Registers a callback for changes to packages in current and managed profiles. * - * @param callback The callback to add. + * @param callback The callback to register. * @param handler that should be used to post callbacks on, may be null. */ - public void addCallback(Callback callback, Handler handler) { + public void registerCallback(Callback callback, Handler handler) { synchronized (this) { if (callback != null && !mCallbacks.contains(callback)) { boolean addedFirstCallback = mCallbacks.size() == 0; @@ -308,12 +308,12 @@ public class LauncherApps { } /** - * Removes a callback that was previously added. + * Unregisters a callback that was previously registered. * - * @param callback The callback to remove. - * @see #addCallback(Callback) + * @param callback The callback to unregister. + * @see #registerCallback(Callback) */ - public void removeCallback(Callback callback) { + public void unregisterCallback(Callback callback) { synchronized (this) { removeCallbackLocked(callback); if (mCallbacks.size() == 0) { @@ -500,44 +500,12 @@ public class LauncherApps { } } - /** Remove after unbundled apps have migrated STOP SHIP */ - public static abstract class OnAppsChangedCallback extends Callback { - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public void addOnAppsChangedCallback(OnAppsChangedCallback callback) { - addCallback(callback, null); - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public void addOnAppsChangedCallback(OnAppsChangedCallback callback, Handler handler) { - addCallback(callback, handler); - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public void removeOnAppsChangedCallback(OnAppsChangedCallback callback) { - removeCallback(callback); - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public void startActivityForProfile(ComponentName component, UserHandle user, Rect sourceBounds, - Bundle opts) { - startMainActivity(component, user, sourceBounds, opts); - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public void showAppDetailsForProfile(ComponentName component, UserHandle user, - Rect sourceBounds, Bundle opts) { - startAppDetailsActivity(component, user, sourceBounds, opts); - } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public boolean isPackageEnabledForProfile(String packageName, UserHandle user) { - return isPackageEnabled(packageName, user); + /** STOPSHIP remove when launcher 3 has been updated */ + public void addCallback(Callback callback) { + registerCallback(callback); } - - /** Remove after unbundled apps have migrated STOP SHIP */ - public boolean isActivityEnabledForProfile(ComponentName component, UserHandle user) { - return isActivityEnabled(component, user); + /** STOPSHIP remove when launcher 3 has been updated */ + public void removeCallback(Callback callback) { + unregisterCallback(callback); } } diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 0a211cf..06d4c4a 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -285,6 +285,9 @@ public class PackageInstaller { * * @throws IOException if parameters were unsatisfiable, such as lack of * disk space or unavailable media. + * @throws SecurityException when installation services are unavailable, + * such as when called from a restricted user. + * @throws IllegalArgumentException when {@link SessionParams} is invalid. * @return positive, non-zero unique ID that represents the created session. * This ID remains consistent across device reboots until the * session is finalized. IDs are not reused during a given boot. @@ -303,6 +306,11 @@ public class PackageInstaller { /** * Open an existing session to actively perform work. To succeed, the caller * must be the owner of the install session. + * + * @throws IOException if parameters were unsatisfiable, such as lack of + * disk space or unavailable media. + * @throws SecurityException when the caller does not own the session, or + * the session is invalid. */ public @NonNull Session openSession(int sessionId) throws IOException { try { @@ -319,6 +327,9 @@ public class PackageInstaller { * Update the icon representing the app being installed in a specific * session. This should be roughly * {@link ActivityManager#getLauncherLargeIconSize()} in both dimensions. + * + * @throws SecurityException when the caller does not own the session, or + * the session is invalid. */ public void updateSessionAppIcon(int sessionId, @Nullable Bitmap appIcon) { try { @@ -331,6 +342,9 @@ public class PackageInstaller { /** * Update the label representing the app being installed in a specific * session. + * + * @throws SecurityException when the caller does not own the session, or + * the session is invalid. */ public void updateSessionAppLabel(int sessionId, @Nullable CharSequence appLabel) { try { @@ -341,6 +355,15 @@ public class PackageInstaller { } } + /** + * Completely abandon the given session, destroying all staged data and + * rendering it invalid. Abandoned sessions will be reported to + * {@link SessionCallback} listeners as failures. This is equivalent to + * opening the session and calling {@link Session#abandon()}. + * + * @throws SecurityException when the caller does not own the session, or + * the session is invalid. + */ public void abandonSession(int sessionId) { try { mInstaller.abandonSession(sessionId); @@ -350,7 +373,11 @@ public class PackageInstaller { } /** - * Return details for a specific session. + * Return details for a specific session. No special permissions are + * required to retrieve these details. + * + * @return details for the requested session, or {@code null} if the session + * does not exist. */ public @Nullable SessionInfo getSessionInfo(int sessionId) { try { @@ -361,7 +388,7 @@ public class PackageInstaller { } /** - * Return list of all active install sessions, regardless of the installer. + * Return list of all known install sessions, regardless of the installer. */ public @NonNull List<SessionInfo> getAllSessions() { final ApplicationInfo info = mContext.getApplicationInfo(); @@ -379,7 +406,7 @@ public class PackageInstaller { } /** - * Return list of all install sessions owned by the calling app. + * Return list of all known install sessions owned by the calling app. */ public @NonNull List<SessionInfo> getMySessions() { try { @@ -547,7 +574,8 @@ public class PackageInstaller { } /** - * Register to watch for session lifecycle events. + * Register to watch for session lifecycle events. No special permissions + * are required to watch for these events. */ public void registerSessionCallback(@NonNull SessionCallback callback) { registerSessionCallback(callback, new Handler()); @@ -560,7 +588,8 @@ public class PackageInstaller { } /** - * Register to watch for session lifecycle events. + * Register to watch for session lifecycle events. No special permissions + * are required to watch for these events. * * @param handler to dispatch callback events through, otherwise uses * calling thread. @@ -593,7 +622,7 @@ public class PackageInstaller { } /** - * Unregister an existing callback. + * Unregister a previously registered callback. */ public void unregisterSessionCallback(@NonNull SessionCallback callback) { synchronized (mDelegates) { @@ -686,6 +715,12 @@ public class PackageInstaller { * start at the beginning of the file. * @param lengthBytes total size of the file being written, used to * preallocate the underlying disk space, or -1 if unknown. + * The system may clear various caches as needed to allocate + * this space. + * @throws IOException if trouble opening the file for writing, such as + * lack of disk space or unavailable media. + * @throws SecurityException if called after the session has been + * committed or abandoned. */ public @NonNull OutputStream openWrite(@NonNull String name, long offsetBytes, long lengthBytes) throws IOException { @@ -719,6 +754,9 @@ public class PackageInstaller { * <p> * This returns all names which have been previously written through * {@link #openWrite(String, long, long)} as part of this session. + * + * @throws SecurityException if called after the session has been + * committed or abandoned. */ public @NonNull String[] getNames() throws IOException { try { @@ -738,6 +776,9 @@ public class PackageInstaller { * through {@link #openWrite(String, long, long)} as part of this * session. For example, this stream may be used to calculate a * {@link MessageDigest} of a written APK before committing. + * + * @throws SecurityException if called after the session has been + * committed or abandoned. */ public @NonNull InputStream openRead(@NonNull String name) throws IOException { try { @@ -759,6 +800,9 @@ public class PackageInstaller { * Once this method is called, no additional mutations may be performed * on the session. If the device reboots before the session has been * finalized, you may commit the session again. + * + * @throws SecurityException if streams opened through + * {@link #openWrite(String, long, long)} are still open. */ public void commit(@NonNull IntentSender statusReceiver) { try { @@ -783,7 +827,9 @@ public class PackageInstaller { /** * Completely abandon this session, destroying all staged data and - * rendering it invalid. + * rendering it invalid. Abandoned sessions will be reported to + * {@link SessionCallback} listeners as failures. This is equivalent to + * opening the session and calling {@link Session#abandon()}. */ public void abandon() { try { @@ -937,6 +983,18 @@ public class PackageInstaller { } /** {@hide} */ + public void setInstallFlagsInternal() { + installFlags |= PackageManager.INSTALL_INTERNAL; + installFlags &= ~PackageManager.INSTALL_EXTERNAL; + } + + /** {@hide} */ + public void setInstallFlagsExternal() { + installFlags |= PackageManager.INSTALL_EXTERNAL; + installFlags &= ~PackageManager.INSTALL_INTERNAL; + } + + /** {@hide} */ public void dump(IndentingPrintWriter pw) { pw.printPair("mode", mode); pw.printHexPair("installFlags", installFlags); diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 748fca2..5ce968b 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -201,12 +201,6 @@ public abstract class PackageManager { public static final int MATCH_DEFAULT_ONLY = 0x00010000; /** - * Resolution and querying flag: do not resolve intents cross-profile. - * @hide - */ - public static final int NO_CROSS_PROFILE = 0x00020000; - - /** * Flag for {@link addCrossProfileIntentFilter}: if this flag is set: * when resolving an intent that matches the {@link CrossProfileIntentFilter}, the current * profile will be skipped. @@ -1531,6 +1525,22 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: + * The device supports verified boot. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_VERIFIED_BOOT = "android.software.verified_boot"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: + * The device supports secure removal of users. When a user is deleted the data associated + * with that user is securely deleted and no longer available. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_SECURELY_REMOVES_USERS + = "android.software.securely_removes_users"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: * The device has a full implementation of the android.webkit.* APIs. Devices * lacking this feature will not have a functioning WebView implementation. */ @@ -1554,6 +1564,15 @@ public abstract class PackageManager { public static final String FEATURE_HDMI_CEC = "android.hardware.hdmi.cec"; /** + * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: + * The device has all of the inputs necessary to be considered a compatible game controller, or + * includes a compatible game controller in the box. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_GAMEPAD = "android.hardware.gamepad"; + + + /** * Action to external storage service to clean out removed apps. * @hide */ @@ -2431,7 +2450,6 @@ public abstract class PackageManager { * @see #MATCH_DEFAULT_ONLY * @see #GET_INTENT_FILTERS * @see #GET_RESOLVED_FILTER - * @see #NO_CROSS_PROFILE * @hide */ public abstract List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index e0fd532..ddb0a6d 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1099,9 +1099,12 @@ public class PackageParser { } } } - } catch (GeneralSecurityException | IOException | RuntimeException e) { + } catch (GeneralSecurityException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING, "Failed to collect certificates from " + apkPath, e); + } catch (IOException | RuntimeException e) { + throw new PackageParserException(INSTALL_PARSE_FAILED_NO_CERTIFICATES, + "Failed to collect certificates from " + apkPath, e); } finally { closeQuietly(jarFile); } diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index c0383a3..c03be32 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -89,6 +89,7 @@ public class UserInfo implements Parcelable { /** User is only partially created. */ public boolean partial; + public boolean guestToRemove; public UserInfo(int id, String name, int flags) { this(id, name, null, flags); @@ -147,6 +148,7 @@ public class UserInfo implements Parcelable { lastLoggedInTime = orig.lastLoggedInTime; partial = orig.partial; profileGroupId = orig.profileGroupId; + guestToRemove = orig.guestToRemove; } public UserHandle getUserHandle() { @@ -172,6 +174,7 @@ public class UserInfo implements Parcelable { dest.writeLong(lastLoggedInTime); dest.writeInt(partial ? 1 : 0); dest.writeInt(profileGroupId); + dest.writeInt(guestToRemove ? 1 : 0); } public static final Parcelable.Creator<UserInfo> CREATOR @@ -194,5 +197,6 @@ public class UserInfo implements Parcelable { lastLoggedInTime = source.readLong(); partial = source.readInt() != 0; profileGroupId = source.readInt(); + guestToRemove = source.readInt() != 0; } } diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 29e42ea..ce83028 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -483,7 +483,9 @@ public abstract class CameraCaptureSession implements AutoCloseable { * and in the buffers sent to each output Surface. These buffer * timestamps are accessible through, for example, * {@link android.media.Image#getTimestamp() Image.getTimestamp()} or - * {@link android.graphics.SurfaceTexture#getTimestamp()}.</p> + * {@link android.graphics.SurfaceTexture#getTimestamp()}. + * The frame number included is equal to the frame number that will be included in + * {@link CaptureResult#getFrameNumber}.</p> * * <p>For the simplest way to play a shutter sound camera shutter or a * video recording start/stop sound, see the @@ -494,10 +496,21 @@ public abstract class CameraCaptureSession implements AutoCloseable { * @param session the session returned by {@link CameraDevice#createCaptureSession} * @param request the request for the capture that just begun * @param timestamp the timestamp at start of capture, in nanoseconds. + * @param frameNumber the frame number for this capture * * @see android.media.MediaActionSound */ public void onCaptureStarted(CameraCaptureSession session, + CaptureRequest request, long timestamp, long frameNumber) { + // Temporary trampoline for API change transition + onCaptureStarted(session, request, timestamp); + } + + /** + * Temporary for API change transition + * @hide + */ + public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp) { // default empty implementation } diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 6d0d505..93eb3de 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -731,6 +731,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <p>List of areas to use for * metering.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -746,7 +748,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ @@ -820,6 +824,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <p>List of areas to use for focus * estimation.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -835,7 +841,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ @@ -921,6 +929,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> /** * <p>List of areas to use for illuminant * estimation.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -936,7 +946,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 754d83e..01276a2 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -582,6 +582,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>List of areas to use for * metering.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AE android.control.maxRegionsAe} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -597,7 +599,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AE * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ @@ -870,6 +874,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>List of areas to use for focus * estimation.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AF android.control.maxRegionsAf} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -885,7 +891,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AF * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ @@ -1369,6 +1377,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>List of areas to use for illuminant * estimation.</p> + * <p>Optional. Not available if {@link CameraCharacteristics#CONTROL_MAX_REGIONS_AWB android.control.maxRegionsAwb} is 0. + * Otherwise will always be present.</p> * <p>The coordinate system is based on the active pixel array, * with (0,0) being the top-left pixel in the active pixel array, and * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1, @@ -1384,7 +1394,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * outside the used {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} returned in capture result metadata, * the camera device will ignore the sections outside the region and output the * used sections in the result metadata.</p> + * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#CONTROL_MAX_REGIONS_AWB * @see CaptureRequest#SCALER_CROP_REGION * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE */ diff --git a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java index 02c3d87..c66a3a4 100644 --- a/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java +++ b/core/java/android/hardware/camera2/dispatch/MethodNameInvoker.java @@ -48,7 +48,8 @@ public class MethodNameInvoker<T> { /** * Invoke a method by its name. * - * <p>If more than one method exists in {@code targetClass}, the first method will be used.</p> + * <p>If more than one method exists in {@code targetClass}, the first method with the right + * number of arguments will be used, and later calls will all use that method.</p> * * @param methodName * The name of the method, which will be matched 1:1 to the destination method @@ -68,8 +69,9 @@ public class MethodNameInvoker<T> { Method targetMethod = mMethods.get(methodName); if (targetMethod == null) { for (Method method : mTargetClass.getMethods()) { - // TODO future: match by # of params and types of params if possible - if (method.getName().equals(methodName)) { + // TODO future: match types of params if possible + if (method.getName().equals(methodName) && + (params.length == method.getParameterTypes().length) ) { targetMethod = method; mMethods.put(methodName, targetMethod); break; diff --git a/core/java/android/hardware/camera2/impl/CallbackProxies.java b/core/java/android/hardware/camera2/impl/CallbackProxies.java index e5ddb7a..f0217ac 100644 --- a/core/java/android/hardware/camera2/impl/CallbackProxies.java +++ b/core/java/android/hardware/camera2/impl/CallbackProxies.java @@ -98,8 +98,8 @@ public class CallbackProxies { @Override public void onCaptureStarted(CameraDevice camera, - CaptureRequest request, long timestamp) { - mProxy.invoke("onCaptureStarted", camera, request, timestamp); + CaptureRequest request, long timestamp, long frameNumber) { + mProxy.invoke("onCaptureStarted", camera, request, timestamp, frameNumber); } @Override diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index d454092..f011d60 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -803,7 +803,7 @@ public class CameraDeviceImpl extends CameraDevice { * @see android.media.MediaActionSound */ public void onCaptureStarted(CameraDevice camera, - CaptureRequest request, long timestamp) { + CaptureRequest request, long timestamp, long frameNumber) { // default empty implementation } @@ -1237,8 +1237,10 @@ public class CameraDeviceImpl extends CameraDevice { @Override public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) { int requestId = resultExtras.getRequestId(); + final long frameNumber = resultExtras.getFrameNumber(); + if (DEBUG) { - Log.d(TAG, "Capture started for id " + requestId); + Log.d(TAG, "Capture started for id " + requestId + " frame number " + frameNumber); } final CaptureCallbackHolder holder; @@ -1263,7 +1265,7 @@ public class CameraDeviceImpl extends CameraDevice { holder.getCallback().onCaptureStarted( CameraDeviceImpl.this, holder.getRequest(resultExtras.getSubsequenceId()), - timestamp); + timestamp, frameNumber); } } }); diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java index a8d1018..3c0e0e4 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java @@ -675,15 +675,13 @@ public class LegacyMetadataMapper { * request.availableRequestKeys */ { - CaptureRequest.Key<?> availableKeys[] = new CaptureRequest.Key<?>[] { + CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] { CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, CaptureRequest.CONTROL_AE_LOCK, CaptureRequest.CONTROL_AE_MODE, - CaptureRequest.CONTROL_AE_REGIONS, CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, CaptureRequest.CONTROL_AF_MODE, - CaptureRequest.CONTROL_AF_REGIONS, CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AWB_LOCK, CaptureRequest.CONTROL_AWB_MODE, @@ -704,21 +702,32 @@ public class LegacyMetadataMapper { CaptureRequest.SCALER_CROP_REGION, CaptureRequest.STATISTICS_FACE_DETECT_MODE, }; - m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableKeys)); + ArrayList<CaptureRequest.Key<?>> availableKeys = + new ArrayList<CaptureRequest.Key<?>>(Arrays.asList(defaultAvailableKeys)); + + if (p.getMaxNumMeteringAreas() > 0) { + availableKeys.add(CaptureRequest.CONTROL_AE_REGIONS); + } + if (p.getMaxNumFocusAreas() > 0) { + availableKeys.add(CaptureRequest.CONTROL_AF_REGIONS); + } + + CaptureRequest.Key<?> availableRequestKeys[] = + new CaptureRequest.Key<?>[availableKeys.size()]; + availableKeys.toArray(availableRequestKeys); + m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableRequestKeys)); } /* * request.availableResultKeys */ { - CaptureResult.Key<?> availableKeys[] = new CaptureResult.Key<?>[] { + CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] { CaptureResult.CONTROL_AE_ANTIBANDING_MODE , CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION , CaptureResult.CONTROL_AE_LOCK , CaptureResult.CONTROL_AE_MODE , - CaptureResult.CONTROL_AE_REGIONS , CaptureResult.CONTROL_AF_MODE , - CaptureResult.CONTROL_AF_REGIONS , CaptureResult.CONTROL_AF_STATE , CaptureResult.CONTROL_AWB_MODE , CaptureResult.CONTROL_AWB_LOCK , @@ -737,7 +746,20 @@ public class LegacyMetadataMapper { CaptureResult.STATISTICS_FACE_DETECT_MODE , // CaptureResult.STATISTICS_FACES , }; - m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableKeys)); + List<CaptureResult.Key<?>> availableKeys = + new ArrayList<CaptureResult.Key<?>>(Arrays.asList(defaultAvailableKeys)); + + if (p.getMaxNumMeteringAreas() > 0) { + availableKeys.add(CaptureResult.CONTROL_AE_REGIONS); + } + if (p.getMaxNumFocusAreas() > 0) { + availableKeys.add(CaptureResult.CONTROL_AF_REGIONS); + } + + CaptureResult.Key<?> availableResultKeys[] = + new CaptureResult.Key<?>[availableKeys.size()]; + availableKeys.toArray(availableResultKeys); + m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableResultKeys)); } /* diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java index 090a822..ddaa6ee 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java +++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java @@ -322,7 +322,7 @@ public class LegacyResultMapper { } // control.aeRegions - { + if (p.getMaxNumMeteringAreas() > 0) { if (VERBOSE) { String meteringAreas = p.get("metering-areas"); Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas); @@ -342,7 +342,7 @@ public class LegacyResultMapper { m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode())); // control.afRegions - { + if (p.getMaxNumFocusAreas() > 0) { if (VERBOSE) { String focusAreas = p.get("focus-areas"); Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas); diff --git a/core/java/android/os/FileBridge.java b/core/java/android/os/FileBridge.java index 022a106..0acf24b 100644 --- a/core/java/android/os/FileBridge.java +++ b/core/java/android/os/FileBridge.java @@ -75,6 +75,13 @@ public class FileBridge extends Thread { return mClosed; } + public void forceClose() { + IoUtils.closeQuietly(mTarget); + IoUtils.closeQuietly(mServer); + IoUtils.closeQuietly(mClient); + mClosed = true; + } + public void setTargetFile(FileDescriptor target) { mTarget = target; } @@ -89,7 +96,6 @@ public class FileBridge extends Thread { try { while (IoBridge.read(mServer, temp, 0, MSG_LENGTH) == MSG_LENGTH) { final int cmd = Memory.peekInt(temp, 0, ByteOrder.BIG_ENDIAN); - if (cmd == CMD_WRITE) { // Shuttle data into local file int len = Memory.peekInt(temp, 4, ByteOrder.BIG_ENDIAN); @@ -118,15 +124,10 @@ public class FileBridge extends Thread { } } - } catch (ErrnoException e) { - Log.wtf(TAG, "Failed during bridge", e); - } catch (IOException e) { + } catch (ErrnoException | IOException e) { Log.wtf(TAG, "Failed during bridge", e); } finally { - IoUtils.closeQuietly(mTarget); - IoUtils.closeQuietly(mServer); - IoUtils.closeQuietly(mClient); - mClosed = true; + forceClose(); } } @@ -151,6 +152,7 @@ public class FileBridge extends Thread { writeCommandAndBlock(CMD_CLOSE, "close()"); } finally { IoBridge.closeAndSignalBlockedThreads(mClient); + IoUtils.closeQuietly(mClientPfd); } } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index c3ac012..b2ebc31 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -468,6 +468,7 @@ public class Process { * @param targetSdkVersion The target SDK version for the app. * @param seInfo null-ok SELinux information for the new process. * @param abi non-null the ABI this app should be started with. + * @param instructionSet null-ok the instruction set to use. * @param zygoteArgs Additional arguments to supply to the zygote process. * * @return An object that describes the result of the attempt to start the process. @@ -482,11 +483,12 @@ public class Process { int targetSdkVersion, String seInfo, String abi, + String instructionSet, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, debugFlags, mountExternal, targetSdkVersion, seInfo, - abi, zygoteArgs); + abi, instructionSet, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); @@ -589,6 +591,7 @@ public class Process { * @param targetSdkVersion The target SDK version for the app. * @param seInfo null-ok SELinux information for the new process. * @param abi the ABI the process should use. + * @param instructionSet null-ok the instruction set to use. * @param extraArgs Additional arguments to supply to the zygote process. * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason @@ -601,6 +604,7 @@ public class Process { int targetSdkVersion, String seInfo, String abi, + String instructionSet, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { @@ -660,6 +664,10 @@ public class Process { argsForZygote.add("--seinfo=" + seInfo); } + if (instructionSet != null) { + argsForZygote.add("--instruction-set=" + instructionSet); + } + argsForZygote.add(processClass); if (extraArgs != null) { diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index ec77a5e..33fda4a 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -43,190 +43,208 @@ public class UserManager { private final Context mContext; /** - * Key for user restrictions. Specifies if a user is disallowed from adding and removing - * accounts. + * Specifies if a user is disallowed from adding and removing accounts. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts"; /** - * Key for user restrictions. Specifies if a user is disallowed from changing Wi-Fi + * Specifies if a user is disallowed from changing Wi-Fi * access points. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_WIFI = "no_config_wifi"; /** - * Key for user restrictions. Specifies if a user is disallowed from installing applications. + * Specifies if a user is disallowed from installing applications. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_INSTALL_APPS = "no_install_apps"; /** - * Key for user restrictions. Specifies if a user is disallowed from uninstalling applications. + * Specifies if a user is disallowed from uninstalling applications. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_UNINSTALL_APPS = "no_uninstall_apps"; /** - * Key for user restrictions. Specifies if a user is disallowed from toggling location sharing. + * Specifies if a user is disallowed from toggling location sharing. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_SHARE_LOCATION = "no_share_location"; /** - * Key for user restrictions. Specifies if a user is disallowed from enabling the + * Specifies if a user is disallowed from enabling the * "Unknown Sources" setting, that allows installation of apps from unknown sources. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring bluetooth. + * Specifies if a user is disallowed from configuring bluetooth. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth"; /** - * Key for user restrictions. Specifies if a user is disallowed from transferring files over + * Specifies if a user is disallowed from transferring files over * USB. This can only be set by device owners. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_USB_FILE_TRANSFER = "no_usb_file_transfer"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring user + * Specifies if a user is disallowed from configuring user * credentials. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_CREDENTIALS = "no_config_credentials"; /** - * Key for user restrictions. Specifies if a user is disallowed from removing itself and other + * Specifies if a user is disallowed from removing itself and other * users. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_REMOVE_USER = "no_remove_user"; /** - * Key for user restrictions. Specifies if a user is disallowed from enabling or + * Specifies if a user is disallowed from enabling or * accessing debugging features. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring VPN. + * Specifies if a user is disallowed from configuring VPN. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_VPN = "no_config_vpn"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring Tethering + * Specifies if a user is disallowed from configuring Tethering * & portable hotspots. This can only be set by device owners. The default value is * <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_TETHERING = "no_config_tethering"; /** - * Key for user restrictions. Specifies if a user is disallowed from factory resetting + * Specifies if a user is disallowed from factory resetting * from Settings. This can only be set by device owners. The default value is * <code>false</code>. - * <p> + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_FACTORY_RESET = "no_factory_reset"; /** - * Key for user restrictions. Specifies if a user is disallowed from adding new users and + * Specifies if a user is disallowed from adding new users and * profiles. This can only be set by device owners. The default value is <code>false</code>. - * <p> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_ADD_USER = "no_add_user"; /** - * Key for user restrictions. Specifies if a user is disallowed from disabling application + * Specifies if a user is disallowed from disabling application * verification. The default value is <code>false</code>. - * <p> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String ENSURE_VERIFY_APPS = "ensure_verify_apps"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring cell + * Specifies if a user is disallowed from configuring cell * broadcasts. This can only be set by device owners. The default value is <code>false</code>. - * <p> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_CELL_BROADCASTS = "no_config_cell_broadcasts"; /** - * Key for user restrictions. Specifies if a user is disallowed from configuring mobile + * Specifies if a user is disallowed from configuring mobile * networks. This can only be set by device owners. The default value is <code>false</code>. - * <p> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks"; /** - * Key for user restrictions. Specifies if a user is disallowed from modifying + * Specifies if a user is disallowed from modifying * applications in Settings or launchers. The following actions will not be allowed when this * restriction is enabled: * <li>uninstalling apps</li> @@ -237,69 +255,75 @@ public class UserManager { * <li>clearing app defaults</li> * <p> * The default value is <code>false</code>. - * <p> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_APPS_CONTROL = "no_control_apps"; /** - * Key for user restrictions. Specifies if a user is disallowed from mounting + * Specifies if a user is disallowed from mounting * physical external media. This can only be set by device owners. The default value is * <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media"; /** - * Key for user restrictions. Specifies if a user is disallowed from adjusting microphone + * Specifies if a user is disallowed from adjusting microphone * volume. If set, the microphone will be muted. This can only be set by device owners. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_UNMUTE_MICROPHONE = "no_unmute_microphone"; /** - * Key for user restrictions. Specifies if a user is disallowed from adjusting the master + * Specifies if a user is disallowed from adjusting the master * volume. If set, the master volume will be muted. This can only be set by device owners. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_ADJUST_VOLUME = "no_adjust_volume"; /** - * Key for user restrictions. Specifies that the user is not allowed to make outgoing + * Specifies that the user is not allowed to make outgoing * phone calls. Emergency calls are still permitted. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_OUTGOING_CALLS = "no_outgoing_calls"; /** - * Key for user restrictions. Specifies that the user is not allowed to send or receive + * Specifies that the user is not allowed to send or receive * SMS messages. This can only be set by device owners. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_SMS = "no_sms"; /** - * Key for user restrictions. Specifies that windows besides app windows should not be + * Specifies that windows besides app windows should not be * created. This will block the creation of the following types of windows. * <li>{@link LayoutParams#TYPE_TOAST}</li> * <li>{@link LayoutParams#TYPE_PHONE}</li> @@ -309,25 +333,38 @@ public class UserManager { * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li> * * <p>This can only be set by device owners. The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CREATE_WINDOWS = "no_create_windows"; /** - * Key for user restrictions. Specifies if what is copied in the clipboard of this profile can + * Specifies if what is copied in the clipboard of this profile can * be pasted in related profiles. Does not restrict if the clipboard of related profiles can be * pasted in this profile. * The default value is <code>false</code>. - * <p/> - * Type: Boolean + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean * @see #setUserRestrictions(Bundle) * @see #getUserRestrictions() */ public static final String DISALLOW_CROSS_PROFILE_COPY_PASTE = "no_cross_profile_copy_paste"; + /** + * Specifies if the user is not allowed to use NFC to beam out data from apps. + * The default value is <code>false</code>. + * + * <p/>Key for user restrictions. + * <p/>Type: Boolean + * @see #setUserRestrictions(Bundle) + * @see #getUserRestrictions() + */ + public static final String DISALLOW_OUTGOING_BEAM = "no_outgoing_beam"; + /** @hide */ public static final int PIN_VERIFICATION_FAILED_INCORRECT = -3; /** @hide */ diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index 5fa1cc9..a5e86d8 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -167,8 +167,6 @@ public class CallLog { */ public static final String FEATURES = "features"; - /** Call had no associated features (e.g. voice-only). */ - public static final int FEATURES_NONE = 0x0; /** Call had video. */ public static final int FEATURES_VIDEO = 0x1; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index f4c2dc8..01fda47 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3739,6 +3739,13 @@ public final class Settings { "show_note_about_notification_hiding"; /** + * Set to 1 by the system after trust agents have been initialized. + * @hide + */ + public static final String TRUST_AGENTS_INITIALIZED = + "trust_agents_initialized"; + + /** * The Logging ID (a unique 64-bit value) as a hex string. * Used as a pseudonymous identifier for logging. * @deprecated This identifier is poorly initialized and has diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java index aa724f0..3a91d1a 100644 --- a/core/java/android/service/notification/Condition.java +++ b/core/java/android/service/notification/Condition.java @@ -16,6 +16,7 @@ package android.service.notification; +import android.annotation.SystemApi; import android.content.Context; import android.net.Uri; import android.os.Parcel; @@ -28,6 +29,7 @@ import java.util.Objects; * * @hide */ +@SystemApi public class Condition implements Parcelable { public static final String SCHEME = "condition"; diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java index 326412f..03ee726 100644 --- a/core/java/android/service/notification/ConditionProviderService.java +++ b/core/java/android/service/notification/ConditionProviderService.java @@ -17,6 +17,7 @@ package android.service.notification; import android.annotation.SdkConstant; +import android.annotation.SystemApi; import android.app.INotificationManager; import android.app.Service; import android.content.Context; @@ -44,6 +45,7 @@ import android.util.Log; * * @hide */ +@SystemApi public abstract class ConditionProviderService extends Service { private final String TAG = ConditionProviderService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; diff --git a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl index fd6b59e..c25cdb2 100644 --- a/core/java/android/service/notification/IStatusBarNotificationHolder.aidl +++ b/core/java/android/service/notification/IStatusBarNotificationHolder.aidl @@ -20,5 +20,6 @@ import android.service.notification.StatusBarNotification; /** @hide */ interface IStatusBarNotificationHolder { + /** Fetch the held StatusBarNotification. This method should only be called once per Holder */ StatusBarNotification get(); } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index d744070..b22fd9c 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -756,15 +756,6 @@ public abstract class NotificationListenerService extends Service { return mVisibilityOverride; } - /** - * Returns whether the notification meets the user's interruption - * filter. - * - * @removed - */ - public boolean meetsInterruptionFilter() { - return mMatchesInterruptionFilter; - } /** * Returns whether the notification matches the user's interruption diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 872f911..9cbedab 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -17,6 +17,7 @@ package android.service.notification; import android.content.ComponentName; +import android.content.res.Resources; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; @@ -55,6 +56,11 @@ public class ZenModeConfig implements Parcelable { public static final int[] WEEKNIGHT_DAYS = { Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY }; + public static final int[] MINUTE_BUCKETS = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; + private static final int SECONDS_MS = 1000; + private static final int MINUTES_MS = 60 * SECONDS_MS; + private static final int ZERO_VALUE_MS = 20 * SECONDS_MS; + private static final int XML_VERSION = 1; private static final String ZEN_TAG = "zen"; private static final String ZEN_ATT_VERSION = "version"; @@ -445,6 +451,23 @@ public class ZenModeConfig implements Parcelable { return downtime; } + public static Condition toTimeCondition(int minutesFromNow) { + final long now = System.currentTimeMillis(); + final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS; + return toTimeCondition(now + millis, minutesFromNow); + } + + public static Condition toTimeCondition(long time, int minutes) { + final int num = minutes < 60 ? minutes : Math.round(minutes / 60f); + final int resId = minutes < 60 + ? com.android.internal.R.plurals.zen_mode_duration_minutes + : com.android.internal.R.plurals.zen_mode_duration_hours; + final String caption = Resources.getSystem().getQuantityString(resId, num, num); + final Uri id = toCountdownConditionId(time); + return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE, + Condition.FLAG_RELEVANT_NOW); + } + // For built-in conditions private static final String SYSTEM_AUTHORITY = "android"; diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 4de5f41..8aa2689 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -468,19 +468,6 @@ public class AlwaysOnHotwordDetector { } /** - * FIXME: Remove once the prebuilts are updated. - * - * @hide - */ - @Deprecated - public Intent createIntentToEnroll() { - if (DBG) Slog.d(TAG, "createIntentToEnroll"); - synchronized (mLock) { - return getManageIntentLocked(MANAGE_ACTION_ENROLL); - } - } - - /** * Creates an intent to start the un-enrollment for the associated keyphrase. * This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}. * Starting re-enrollment is only valid if the keyphrase is already enrolled, @@ -502,19 +489,6 @@ public class AlwaysOnHotwordDetector { } /** - * FIXME: Remove once the prebuilts are updated. - * - * @hide - */ - @Deprecated - public Intent createIntentToUnEnroll() { - if (DBG) Slog.d(TAG, "createIntentToUnEnroll"); - synchronized (mLock) { - return getManageIntentLocked(MANAGE_ACTION_UN_ENROLL); - } - } - - /** * Creates an intent to start the re-enrollment for the associated keyphrase. * This intent must be invoked using {@link Activity#startActivityForResult(Intent, int)}. * Starting re-enrollment is only valid if the keyphrase is already enrolled, @@ -535,19 +509,6 @@ public class AlwaysOnHotwordDetector { } } - /** - * FIXME: Remove once the prebuilts are updated. - * - * @hide - */ - @Deprecated - public Intent createIntentToReEnroll() { - if (DBG) Slog.d(TAG, "createIntentToReEnroll"); - synchronized (mLock) { - return getManageIntentLocked(MANAGE_ACTION_RE_ENROLL); - } - } - private Intent getManageIntentLocked(int action) { if (mAvailability == STATE_INVALID) { throw new IllegalStateException("getManageIntent called on an invalid detector"); diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl index faccde2..de527e9 100644 --- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl +++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl @@ -16,6 +16,7 @@ package android.service.wallpaper; +import android.graphics.Rect; import android.view.MotionEvent; import android.os.Bundle; @@ -24,6 +25,7 @@ import android.os.Bundle; */ oneway interface IWallpaperEngine { void setDesiredSize(int width, int height); + void setDisplayPadding(in Rect padding); void setVisibility(boolean visible); void dispatchPointer(in MotionEvent event); void dispatchWallpaperCommand(String action, int x, int y, diff --git a/core/java/android/service/wallpaper/IWallpaperService.aidl b/core/java/android/service/wallpaper/IWallpaperService.aidl index bc7a1d7..5fd0157 100644 --- a/core/java/android/service/wallpaper/IWallpaperService.aidl +++ b/core/java/android/service/wallpaper/IWallpaperService.aidl @@ -16,6 +16,7 @@ package android.service.wallpaper; +import android.graphics.Rect; import android.service.wallpaper.IWallpaperConnection; /** @@ -24,5 +25,5 @@ import android.service.wallpaper.IWallpaperConnection; oneway interface IWallpaperService { void attach(IWallpaperConnection connection, IBinder windowToken, int windowType, boolean isPreview, - int reqWidth, int reqHeight); + int reqWidth, int reqHeight, in Rect padding); } diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index f3c26c8..26e9a30 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -16,6 +16,14 @@ package android.service.wallpaper; +import android.content.res.TypedArray; +import android.os.Build; +import android.os.SystemProperties; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.ViewRootImpl; +import android.view.WindowInsets; +import com.android.internal.R; import com.android.internal.os.HandlerCaller; import com.android.internal.view.BaseIWindow; import com.android.internal.view.BaseSurfaceHolder; @@ -56,6 +64,8 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; + /** * A wallpaper service is responsible for showing a live wallpaper behind * applications that would like to sit on top of it. This service object @@ -90,7 +100,8 @@ public abstract class WallpaperService extends Service { private static final int DO_ATTACH = 10; private static final int DO_DETACH = 20; private static final int DO_SET_DESIRED_SIZE = 30; - + private static final int DO_SET_DISPLAY_PADDING = 40; + private static final int MSG_UPDATE_SURFACE = 10000; private static final int MSG_VISIBILITY_CHANGED = 10010; private static final int MSG_WALLPAPER_OFFSETS = 10020; @@ -150,13 +161,23 @@ public abstract class WallpaperService extends Service { WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS; int mCurWindowFlags = mWindowFlags; int mCurWindowPrivateFlags = mWindowPrivateFlags; + TypedValue mOutsetBottom; final Rect mVisibleInsets = new Rect(); final Rect mWinFrame = new Rect(); final Rect mOverscanInsets = new Rect(); final Rect mContentInsets = new Rect(); final Rect mStableInsets = new Rect(); + final Rect mDispatchedOverscanInsets = new Rect(); + final Rect mDispatchedContentInsets = new Rect(); + final Rect mDispatchedStableInsets = new Rect(); + final Rect mFinalSystemInsets = new Rect(); + final Rect mFinalStableInsets = new Rect(); final Configuration mConfiguration = new Configuration(); - + + private boolean mIsEmulator; + private boolean mIsCircularEmulator; + private boolean mWindowIsRound; + final WindowManager.LayoutParams mLayout = new WindowManager.LayoutParams(); IWindowSession mSession; @@ -406,7 +427,7 @@ public abstract class WallpaperService extends Service { */ public void onCreate(SurfaceHolder surfaceHolder) { } - + /** * Called right before the engine is going away. After this the * surface will be destroyed and this Engine object is no longer @@ -414,7 +435,7 @@ public abstract class WallpaperService extends Service { */ public void onDestroy() { } - + /** * Called to inform you of the wallpaper becoming visible or * hidden. <em>It is very important that a wallpaper only use @@ -422,7 +443,17 @@ public abstract class WallpaperService extends Service { */ public void onVisibilityChanged(boolean visible) { } - + + /** + * Called with the current insets that are in effect for the wallpaper. + * This gives you the part of the overall wallpaper surface that will + * generally be visible to the user (ignoring position offsets applied to it). + * + * @param insets Insets to apply. + */ + public void onApplyWindowInsets(WindowInsets insets) { + } + /** * Called as the user performs touch-screen interaction with the * window that is currently showing this wallpaper. Note that the @@ -432,7 +463,7 @@ public abstract class WallpaperService extends Service { */ public void onTouchEvent(MotionEvent event) { } - + /** * Called to inform you of the wallpaper's offsets changing * within its contain, corresponding to the container's @@ -443,7 +474,7 @@ public abstract class WallpaperService extends Service { float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { } - + /** * Process a command that was sent to the wallpaper with * {@link WallpaperManager#sendWallpaperCommand}. @@ -465,14 +496,14 @@ public abstract class WallpaperService extends Service { Bundle extras, boolean resultRequested) { return null; } - + /** * Called when an application has changed the desired virtual size of * the wallpaper. */ public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { } - + /** * Convenience for {@link SurfaceHolder.Callback#surfaceChanged * SurfaceHolder.Callback.surfaceChanged()}. @@ -561,16 +592,20 @@ public abstract class WallpaperService extends Service { if (mDestroyed) { Log.w(TAG, "Ignoring updateSurface: destroyed"); } - + + boolean fixedSize = false; int myWidth = mSurfaceHolder.getRequestedWidth(); if (myWidth <= 0) myWidth = ViewGroup.LayoutParams.MATCH_PARENT; + else fixedSize = true; int myHeight = mSurfaceHolder.getRequestedHeight(); if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT; - + else fixedSize = true; + final boolean creating = !mCreated; final boolean surfaceCreating = !mSurfaceCreated; final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat(); boolean sizeChanged = mWidth != myWidth || mHeight != myHeight; + boolean insetsChanged = !mCreated; final boolean typeChanged = mType != mSurfaceHolder.getRequestedType(); final boolean flagsChanged = mCurWindowFlags != mWindowFlags || mCurWindowPrivateFlags != mWindowPrivateFlags; @@ -607,6 +642,32 @@ public abstract class WallpaperService extends Service { mLayout.token = mWindowToken; if (!mCreated) { + // Retrieve watch round and outset info + final WindowManager windowService = (WindowManager)getSystemService( + Context.WINDOW_SERVICE); + TypedArray windowStyle = obtainStyledAttributes( + com.android.internal.R.styleable.Window); + final Display display = windowService.getDefaultDisplay(); + final boolean shouldUseBottomOutset = + display.getDisplayId() == Display.DEFAULT_DISPLAY; + if (shouldUseBottomOutset && windowStyle.hasValue( + R.styleable.Window_windowOutsetBottom)) { + if (mOutsetBottom == null) mOutsetBottom = new TypedValue(); + windowStyle.getValue(R.styleable.Window_windowOutsetBottom, + mOutsetBottom); + } else { + mOutsetBottom = null; + } + mWindowIsRound = getResources().getBoolean( + com.android.internal.R.bool.config_windowIsRound); + windowStyle.recycle(); + + // detect emulator + mIsEmulator = Build.HARDWARE.contains("goldfish"); + mIsCircularEmulator = SystemProperties.getBoolean( + ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false); + + // Add window mLayout.type = mIWallpaperEngine.mWindowType; mLayout.gravity = Gravity.START|Gravity.TOP; mLayout.setTitle(WallpaperService.this.getClass().getName()); @@ -627,6 +688,11 @@ public abstract class WallpaperService extends Service { mSurfaceHolder.mSurfaceLock.lock(); mDrawingAllowed = true; + if (!fixedSize) { + mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding); + } else { + mLayout.surfaceInsets.set(0, 0, 0, 0); + } final int relayoutResult = mSession.relayout( mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets, @@ -636,16 +702,39 @@ public abstract class WallpaperService extends Service { + ", frame=" + mWinFrame); int w = mWinFrame.width(); + int h = mWinFrame.height(); + + if (!fixedSize) { + final Rect padding = mIWallpaperEngine.mDisplayPadding; + w += padding.left + padding.right; + h += padding.top + padding.bottom; + mOverscanInsets.left += padding.left; + mOverscanInsets.top += padding.top; + mOverscanInsets.right += padding.right; + mOverscanInsets.bottom += padding.bottom; + mContentInsets.left += padding.left; + mContentInsets.top += padding.top; + mContentInsets.right += padding.right; + mContentInsets.bottom += padding.bottom; + mStableInsets.left += padding.left; + mStableInsets.top += padding.top; + mStableInsets.right += padding.right; + mStableInsets.bottom += padding.bottom; + } + if (mCurWidth != w) { sizeChanged = true; mCurWidth = w; } - int h = mWinFrame.height(); if (mCurHeight != h) { sizeChanged = true; mCurHeight = h; } + insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets); + insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets); + insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets); + mSurfaceHolder.setSurfaceFrameSize(w, h); mSurfaceHolder.mSurfaceLock.unlock(); @@ -702,6 +791,25 @@ public abstract class WallpaperService extends Service { } } + if (insetsChanged) { + mDispatchedOverscanInsets.set(mOverscanInsets); + mDispatchedContentInsets.set(mContentInsets); + mDispatchedStableInsets.set(mStableInsets); + final boolean isRound = (mIsEmulator && mIsCircularEmulator) + || mWindowIsRound; + mFinalSystemInsets.set(mDispatchedOverscanInsets); + mFinalStableInsets.set(mDispatchedStableInsets); + if (mOutsetBottom != null) { + final DisplayMetrics metrics = getResources().getDisplayMetrics(); + mFinalSystemInsets.bottom = + ( (int) mOutsetBottom.getDimension(metrics) ) + + mIWallpaperEngine.mDisplayPadding.bottom; + } + WindowInsets insets = new WindowInsets(mFinalSystemInsets, + null, mFinalStableInsets, isRound); + onApplyWindowInsets(insets); + } + if (redrawNeeded) { onSurfaceRedrawNeeded(mSurfaceHolder); SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks(); @@ -781,7 +889,7 @@ public abstract class WallpaperService extends Service { mReportedVisible = false; updateSurface(false, false, false); } - + void doDesiredSizeChanged(int desiredWidth, int desiredHeight) { if (!mDestroyed) { if (DEBUG) Log.v(TAG, "onDesiredSizeChanged(" @@ -792,14 +900,24 @@ public abstract class WallpaperService extends Service { doOffsetsChanged(true); } } - + + void doDisplayPaddingChanged(Rect padding) { + if (!mDestroyed) { + if (DEBUG) Log.v(TAG, "onDisplayPaddingChanged(" + padding + "): " + this); + if (!mIWallpaperEngine.mDisplayPadding.equals(padding)) { + mIWallpaperEngine.mDisplayPadding.set(padding); + updateSurface(true, false, false); + } + } + } + void doVisibilityChanged(boolean visible) { if (!mDestroyed) { mVisible = visible; reportVisibility(); } } - + void reportVisibility() { if (!mDestroyed) { boolean visible = mVisible && mScreenOn; @@ -956,12 +1074,13 @@ public abstract class WallpaperService extends Service { boolean mShownReported; int mReqWidth; int mReqHeight; - + final Rect mDisplayPadding = new Rect(); + Engine mEngine; - + IWallpaperEngineWrapper(WallpaperService context, IWallpaperConnection conn, IBinder windowToken, - int windowType, boolean isPreview, int reqWidth, int reqHeight) { + int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) { mCaller = new HandlerCaller(context, context.getMainLooper(), this, true); mConnection = conn; mWindowToken = windowToken; @@ -969,16 +1088,22 @@ public abstract class WallpaperService extends Service { mIsPreview = isPreview; mReqWidth = reqWidth; mReqHeight = reqHeight; + mDisplayPadding.set(padding); Message msg = mCaller.obtainMessage(DO_ATTACH); mCaller.sendMessage(msg); } - + public void setDesiredSize(int width, int height) { Message msg = mCaller.obtainMessageII(DO_SET_DESIRED_SIZE, width, height); mCaller.sendMessage(msg); } - + + public void setDisplayPadding(Rect padding) { + Message msg = mCaller.obtainMessageO(DO_SET_DISPLAY_PADDING, padding); + mCaller.sendMessage(msg); + } + public void setVisibility(boolean visible) { Message msg = mCaller.obtainMessageI(MSG_VISIBILITY_CHANGED, visible ? 1 : 0); @@ -1041,6 +1166,9 @@ public abstract class WallpaperService extends Service { mEngine.doDesiredSizeChanged(message.arg1, message.arg2); return; } + case DO_SET_DISPLAY_PADDING: { + mEngine.doDisplayPaddingChanged((Rect) message.obj); + } case MSG_UPDATE_SURFACE: mEngine.updateSurface(true, false, false); break; @@ -1102,9 +1230,9 @@ public abstract class WallpaperService extends Service { @Override public void attach(IWallpaperConnection conn, IBinder windowToken, - int windowType, boolean isPreview, int reqWidth, int reqHeight) { + int windowType, boolean isPreview, int reqWidth, int reqHeight, Rect padding) { new IWallpaperEngineWrapper(mTarget, conn, windowToken, - windowType, isPreview, reqWidth, reqHeight); + windowType, isPreview, reqWidth, reqHeight, padding); } } diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 0d1b568..40bb6ec 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -1417,9 +1417,9 @@ public abstract class Transition implements Cloneable { } capturePropagationValues(values); if (start) { - addViewValues(mStartValues, view, values); + addViewValues(mStartValues, view, values, true); } else { - addViewValues(mEndValues, view, values); + addViewValues(mEndValues, view, values, true); } } } @@ -1460,7 +1460,7 @@ public abstract class Transition implements Cloneable { } static void addViewValues(TransitionValuesMaps transitionValuesMaps, - View view, TransitionValues transitionValues) { + View view, TransitionValues transitionValues, boolean setTransientState) { transitionValuesMaps.viewValues.put(view, transitionValues); int id = view.getId(); if (id >= 0) { @@ -1489,11 +1489,15 @@ public abstract class Transition implements Cloneable { // Duplicate item IDs: cannot match by item ID. View alreadyMatched = transitionValuesMaps.itemIdValues.get(itemId); if (alreadyMatched != null) { - alreadyMatched.setHasTransientState(false); + if (setTransientState) { + alreadyMatched.setHasTransientState(false); + } transitionValuesMaps.itemIdValues.put(itemId, null); } } else { - view.setHasTransientState(true); + if (setTransientState) { + view.setHasTransientState(true); + } transitionValuesMaps.itemIdValues.put(itemId, view); } } @@ -1560,9 +1564,9 @@ public abstract class Transition implements Cloneable { } capturePropagationValues(values); if (start) { - addViewValues(mStartValues, view, values); + addViewValues(mStartValues, view, values, true); } else { - addViewValues(mEndValues, view, values); + addViewValues(mEndValues, view, values, true); } } if (view instanceof ViewGroup) { diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java index f6499ae..56db674 100644 --- a/core/java/android/transition/TransitionSet.java +++ b/core/java/android/transition/TransitionSet.java @@ -408,7 +408,7 @@ public class TransitionSet extends Transition { for (int i = 0; i < numValues; i++) { View view = values.viewValues.keyAt(i); if (isValidTarget(view)) { - addViewValues(included, view, values.viewValues.valueAt(i)); + addViewValues(included, view, values.viewValues.valueAt(i), false); } } return included; diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index a10dda3..a283b91 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -19,7 +19,6 @@ package android.view; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -101,7 +100,7 @@ final class AccessibilityInteractionController { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); - message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID; + message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID; message.arg1 = flags; SomeArgs args = SomeArgs.obtain(); @@ -176,7 +175,7 @@ final class AccessibilityInteractionController { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); - message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID; + message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID; message.arg1 = flags; message.arg2 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); @@ -261,7 +260,7 @@ final class AccessibilityInteractionController { IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { Message message = mHandler.obtainMessage(); - message.what = PrivateHandler.MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT; + message.what = PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT; message.arg1 = flags; SomeArgs args = SomeArgs.obtain(); @@ -637,6 +636,95 @@ final class AccessibilityInteractionController { } } + public void computeClickPointInScreenClientThread(long accessibilityNodeId, + Region interactiveRegion, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int interrogatingPid, + long interrogatingTid, MagnificationSpec spec) { + Message message = mHandler.obtainMessage(); + message.what = PrivateHandler.MSG_COMPUTE_CLICK_POINT_IN_SCREEN; + + SomeArgs args = SomeArgs.obtain(); + args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId); + args.argi2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId); + args.argi3 = interactionId; + args.arg1 = callback; + args.arg2 = spec; + args.arg3 = interactiveRegion; + + message.obj = args; + + // If the interrogation is performed by the same thread as the main UI + // thread in this process, set the message as a static reference so + // after this call completes the same thread but in the interrogating + // client can handle the message to generate the result. + if (interrogatingPid == mMyProcessId && interrogatingTid == mMyLooperThreadId) { + AccessibilityInteractionClient.getInstanceForThread( + interrogatingTid).setSameThreadMessage(message); + } else { + mHandler.sendMessage(message); + } + } + + private void computeClickPointInScreenUiThread(Message message) { + SomeArgs args = (SomeArgs) message.obj; + final int accessibilityViewId = args.argi1; + final int virtualDescendantId = args.argi2; + final int interactionId = args.argi3; + final IAccessibilityInteractionConnectionCallback callback = + (IAccessibilityInteractionConnectionCallback) args.arg1; + final MagnificationSpec spec = (MagnificationSpec) args.arg2; + final Region interactiveRegion = (Region) args.arg3; + args.recycle(); + + boolean succeeded = false; + Point point = mTempPoint; + try { + if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) { + return; + } + View target = null; + if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + target = findViewByAccessibilityId(accessibilityViewId); + } else { + target = mViewRootImpl.mView; + } + if (target != null && isShown(target)) { + AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider(); + if (provider != null) { + // For virtual views just use the center of the bounds in screen. + AccessibilityNodeInfo node = null; + if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + node = provider.createAccessibilityNodeInfo(virtualDescendantId); + } else { + node = provider.createAccessibilityNodeInfo( + AccessibilityNodeProvider.HOST_VIEW_ID); + } + if (node != null) { + succeeded = true; + Rect boundsInScreen = mTempRect; + node.getBoundsInScreen(boundsInScreen); + point.set(boundsInScreen.centerX(), boundsInScreen.centerY()); + } + } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) { + // For a real view, ask the view to compute the click point. + succeeded = target.computeClickPointInScreenForAccessibility( + interactiveRegion, point); + } + } + } finally { + try { + Point result = null; + if (succeeded) { + applyAppScaleAndMagnificationSpecIfNeeded(point, spec); + result = point; + } + callback.setComputeClickPointInScreenActionResult(result, interactionId); + } catch (RemoteException re) { + /* ignore - the other side will time out */ + } + } + } + private View findViewByAccessibilityId(int accessibilityId) { View root = mViewRootImpl.mView; if (root == null) { @@ -688,6 +776,26 @@ final class AccessibilityInteractionController { } } + private void applyAppScaleAndMagnificationSpecIfNeeded(Point point, + MagnificationSpec spec) { + final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale; + if (!shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) { + return; + } + + if (applicationScale != 1.0f) { + point.x *= applicationScale; + point.y *= applicationScale; + } + + if (spec != null) { + point.x *= spec.scale; + point.y *= spec.scale; + point.x += (int) spec.offsetX; + point.y += (int) spec.offsetY; + } + } + private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info, MagnificationSpec spec) { if (info == null) { @@ -1080,11 +1188,12 @@ final class AccessibilityInteractionController { private class PrivateHandler extends Handler { private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 1; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID = 3; - private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 4; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID = 2; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID = 3; + private final static int MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT = 4; private final static int MSG_FIND_FOCUS = 5; private final static int MSG_FOCUS_SEARCH = 6; + private final static int MSG_COMPUTE_CLICK_POINT_IN_SCREEN = 7; public PrivateHandler(Looper looper) { super(looper); @@ -1096,16 +1205,18 @@ final class AccessibilityInteractionController { switch (type) { case MSG_PERFORM_ACCESSIBILITY_ACTION: return "MSG_PERFORM_ACCESSIBILITY_ACTION"; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: - return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID"; - case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: - return "MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID"; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: - return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT"; + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: + return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID"; + case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: + return "MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID"; + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: + return "MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT"; case MSG_FIND_FOCUS: return "MSG_FIND_FOCUS"; case MSG_FOCUS_SEARCH: return "MSG_FOCUS_SEARCH"; + case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: + return "MSG_COMPUTE_CLICK_POINT_IN_SCREEN"; default: throw new IllegalArgumentException("Unknown message type: " + type); } @@ -1115,16 +1226,16 @@ final class AccessibilityInteractionController { public void handleMessage(Message message) { final int type = message.what; switch (type) { - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: { + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID: { findAccessibilityNodeInfoByAccessibilityIdUiThread(message); } break; case MSG_PERFORM_ACCESSIBILITY_ACTION: { perfromAccessibilityActionUiThread(message); } break; - case MSG_FIND_ACCESSIBLITY_NODE_INFOS_BY_VIEW_ID: { + case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: { findAccessibilityNodeInfosByViewIdUiThread(message); } break; - case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: { + case MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_TEXT: { findAccessibilityNodeInfosByTextUiThread(message); } break; case MSG_FIND_FOCUS: { @@ -1133,6 +1244,9 @@ final class AccessibilityInteractionController { case MSG_FOCUS_SEARCH: { focusSearchUiThread(message); } break; + case MSG_COMPUTE_CLICK_POINT_IN_SCREEN: { + computeClickPointInScreenUiThread(message); + } break; default: throw new IllegalArgumentException("Unknown message type: " + type); } diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 0f3f182..037ed28 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -177,6 +177,11 @@ interface IWindowSession { void wallpaperOffsetsComplete(IBinder window); + /** + * Apply a raw offset to the wallpaper service when shown behind this window. + */ + void setWallpaperDisplayOffset(IBinder windowToken, int x, int y); + Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, int z, in Bundle extras, boolean sync); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 1e28e33..4074529 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -39,7 +39,7 @@ public class SurfaceControl { private static native Bitmap nativeScreenshot(IBinder displayToken, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, - boolean allLayers, boolean useIdentityTransform); + boolean allLayers, boolean useIdentityTransform, int rotation); private static native void nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); @@ -688,17 +688,23 @@ public class SurfaceControl { * @param useIdentityTransform Replace whatever transformation (rotation, * scaling, translation) the surface layers are currently using with the * identity transformation while taking the screenshot. + * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. + * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take + * screenshots in its native portrait orientation by default, so this is + * useful for returning screenshots that are independent of device + * orientation. * @return Returns a Bitmap containing the screen contents, or null * if an error occurs. Make sure to call Bitmap.recycle() as soon as * possible, once its content is not needed anymore. */ public static Bitmap screenshot(Rect sourceCrop, int width, int height, - int minLayer, int maxLayer, boolean useIdentityTransform) { + int minLayer, int maxLayer, boolean useIdentityTransform, + int rotation) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, sourceCrop, width, height, - minLayer, maxLayer, false, useIdentityTransform); + minLayer, maxLayer, false, useIdentityTransform, rotation); } /** @@ -717,7 +723,8 @@ public class SurfaceControl { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false); + return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, + false, Surface.ROTATION_0); } private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 770e78c..82c5425 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -35,6 +35,8 @@ import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Outline; import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PathMeasure; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; @@ -5731,6 +5733,136 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Computes a point on which a sequence of a down/up event can be sent to + * trigger clicking this view. This method is for the exclusive use by the + * accessibility layer to determine where to send a click event in explore + * by touch mode. + * + * @param interactiveRegion The interactive portion of this window. + * @param outPoint The point to populate. + * @return True of such a point exists. + */ + boolean computeClickPointInScreenForAccessibility(Region interactiveRegion, + Point outPoint) { + // Since the interactive portion of the view is a region but as a view + // may have a transformation matrix which cannot be applied to a + // region we compute the view bounds rectangle and all interactive + // predecessor's and sibling's (siblings of predecessors included) + // rectangles that intersect the view bounds. At the + // end if the view was partially covered by another interactive + // view we compute the view's interactive region and pick a point + // on its boundary path as regions do not offer APIs to get inner + // points. Note that the the code is optimized to fail early and + // avoid unnecessary allocations plus computations. + + // The current approach has edge cases that may produce false + // positives or false negatives. For example, a portion of the + // view may be covered by an interactive descendant of a + // predecessor, which we do not compute. Also a view may be handling + // raw touch events instead registering click listeners, which + // we cannot compute. Despite these limitations this approach will + // work most of the time and it is a huge improvement over just + // blindly sending the down and up events in the center of the + // view. + + // Cannot click on an unattached view. + if (mAttachInfo == null) { + return false; + } + + // Attached to an invisible window means this view is not visible. + if (mAttachInfo.mWindowVisibility != View.VISIBLE) { + return false; + } + + RectF bounds = mAttachInfo.mTmpTransformRect; + bounds.set(0, 0, getWidth(), getHeight()); + List<RectF> intersections = mAttachInfo.mTmpRectList; + intersections.clear(); + + if (mParent instanceof ViewGroup) { + ViewGroup parentGroup = (ViewGroup) mParent; + if (!parentGroup.translateBoundsAndIntersectionsInWindowCoordinates( + this, bounds, intersections)) { + intersections.clear(); + return false; + } + } + + // Take into account the window location. + final int dx = mAttachInfo.mWindowLeft; + final int dy = mAttachInfo.mWindowTop; + bounds.offset(dx, dy); + offsetRects(intersections, dx, dy); + + if (intersections.isEmpty() && interactiveRegion == null) { + outPoint.set((int) bounds.centerX(), (int) bounds.centerY()); + } else { + // This view is partially covered by other views, then compute + // the not covered region and pick a point on its boundary. + Region region = new Region(); + region.set((int) bounds.left, (int) bounds.top, + (int) bounds.right, (int) bounds.bottom); + + final int intersectionCount = intersections.size(); + for (int i = intersectionCount - 1; i >= 0; i--) { + RectF intersection = intersections.remove(i); + region.op((int) intersection.left, (int) intersection.top, + (int) intersection.right, (int) intersection.bottom, + Region.Op.DIFFERENCE); + } + + // If the view is completely covered, done. + if (region.isEmpty()) { + return false; + } + + // Take into account the interactive portion of the window + // as the rest is covered by other windows. If no such a region + // then the whole window is interactive. + if (interactiveRegion != null) { + region.op(interactiveRegion, Region.Op.INTERSECT); + } + + // If the view is completely covered, done. + if (region.isEmpty()) { + return false; + } + + // Try a shortcut here. + if (region.isRect()) { + Rect regionBounds = mAttachInfo.mTmpInvalRect; + region.getBounds(regionBounds); + outPoint.set(regionBounds.centerX(), regionBounds.centerY()); + return true; + } + + // Get the a point on the region boundary path. + Path path = region.getBoundaryPath(); + PathMeasure pathMeasure = new PathMeasure(path, false); + final float[] coordinates = mAttachInfo.mTmpTransformLocation; + + // Without loss of generality pick a point. + final float point = pathMeasure.getLength() * 0.01f; + if (!pathMeasure.getPosTan(point, coordinates, null)) { + return false; + } + + outPoint.set(Math.round(coordinates[0]), Math.round(coordinates[1])); + } + + return true; + } + + static void offsetRects(List<RectF> rects, float offsetX, float offsetY) { + final int rectCount = rects.size(); + for (int i = 0; i < rectCount; i++) { + RectF intersection = rects.get(i); + intersection.offset(offsetX, offsetY); + } + } + + /** * Returns the delegate for implementing accessibility support via * composition. For more details see {@link AccessibilityDelegate}. * @@ -20154,6 +20286,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, final RectF mTmpTransformRect = new RectF(); /** + * Temporary for use in computing hit areas with transformed views + */ + final RectF mTmpTransformRect1 = new RectF(); + + /** + * Temporary list of rectanges. + */ + final List<RectF> mTmpRectList = new ArrayList<>(); + + /** * Temporary for use in transforming invalidation rect */ final Matrix mTmpMatrix = new Matrix(); diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index c1e66de..4e1db90 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -771,6 +771,112 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * Translates the given bounds and intersections from child coordinates to + * local coordinates. In case any interactive sibling of the calling child + * covers the latter, a new intersections is added to the intersection list. + * This method is for the exclusive use by the accessibility layer to compute + * a point where a sequence of down and up events would click on a view. + * + * @param child The child making the call. + * @param bounds The bounds to translate in child coordinates. + * @param intersections The intersections of interactive views covering the child. + * @return True if the bounds and intersections were computed, false otherwise. + */ + boolean translateBoundsAndIntersectionsInWindowCoordinates(View child, + RectF bounds, List<RectF> intersections) { + // Not attached, done. + if (mAttachInfo == null) { + return false; + } + + if (getAlpha() <= 0 || getTransitionAlpha() <= 0 || + getVisibility() != VISIBLE) { + // Cannot click on a view with an invisible predecessor. + return false; + } + + // Compensate for the child transformation. + if (!child.hasIdentityMatrix()) { + Matrix matrix = child.getMatrix(); + matrix.mapRect(bounds); + final int intersectionCount = intersections.size(); + for (int i = 0; i < intersectionCount; i++) { + RectF intersection = intersections.get(i); + matrix.mapRect(intersection); + } + } + + // Translate the bounds from child to parent coordinates. + final int dx = child.mLeft - mScrollX; + final int dy = child.mTop - mScrollY; + bounds.offset(dx, dy); + offsetRects(intersections, dx, dy); + + // If the bounds do not intersect our bounds, done. + if (!bounds.intersects(0, 0, getWidth(), getHeight())) { + return false; + } + + // Check whether any clickable siblings cover the child + // view and if so keep track of the intersections. Also + // respect Z ordering when iterating over children. + ArrayList<View> orderedList = buildOrderedChildList(); + final boolean useCustomOrder = orderedList == null + && isChildrenDrawingOrderEnabled(); + + final int childCount = mChildrenCount; + for (int i = childCount - 1; i >= 0; i--) { + final int childIndex = useCustomOrder + ? getChildDrawingOrder(childCount, i) : i; + final View sibling = (orderedList == null) + ? mChildren[childIndex] : orderedList.get(childIndex); + + // We care only about siblings over the child. + if (sibling == child) { + break; + } + + // If sibling is not interactive we do not care. + if (!sibling.isClickable() && !sibling.isLongClickable()) { + continue; + } + + // Compute the sibling bounds in its coordinates. + RectF siblingBounds = mAttachInfo.mTmpTransformRect1; + siblingBounds.set(0, 0, sibling.getWidth(), sibling.getHeight()); + + // Take into account the sibling transformation matrix. + if (!sibling.hasIdentityMatrix()) { + sibling.getMatrix().mapRect(siblingBounds); + } + + // Offset the sibling to our coordinates. + final int siblingDx = sibling.mLeft - mScrollX; + final int siblingDy = sibling.mTop - mScrollY; + siblingBounds.offset(siblingDx, siblingDy); + + // Compute the intersection between the child and the sibling. + if (siblingBounds.intersect(bounds)) { + // If an interactive sibling completely covers the child, done. + if (siblingBounds.equals(bounds)) { + return false; + } + // Keep track of the intersection rectangle. + RectF intersection = new RectF(siblingBounds); + intersections.add(intersection); + } + } + + if (mParent instanceof ViewGroup) { + ViewGroup parentGroup = (ViewGroup) mParent; + return parentGroup.translateBoundsAndIntersectionsInWindowCoordinates( + this, bounds, intersections); + } + + return true; + } + + /** * Called when a child view has changed whether or not it is tracking transient state. */ public void childHasTransientStateChanged(View child, boolean childHasTransientState) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 4299e2e..43ab4ef 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -121,7 +121,7 @@ public final class ViewRootImpl implements ViewParent, private static final String PROPERTY_MEDIA_DISABLED = "config.disable_media"; // property used by emulator to determine display shape - private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular"; + public static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular"; /** * Maximum time we allow the user to roll the trackball enough to generate @@ -6679,12 +6679,12 @@ public final class ViewRootImpl implements ViewParent, public void performAccessibilityAction(long accessibilityNodeId, int action, Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, - int interogatingPid, long interrogatingTid) { + int interrogatingPid, long interrogatingTid) { ViewRootImpl viewRootImpl = mViewRootImpl.get(); if (viewRootImpl != null && viewRootImpl.mView != null) { viewRootImpl.getAccessibilityInteractionController() .performAccessibilityActionClientThread(accessibilityNodeId, action, arguments, - interactionId, callback, flags, interogatingPid, interrogatingTid); + interactionId, callback, flags, interrogatingPid, interrogatingTid); } else { // We cannot make the call and notify the caller so it does not wait. try { @@ -6696,6 +6696,26 @@ public final class ViewRootImpl implements ViewParent, } @Override + public void computeClickPointInScreen(long accessibilityNodeId, Region interactiveRegion, + int interactionId, IAccessibilityInteractionConnectionCallback callback, + int interrogatingPid, long interrogatingTid, MagnificationSpec spec) { + ViewRootImpl viewRootImpl = mViewRootImpl.get(); + if (viewRootImpl != null && viewRootImpl.mView != null) { + viewRootImpl.getAccessibilityInteractionController() + .computeClickPointInScreenClientThread(accessibilityNodeId, + interactiveRegion, interactionId, callback, interrogatingPid, + interrogatingTid, spec); + } else { + // We cannot make the call and notify the caller so it does not wait. + try { + callback.setComputeClickPointInScreenActionResult(null, interactionId); + } catch (RemoteException re) { + /* best effort - ignore */ + } + } + } + + @Override public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId, String viewId, Region interactiveRegion, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 571a8f0..24c3c1a 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -378,35 +378,75 @@ public final class WindowInsets { } /** - * @hide + * Returns the top stable inset in pixels. + * + * <p>The stable inset represents the area of a full-screen window that <b>may</b> be + * partially or fully obscured by the system UI elements. This value does not change + * based on the visibility state of those elements; for example, if the status bar is + * normally shown, but temporarily hidden, the stable inset will still provide the inset + * associated with the status bar being shown.</p> + * + * @return The top stable inset */ public int getStableInsetTop() { return mStableInsets.top; } /** - * @hide + * Returns the left stable inset in pixels. + * + * <p>The stable inset represents the area of a full-screen window that <b>may</b> be + * partially or fully obscured by the system UI elements. This value does not change + * based on the visibility state of those elements; for example, if the status bar is + * normally shown, but temporarily hidden, the stable inset will still provide the inset + * associated with the status bar being shown.</p> + * + * @return The left stable inset */ public int getStableInsetLeft() { return mStableInsets.left; } /** - * @hide + * Returns the right stable inset in pixels. + * + * <p>The stable inset represents the area of a full-screen window that <b>may</b> be + * partially or fully obscured by the system UI elements. This value does not change + * based on the visibility state of those elements; for example, if the status bar is + * normally shown, but temporarily hidden, the stable inset will still provide the inset + * associated with the status bar being shown.</p> + * + * @return The right stable inset */ public int getStableInsetRight() { return mStableInsets.right; } /** - * @hide + * Returns the bottom stable inset in pixels. + * + * <p>The stable inset represents the area of a full-screen window that <b>may</b> be + * partially or fully obscured by the system UI elements. This value does not change + * based on the visibility state of those elements; for example, if the status bar is + * normally shown, but temporarily hidden, the stable inset will still provide the inset + * associated with the status bar being shown.</p> + * + * @return The bottom stable inset */ public int getStableInsetBottom() { return mStableInsets.bottom; } /** - * @hide + * Returns true if this WindowInsets has nonzero stable insets. + * + * <p>The stable inset represents the area of a full-screen window that <b>may</b> be + * partially or fully obscured by the system UI elements. This value does not change + * based on the visibility state of those elements; for example, if the status bar is + * normally shown, but temporarily hidden, the stable inset will still provide the inset + * associated with the status bar being shown.</p> + * + * @return true if any of the stable inset values are nonzero */ public boolean hasStableInsets() { return mStableInsets.top != 0 || mStableInsets.left != 0 || mStableInsets.right != 0 @@ -414,7 +454,9 @@ public final class WindowInsets { } /** - * @hide + * Returns a copy of this WindowInsets with the stable insets fully consumed. + * + * @return A modified copy of this WindowInsets */ public WindowInsets consumeStableInsets() { final WindowInsets result = new WindowInsets(this); diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java index db78ec5..374f7e0 100644 --- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java +++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java @@ -17,6 +17,7 @@ package android.view.accessibility; import android.accessibilityservice.IAccessibilityServiceConnection; +import android.graphics.Point; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -98,6 +99,8 @@ public final class AccessibilityInteractionClient private boolean mPerformAccessibilityActionResult; + private Point mComputeClickPointResult; + private Message mSameThreadMessage; private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache = @@ -519,6 +522,43 @@ public final class AccessibilityInteractionClient return false; } + /** + * Computes a point in screen coordinates where sending a down/up events would + * perform a click on an {@link AccessibilityNodeInfo}. + * + * @param connectionId The id of a connection for interacting with the system. + * @param accessibilityWindowId A unique window id. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID} + * to query the currently active window. + * @param accessibilityNodeId A unique view id or virtual descendant id from + * where to start the search. Use + * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID} + * to start from the root. + * @return Point the click point of null if no such point. + */ + public Point computeClickPointInScreen(int connectionId, int accessibilityWindowId, + long accessibilityNodeId) { + try { + IAccessibilityServiceConnection connection = getConnection(connectionId); + if (connection != null) { + final int interactionId = mInteractionIdCounter.getAndIncrement(); + final boolean success = connection.computeClickPointInScreen( + accessibilityWindowId, accessibilityNodeId, + interactionId, this, Thread.currentThread().getId()); + if (success) { + return getComputeClickPointInScreenResultAndClear(interactionId); + } + } else { + if (DEBUG) { + Log.w(LOG_TAG, "No connection for connection id: " + connectionId); + } + } + } catch (RemoteException re) { + Log.w(LOG_TAG, "Error while calling remote computeClickPointInScreen", re); + } + return null; + } + public void clearCache() { sAccessibilityCache.clear(); } @@ -634,6 +674,34 @@ public final class AccessibilityInteractionClient } /** + * Gets the result of a request to compute a point in screen for clicking on a node. + * + * @param interactionId The interaction id to match the result with the request. + * @return The point or null if no such point. + */ + private Point getComputeClickPointInScreenResultAndClear(int interactionId) { + synchronized (mInstanceLock) { + final boolean success = waitForResultTimedLocked(interactionId); + Point result = success ? mComputeClickPointResult : null; + clearResultLocked(); + return result; + } + } + + /** + * {@inheritDoc} + */ + public void setComputeClickPointInScreenActionResult(Point point, int interactionId) { + synchronized (mInstanceLock) { + if (interactionId > mInteractionId) { + mComputeClickPointResult = point; + mInteractionId = interactionId; + } + mInstanceLock.notifyAll(); + } + } + + /** * Clears the result state. */ private void clearResultLocked() { @@ -641,6 +709,7 @@ public final class AccessibilityInteractionClient mFindAccessibilityNodeInfoResult = null; mFindAccessibilityNodeInfosResult = null; mPerformAccessibilityActionResult = false; + mComputeClickPointResult = null; } /** diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl index faf7789..66a3f46 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl @@ -17,6 +17,7 @@ package android.view.accessibility; import android.graphics.Region; +import android.graphics.Point; import android.os.Bundle; import android.view.MagnificationSpec; import android.view.accessibility.AccessibilityNodeInfo; @@ -53,4 +54,8 @@ oneway interface IAccessibilityInteractionConnection { void performAccessibilityAction(long accessibilityNodeId, int action, in Bundle arguments, int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags, int interrogatingPid, long interrogatingTid); + + void computeClickPointInScreen(long accessibilityNodeId, in Region bounds, int interactionId, + IAccessibilityInteractionConnectionCallback callback, int interrogatingPid, + long interrogatingTid, in MagnificationSpec spec); } diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl index c1a3ab7..f480216 100644 --- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl +++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl @@ -16,6 +16,7 @@ package android.view.accessibility; +import android.graphics.Point; import android.view.accessibility.AccessibilityNodeInfo; import java.util.List; @@ -51,4 +52,12 @@ oneway interface IAccessibilityInteractionConnectionCallback { * @param interactionId The interaction id to match the result with the request. */ void setPerformAccessibilityActionResult(boolean succeeded, int interactionId); + + /** + * Sets the result of a request to compute a point for clicking in a view. + * + * @param point The point of null if no such point. + * @param interactionId The interaction id to match the result with the request. + */ + void setComputeClickPointInScreenActionResult(in Point point, int interactionId); } diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java index e7ada27..1671faa 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtype.java +++ b/core/java/android/view/inputmethod/InputMethodSubtype.java @@ -211,18 +211,6 @@ public final class InputMethodSubtype implements Parcelable { } /** - * Constructor with no subtype ID specified, overridesImplicitlyEnabledSubtype not specified. - * Arguments for this constructor have the same meanings as - * {@link InputMethodSubtype#InputMethodSubtype(int, int, String, String, String, boolean, - * boolean, int)} except "id" and "overridesImplicitlyEnabledSubtype". - * @hide - */ - public InputMethodSubtype(int nameId, int iconId, String locale, String mode, String extraValue, - boolean isAuxiliary) { - this(nameId, iconId, locale, mode, extraValue, isAuxiliary, false); - } - - /** * Constructor with no subtype ID specified. * @deprecated use {@link InputMethodSubtypeBuilder} instead. * Arguments for this constructor have the same meanings as diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index eef8554..94d52d5 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3325,8 +3325,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } if (dispatchNestedPreScroll(0, -rawDeltaY, mScrollConsumed, mScrollOffset)) { rawDeltaY += mScrollConsumed[1]; - scrollOffsetCorrection -= mScrollOffset[1]; - scrollConsumedCorrection -= mScrollConsumed[1]; + scrollOffsetCorrection = -mScrollOffset[1]; + scrollConsumedCorrection = mScrollConsumed[1]; if (vtev != null) { vtev.offsetLocation(0, mScrollOffset[1]); } @@ -3437,7 +3437,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } - mMotionY = y + scrollOffsetCorrection; + mMotionY = y + lastYCorrection + scrollOffsetCorrection; } mLastY = y + lastYCorrection + scrollOffsetCorrection; } @@ -3505,10 +3505,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mMotionCorrection = 0; View motionView = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = motionView != null ? motionView.getTop() : 0; - mMotionY = y; + mMotionY = y + scrollOffsetCorrection; mMotionPosition = motionPosition; } - mLastY = y; + mLastY = y + lastYCorrection + scrollOffsetCorrection; mDirection = newDirection; } } @@ -3876,7 +3876,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mPositionScroller != null) { mPositionScroller.stop(); } - if (flingVelocity) { + if (flingVelocity && !dispatchNestedPreFling(0, -initialVelocity)) { dispatchNestedFling(0, -initialVelocity, false); } } @@ -4001,14 +4001,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * <p>Applications can use this method to manually initiate a fling as if the user * initiated it via touch interaction.</p> * - * @param velocityY Vertical velocity in pixels per second + * @param velocityY Vertical velocity in pixels per second. Note that this is velocity of + * content, not velocity of a touch that initiated the fling. */ public void fling(int velocityY) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); - mFlingRunnable.start(-velocityY); + mFlingRunnable.start(velocityY); } @Override diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java index 6ca4a9e..7198e52 100644 --- a/core/java/android/widget/ActionMenuView.java +++ b/core/java/android/widget/ActionMenuView.java @@ -611,6 +611,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo mMenu = new MenuBuilder(context); mMenu.setCallback(new MenuBuilderCallback()); mPresenter = new ActionMenuPresenter(context); + mPresenter.setReserveOverflow(true); mPresenter.setCallback(mActionMenuPresenterCallback != null ? mActionMenuPresenterCallback : new ActionMenuPresenterCallback()); mMenu.addMenuPresenter(mPresenter, mPopupContext); diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index d263625..efd6fc0 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -2356,7 +2356,7 @@ public class GridView extends AbsListView { final int rowsCount = getCount() / columnsCount; final int selectionMode = getSelectionModeForAccessibility(); final CollectionInfo collectionInfo = CollectionInfo.obtain( - columnsCount, rowsCount, false, selectionMode); + rowsCount, columnsCount, false, selectionMode); info.setCollectionInfo(collectionInfo); } @@ -2385,7 +2385,7 @@ public class GridView extends AbsListView { final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER; final boolean isSelected = isItemChecked(position); final CollectionItemInfo itemInfo = CollectionItemInfo.obtain( - column, 1, row, 1, isHeading, isSelected); + row, 1, column, 1, isHeading, isSelected); info.setCollectionItemInfo(itemInfo); } } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 1368cd3..2e9858c 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -3882,9 +3882,10 @@ public class ListView extends AbsListView { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(ListView.class.getName()); - final int count = getCount(); + final int rowsCount = getCount(); final int selectionMode = getSelectionModeForAccessibility(); - final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false, selectionMode); + final CollectionInfo collectionInfo = CollectionInfo.obtain( + rowsCount, 1, false, selectionMode); info.setCollectionInfo(collectionInfo); } @@ -3897,7 +3898,7 @@ public class ListView extends AbsListView { final boolean isHeading = lp != null && lp.viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER; final boolean isSelected = isItemChecked(position); final CollectionItemInfo itemInfo = CollectionItemInfo.obtain( - 0, 1, position, 1, isHeading, isSelected); + position, 1, 0, 1, isHeading, isSelected); info.setCollectionItemInfo(itemInfo); } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3e1b674..80ea6ea 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8423,6 +8423,33 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public boolean performAccessibilityAction(int action, Bundle arguments) { switch (action) { + case AccessibilityNodeInfo.ACTION_CLICK: { + boolean handled = false; + + // Simulate View.onTouchEvent for an ACTION_UP event. + if (isClickable() || isLongClickable()) { + if (isFocusable() && !isFocused()) { + requestFocus(); + } + + performClick(); + handled = true; + } + + // Simulate TextView.onTouchEvent for an ACTION_UP event. + if ((mMovement != null || onCheckIsTextEditor()) && isEnabled() + && mText instanceof Spannable && mLayout != null + && (isTextEditable() || isTextSelectable()) && isFocused()) { + // Show the IME, except when selecting in read-only text. + final InputMethodManager imm = InputMethodManager.peekInstance(); + viewClicked(imm); + if (!isTextSelectable() && mEditor.mShowSoftInputOnFocus && imm != null) { + handled |= imm.showSoftInput(this, 0); + } + } + + return handled; + } case AccessibilityNodeInfo.ACTION_COPY: { if (isFocused() && canCopy()) { if (onTextContextMenuItem(ID_COPY)) { diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index b6e7353..107e8c6 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -90,7 +90,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic private boolean mSafeForwardingMode; private boolean mAlwaysUseOption; private boolean mShowExtended; - private GridView mGridView; + private ListView mListView; private Button mAlwaysButton; private Button mOnceButton; private int mIconDpi; @@ -228,10 +228,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic mLaunchedFromUid, alwaysUseOption); final int layoutId; + final boolean useHeader; if (mAdapter.hasFilteredItem()) { layoutId = R.layout.resolver_list_with_default; alwaysUseOption = false; + useHeader = true; } else { + useHeader = false; layoutId = R.layout.resolver_list; } mAlwaysUseOption = alwaysUseOption; @@ -243,16 +246,19 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic return; } else if (count > 1) { setContentView(layoutId); - mGridView = (GridView) findViewById(R.id.resolver_list); - mGridView.setAdapter(mAdapter); - mGridView.setOnItemClickListener(this); - mGridView.setOnItemLongClickListener(new ItemLongClickListener()); + mListView = (ListView) findViewById(R.id.resolver_list); + mListView.setAdapter(mAdapter); + mListView.setOnItemClickListener(this); + mListView.setOnItemLongClickListener(new ItemLongClickListener()); if (alwaysUseOption) { - mGridView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); } - resizeGrid(); + if (useHeader) { + mListView.addHeaderView(LayoutInflater.from(this).inflate( + R.layout.resolver_different_item_header, mListView, false)); + } } else if (count == 1) { safelyStartActivity(mAdapter.intentForPosition(0, false)); mPackageMonitor.unregister(); @@ -265,8 +271,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic final TextView empty = (TextView) findViewById(R.id.empty); empty.setVisibility(View.VISIBLE); - mGridView = (GridView) findViewById(R.id.resolver_list); - mGridView.setVisibility(View.GONE); + mListView = (ListView) findViewById(R.id.resolver_list); + mListView.setVisibility(View.GONE); } final ResolverDrawerLayout rdl = (ResolverDrawerLayout) findViewById(R.id.contentPanel); @@ -340,11 +346,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic } } - void resizeGrid() { - final int itemCount = mAdapter.getCount(); - mGridView.setNumColumns(Math.min(itemCount, mMaxColumns)); - } - void dismiss() { if (!isFinishing()) { finish(); @@ -419,19 +420,24 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (mAlwaysUseOption) { - final int checkedPos = mGridView.getCheckedItemPosition(); + final int checkedPos = mListView.getCheckedItemPosition(); final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION; mLastSelected = checkedPos; setAlwaysButtonEnabled(hasValidSelection, checkedPos, true); mOnceButton.setEnabled(hasValidSelection); if (hasValidSelection) { - mGridView.setSelection(checkedPos); + mListView.setSelection(checkedPos); } } } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + position -= mListView.getHeaderViewsCount(); + if (position < 0) { + // Header views don't count. + return; + } ResolveInfo resolveInfo = mAdapter.resolveInfoForPosition(position, true); if (mResolvingHome && hasManagedProfile() && !supportsManagedProfiles(resolveInfo)) { @@ -441,13 +447,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic Toast.LENGTH_LONG).show(); return; } - final int checkedPos = mGridView.getCheckedItemPosition(); + final int checkedPos = mListView.getCheckedItemPosition(); final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION; if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) { setAlwaysButtonEnabled(hasValidSelection, checkedPos, true); mOnceButton.setEnabled(hasValidSelection); if (hasValidSelection) { - mGridView.smoothScrollToPosition(checkedPos); + mListView.smoothScrollToPosition(checkedPos); } mLastSelected = checkedPos; } else { @@ -504,7 +510,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic public void onButtonClick(View v) { final int id = v.getId(); startSelected(mAlwaysUseOption ? - mGridView.getCheckedItemPosition() : mAdapter.getFilteredPosition(), + mListView.getCheckedItemPosition() : mAdapter.getFilteredPosition(), id == R.id.button_always, mAlwaysUseOption); dismiss(); @@ -714,8 +720,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic if (newItemCount == 0) { // We no longer have any items... just finish the activity. finish(); - } else if (newItemCount != oldItemCount) { - resizeGrid(); } } @@ -957,19 +961,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic } public View getView(int position, View convertView, ViewGroup parent) { - View view; - if (convertView == null) { + View view = convertView; + if (view == null) { view = mInflater.inflate( com.android.internal.R.layout.resolve_list_item, parent, false); final ViewHolder holder = new ViewHolder(view); view.setTag(holder); - - // Fix the icon size even if we have different sized resources - ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); - lp.width = lp.height = mIconSize; - } else { - view = convertView; } bindView(view, getItem(position)); return view; @@ -1007,6 +1005,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { + position -= mListView.getHeaderViewsCount(); + if (position < 0) { + // Header views don't count. + return false; + } ResolveInfo ri = mAdapter.resolveInfoForPosition(position, true); showAppDetails(ri); return true; diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index c17f4ee..7bdb4be 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -390,7 +390,10 @@ public class PackageHelper { if (!emulated && (checkBoth || prefer == RECOMMEND_INSTALL_EXTERNAL)) { final File target = new UserEnvironment(UserHandle.USER_OWNER) .getExternalStorageDirectory(); - fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target)); + // External is only an option when size is known + if (sizeBytes > 0) { + fitsOnExternal = (sizeBytes <= storage.getStorageBytesUntilLow(target)); + } } if (prefer == RECOMMEND_INSTALL_INTERNAL) { diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index c5211bb..c579a15 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -78,17 +78,20 @@ public final class Zygote { * file descriptor numbers that are to be closed by the child * (and replaced by /dev/null) after forking. An integer value * of -1 in any entry in the array means "ignore this one". + * @param instructionSet null-ok the instruction set to use. * * @return 0 if this is the child, pid of the child * if this is the parent, or -1 on error. */ public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, - int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose) { + int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, + String instructionSet) { long startTime = SystemClock.elapsedRealtime(); VM_HOOKS.preFork(); checkTime(startTime, "Zygote.preFork"); int pid = nativeForkAndSpecialize( - uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose); + uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, + instructionSet); checkTime(startTime, "Zygote.nativeForkAndSpecialize"); VM_HOOKS.postForkCommon(); checkTime(startTime, "Zygote.postForkCommon"); @@ -96,7 +99,8 @@ public final class Zygote { } native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags, - int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose); + int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, + String instructionSet); /** * Temporary hack: check time since start time and log if over a fixed threshold. @@ -145,9 +149,9 @@ public final class Zygote { native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, long permittedCapabilities, long effectiveCapabilities); - private static void callPostForkChildHooks(int debugFlags) { + private static void callPostForkChildHooks(int debugFlags, String instructionSet) { long startTime = SystemClock.elapsedRealtime(); - VM_HOOKS.postForkChild(debugFlags); + VM_HOOKS.postForkChild(debugFlags, instructionSet); checkTime(startTime, "Zygote.callPostForkChildHooks"); } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index b4c4da6..fb50b25 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -245,7 +245,7 @@ class ZygoteConnection { checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize"); pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, - parsedArgs.niceName, fdsToClose); + parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet); checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize"); } catch (IOException ex) { logAndPrintError(newStderr, "Exception creating pipe", ex); @@ -335,6 +335,7 @@ class ZygoteConnection { * [--] <args for RuntimeInit > * <li> If <code>--runtime-init</code> is absent: * [--] <classname> [args...] + * <li> --instruction-set=<i>instruction-set-string</i> which instruction set to use/emulate. * </ul> */ static class Arguments { @@ -398,6 +399,11 @@ class ZygoteConnection { boolean abiListQuery; /** + * The instruction set to use, or null when not important. + */ + String instructionSet; + + /** * Constructs instance and parses args * @param args zygote command-line args * @throws IllegalArgumentException @@ -552,6 +558,8 @@ class ZygoteConnection { mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; } else if (arg.equals("--query-abi-list")) { abiListQuery = true; + } else if (arg.startsWith("--instruction-set=")) { + instructionSet = arg.substring(arg.indexOf('=') + 1); } else { break; } diff --git a/core/java/com/android/internal/util/ParcelableString.java b/core/java/com/android/internal/util/ParcelableString.java new file mode 100644 index 0000000..6bd856f --- /dev/null +++ b/core/java/com/android/internal/util/ParcelableString.java @@ -0,0 +1,52 @@ +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.util; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Helper class to adapt a simple String to cases where a Parcelable is expected. + * @hide + */ +public class ParcelableString implements Parcelable { + public String string; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeString(string); + } + + public static final Parcelable.Creator<ParcelableString> CREATOR = + new Parcelable.Creator<ParcelableString>() { + @Override + public ParcelableString createFromParcel(Parcel in) { + ParcelableString ret = new ParcelableString(); + ret.string = in.readString(); + return ret; + } + @Override + public ParcelableString[] newArray(int size) { + return new ParcelableString[size]; + } + }; +}
\ No newline at end of file diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 7db70ba..45d790b 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -1440,6 +1440,16 @@ public class XmlUtils { return Boolean.parseBoolean(value); } + public static boolean readBooleanAttribute(XmlPullParser in, String name, + boolean defaultValue) { + final String value = in.getAttributeValue(null, name); + if (value == null) { + return defaultValue; + } else { + return Boolean.parseBoolean(value); + } + } + public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value) throws IOException { out.attribute(null, name, Boolean.toString(value)); diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index e53f9dd..375822f 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -20,15 +20,15 @@ package com.android.internal.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; -import android.view.Gravity; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; - import android.view.ViewParent; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; @@ -68,6 +68,7 @@ public class ResolverDrawerLayout extends ViewGroup { private boolean mIsDragging; private boolean mOpenOnClick; + private boolean mOpenOnLayout; private final int mTouchSlop; private final float mMinFlingVelocity; private final OverScroller mScroller; @@ -202,6 +203,8 @@ public class ResolverDrawerLayout extends ViewGroup { public boolean onTouchEvent(MotionEvent ev) { final int action = ev.getActionMasked(); + mVelocityTracker.addMovement(ev); + boolean handled = false; switch (action) { case MotionEvent.ACTION_DOWN: { @@ -288,6 +291,10 @@ public class ResolverDrawerLayout extends ViewGroup { break; case MotionEvent.ACTION_CANCEL: { + if (mIsDragging) { + smoothScrollTo( + mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0); + } resetTouch(); return true; } @@ -498,28 +505,39 @@ public class ResolverDrawerLayout extends ViewGroup { @Override public void onStopNestedScroll(View child) { super.onStopNestedScroll(child); - smoothScrollTo(mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0); + if (mScroller.isFinished()) { + smoothScrollTo(mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0); + } } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { - if (dyUnconsumed > 0) { + if (dyUnconsumed < 0) { performDrag(-dyUnconsumed); } } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { - if (dy < 0) { - consumed[1] = (int) performDrag(-dy); + if (dy > 0) { + consumed[1] = (int) -performDrag(-dy); } } @Override + public boolean onNestedPreFling(View target, float velocityX, float velocityY) { + if (velocityY > mMinFlingVelocity && mCollapseOffset != 0) { + smoothScrollTo(0, velocityY); + return true; + } + return false; + } + + @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) { - smoothScrollTo(velocityY < 0 ? 0 : mCollapsibleHeight, velocityY); + smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY); return true; } return false; @@ -571,8 +589,8 @@ public class ResolverDrawerLayout extends ViewGroup { if (isLaidOut()) { mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight); } else { - // Start out collapsed at first - mCollapseOffset = mCollapsibleHeight; + // Start out collapsed at first unless we restored state for otherwise + mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight; } mTopOffset = Math.max(0, heightSize - heightUsed) + (int) mCollapseOffset; @@ -634,6 +652,20 @@ public class ResolverDrawerLayout extends ViewGroup { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); } + @Override + protected Parcelable onSaveInstanceState() { + final SavedState ss = new SavedState(super.onSaveInstanceState()); + ss.open = mCollapsibleHeight > 0 && mCollapseOffset == 0; + return ss; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + final SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + mOpenOnLayout = ss.open; + } + public static class LayoutParams extends MarginLayoutParams { public boolean alwaysShow; public boolean ignoreOffset; @@ -670,4 +702,36 @@ public class ResolverDrawerLayout extends ViewGroup { super(source); } } + + static class SavedState extends BaseSavedState { + boolean open; + + SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + open = in.readInt() != 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(open ? 1 : 0); + } + + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 2106d38..dbaa4b8 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -129,6 +129,7 @@ LOCAL_SRC_FILES:= \ android/graphics/Xfermode.cpp \ android/graphics/YuvToJpegEncoder.cpp \ android/graphics/pdf/PdfDocument.cpp \ + android/graphics/pdf/PdfEditor.cpp \ android/graphics/pdf/PdfRenderer.cpp \ android_media_AudioRecord.cpp \ android_media_AudioSystem.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 62d8036..a63258c 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -126,6 +126,7 @@ extern int register_android_graphics_Region(JNIEnv* env); extern int register_android_graphics_SurfaceTexture(JNIEnv* env); extern int register_android_graphics_Xfermode(JNIEnv* env); extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env); +extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env); extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env); extern int register_android_view_DisplayEventReceiver(JNIEnv* env); extern int register_android_view_RenderNode(JNIEnv* env); @@ -1305,6 +1306,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_Xfermode), REG_JNI(register_android_graphics_YuvImage), REG_JNI(register_android_graphics_pdf_PdfDocument), + REG_JNI(register_android_graphics_pdf_PdfEditor), REG_JNI(register_android_graphics_pdf_PdfRenderer), REG_JNI(register_android_database_CursorWindow), diff --git a/core/jni/android/graphics/pdf/PdfEditor.cpp b/core/jni/android/graphics/pdf/PdfEditor.cpp new file mode 100644 index 0000000..5f60c9e --- /dev/null +++ b/core/jni/android/graphics/pdf/PdfEditor.cpp @@ -0,0 +1,161 @@ +/* + * 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. + */ + +#include "jni.h" +#include "JNIHelp.h" +#include "fpdfview.h" +#include "fpdfedit.h" +#include "fpdfsave.h" + +#include <android_runtime/AndroidRuntime.h> +#include <vector> +#include <utils/Log.h> +#include <unistd.h> +#include <sys/types.h> +#include <unistd.h> + +namespace android { + +static Mutex sLock; + +static int sUnmatchedInitRequestCount = 0; + +static void initializeLibraryIfNeeded() { + Mutex::Autolock _l(sLock); + if (sUnmatchedInitRequestCount == 0) { + FPDF_InitLibrary(NULL); + } + sUnmatchedInitRequestCount++; +} + +static void destroyLibraryIfNeeded() { + Mutex::Autolock _l(sLock); + sUnmatchedInitRequestCount--; + if (sUnmatchedInitRequestCount == 0) { + FPDF_DestroyLibrary(); + } +} + +static int getBlock(void* param, unsigned long position, unsigned char* outBuffer, + unsigned long size) { + const int fd = reinterpret_cast<intptr_t>(param); + const int readCount = pread(fd, outBuffer, size, position); + if (readCount < 0) { + ALOGE("Cannot read from file descriptor. Error:%d", errno); + return 0; + } + return 1; +} + +static jlong nativeOpen(JNIEnv* env, jclass thiz, jint fd, jlong size) { + initializeLibraryIfNeeded(); + + FPDF_FILEACCESS loader; + loader.m_FileLen = size; + loader.m_Param = reinterpret_cast<void*>(intptr_t(fd)); + loader.m_GetBlock = &getBlock; + + FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, NULL); + + if (!document) { + const long error = FPDF_GetLastError(); + jniThrowException(env, "java/io/IOException", + "cannot create document. Error:" + error); + destroyLibraryIfNeeded(); + return -1; + } + + return reinterpret_cast<jlong>(document); +} + +static void nativeClose(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDF_CloseDocument(document); + destroyLibraryIfNeeded(); +} + +static jint nativeGetPageCount(JNIEnv* env, jclass thiz, jlong documentPtr) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + return FPDF_GetPageCount(document); +} + +static jint nativeRemovePage(JNIEnv* env, jclass thiz, jlong documentPtr, jint pageIndex) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + FPDFPage_Delete(document, pageIndex); + return FPDF_GetPageCount(document); +} + +struct PdfToFdWriter : FPDF_FILEWRITE { + int dstFd; +}; + +static bool writeAllBytes(const int fd, const void* buffer, const size_t byteCount) { + char* writeBuffer = static_cast<char*>(const_cast<void*>(buffer)); + size_t remainingBytes = byteCount; + while (remainingBytes > 0) { + ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes); + if (writtenByteCount == -1) { + if (errno == EINTR) { + continue; + } + __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, + "Error writing to buffer: %d", errno); + return false; + } + remainingBytes -= writtenByteCount; + writeBuffer += writtenByteCount; + } + return true; +} + +static int writeBlock(FPDF_FILEWRITE* owner, const void* buffer, unsigned long size) { + const PdfToFdWriter* writer = reinterpret_cast<PdfToFdWriter*>(owner); + const bool success = writeAllBytes(writer->dstFd, buffer, size); + if (success < 0) { + ALOGE("Cannot write to file descriptor. Error:%d", errno); + return 0; + } + return 1; +} + +static void nativeWrite(JNIEnv* env, jclass thiz, jlong documentPtr, jint fd) { + FPDF_DOCUMENT document = reinterpret_cast<FPDF_DOCUMENT>(documentPtr); + PdfToFdWriter writer; + writer.dstFd = fd; + writer.WriteBlock = &writeBlock; + const bool success = FPDF_SaveAsCopy(document, &writer, FPDF_NO_INCREMENTAL); + if (!success) { + jniThrowException(env, "java/io/IOException", + "cannot write to fd. Error:" + errno); + destroyLibraryIfNeeded(); + } +} + +static JNINativeMethod gPdfEditor_Methods[] = { + {"nativeOpen", "(IJ)J", (void*) nativeOpen}, + {"nativeClose", "(J)V", (void*) nativeClose}, + {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount}, + {"nativeRemovePage", "(JI)I", (void*) nativeRemovePage}, + {"nativeWrite", "(JI)V", (void*) nativeWrite} +}; + +int register_android_graphics_pdf_PdfEditor(JNIEnv* env) { + return android::AndroidRuntime::registerNativeMethods( + env, "android/graphics/pdf/PdfEditor", gPdfEditor_Methods, + NELEM(gPdfEditor_Methods)); +}; + +}; diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 8f30f5d..06c22ae 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -117,7 +117,8 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, - jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { + jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform, + int rotation) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { return NULL; @@ -131,17 +132,13 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient()); status_t res; - if (width > 0 && height > 0) { - if (allLayers) { - res = screenshot->update(displayToken, sourceCrop, width, height, - useIdentityTransform); - } else { - res = screenshot->update(displayToken, sourceCrop, width, height, - minLayer, maxLayer, useIdentityTransform); - } - } else { - res = screenshot->update(displayToken, sourceCrop, useIdentityTransform); + if (allLayers) { + minLayer = 0; + maxLayer = -1UL; } + + res = screenshot->update(displayToken, sourceCrop, width, height, + minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation)); if (res != NO_ERROR) { return NULL; } @@ -588,7 +585,7 @@ static JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDestroy", "(J)V", (void*)nativeDestroy }, - {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;", + {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", (void*)nativeScreenshot }, diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index c84a466..2e2d0c7 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -175,17 +175,23 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, continue; } } - // Skip whitespace. - while (*pos == ' ') { - pos++; - } - // Next field is tag. - rawTag = strtoll(pos, &endPos, 16); - //ALOGI("Index #%d: %s", idx, buffer); - if (pos == endPos) { - ALOGE("bad tag: %s", pos); - fclose(fp); - return -1; + + // Ignore whitespace + while (*pos == ' ') pos++; + + // Find end of tag field + endPos = pos; + while (*endPos != ' ') endPos++; + + // Three digit field is always 0x0, otherwise parse + if (endPos - pos == 3) { + rawTag = 0; + } else { + if (sscanf(pos, "%llx", &rawTag) != 1) { + ALOGE("bad tag: %s", pos); + fclose(fp); + return -1; + } } s.tag = rawTag >> 32; if (limitTag != -1 && s.tag != limitTag) { @@ -193,10 +199,10 @@ static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats, continue; } pos = endPos; - // Skip whitespace. - while (*pos == ' ') { - pos++; - } + + // Ignore whitespace + while (*pos == ' ') pos++; + // Parse remaining fields. if (sscanf(pos, "%u %u %llu %llu %llu %llu", &s.uid, &s.set, &s.rxBytes, &s.rxPackets, diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 3d2d471..451d97a 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -421,7 +421,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, - bool is_system_server, jintArray fdsToClose) { + bool is_system_server, jintArray fdsToClose, + jstring instructionSet) { uint64_t start = MsTime(); SetSigChldHandler(); ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler"); @@ -542,7 +543,8 @@ static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArra ckTime(start, "ForkAndSpecializeCommon:child process setup"); - env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags); + env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags, + is_system_server ? NULL : instructionSet); ckTime(start, "ForkAndSpecializeCommon:PostForkChildHooks returns"); if (env->ExceptionCheck()) { ALOGE("Error calling post fork hooks."); @@ -561,7 +563,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( JNIEnv* env, jclass, jint uid, jint gid, jintArray gids, jint debug_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose) { + jintArray fdsToClose, jstring instructionSet) { // Grant CAP_WAKE_ALARM to the Bluetooth process. jlong capabilities = 0; if (uid == AID_BLUETOOTH) { @@ -570,7 +572,7 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize( return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, capabilities, capabilities, mount_external, se_info, - se_name, false, fdsToClose); + se_name, false, fdsToClose, instructionSet); } static jint com_android_internal_os_Zygote_nativeForkSystemServer( @@ -580,7 +582,7 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, effectiveCapabilities, - MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL); + MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL); if (pid > 0) { // The zygote process checks whether the child process has died or not. ALOGI("System server process %d has been created", pid); @@ -598,7 +600,8 @@ static jint com_android_internal_os_Zygote_nativeForkSystemServer( } static JNINativeMethod gMethods[] = { - { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I)I", + { "nativeForkAndSpecialize", + "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;)I", (void *) com_android_internal_os_Zygote_nativeForkAndSpecialize }, { "nativeForkSystemServer", "(II[II[[IJJ)I", (void *) com_android_internal_os_Zygote_nativeForkSystemServer } @@ -609,7 +612,8 @@ int register_com_android_internal_os_Zygote(JNIEnv* env) { if (gZygoteClass == NULL) { RuntimeAbort(env); } - gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks", "(I)V"); + gCallPostForkChildHooks = env->GetStaticMethodID(gZygoteClass, "callPostForkChildHooks", + "(ILjava/lang/String;)V"); return AndroidRuntime::registerNativeMethods(env, "com/android/internal/os/Zygote", gMethods, NELEM(gMethods)); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 72dd930..bf2d09b 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2502,7 +2502,7 @@ <permission android:name="android.permission.PACKAGE_USAGE_STATS" android:label="@string/permlab_pkgUsageStats" android:description="@string/permdesc_pkgUsageStats" - android:protectionLevel="signature|system|development|appop" /> + android:protectionLevel="signature|development|appop" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <!-- @SystemApi Allows an application to collect battery statistics --> @@ -2773,7 +2773,7 @@ android:description="@string/permdesc_bindNotificationListenerService" android:protectionLevel="signature" /> - <!-- Must be required by an {@link + <!-- @SystemApi Must be required by a {@link android.service.notification.ConditionProviderService}, to ensure that only the system can bind to it. @hide --> diff --git a/core/res/res/drawable/emulator_circular_window_overlay.xml b/core/res/res/drawable/emulator_circular_window_overlay.xml new file mode 100644 index 0000000..7616b37 --- /dev/null +++ b/core/res/res/drawable/emulator_circular_window_overlay.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<!-- Default to an empty shape drawable --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> +</shape> diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml index 5f9066a..be89e41 100644 --- a/core/res/res/layout/alert_dialog_material.xml +++ b/core/res/res/layout/alert_dialog_material.xml @@ -33,8 +33,7 @@ android:gravity="center_vertical|start" android:paddingStart="@dimen/alert_dialog_padding_material" android:paddingEnd="@dimen/alert_dialog_padding_material" - android:paddingTop="@dimen/alert_dialog_padding_material" - android:paddingBottom="8dip"> + android:paddingTop="@dimen/alert_dialog_padding_top_material"> <ImageView android:id="@+id/icon" android:layout_width="32dip" android:layout_height="32dip" @@ -57,7 +56,8 @@ android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" - android:minHeight="64dp"> + android:minHeight="64dp" + android:paddingTop="@dimen/alert_dialog_padding_top_material"> <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -67,9 +67,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="@dimen/alert_dialog_padding_material" - android:paddingEnd="@dimen/alert_dialog_padding_material" - android:paddingTop="@dimen/alert_dialog_padding_material" - android:paddingBottom="@dimen/alert_dialog_padding_material" /> + android:paddingEnd="@dimen/alert_dialog_padding_material" /> </ScrollView> </LinearLayout> @@ -89,15 +87,14 @@ android:layout_height="wrap_content" android:layoutDirection="locale" android:orientation="horizontal" - android:paddingStart="6dp" - android:paddingEnd="6dp" - android:paddingBottom="6dp"> + android:paddingStart="12dp" + android:paddingEnd="12dp" + android:paddingTop="8dp" + android:paddingBottom="8dp"> <Button android:id="@+id/button3" style="?attr/buttonBarNeutralButtonStyle" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="2" - android:minHeight="@dimen/alert_dialog_button_bar_height" /> + android:layout_height="wrap_content" /> <Space android:layout_width="0dp" android:layout_height="0dp" @@ -106,14 +103,10 @@ <Button android:id="@+id/button2" style="?attr/buttonBarNegativeButtonStyle" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="2" - android:minHeight="@dimen/alert_dialog_button_bar_height" /> + android:layout_height="wrap_content" /> <Button android:id="@+id/button1" style="?attr/buttonBarPositiveButtonStyle" android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:maxLines="2" - android:minHeight="@dimen/alert_dialog_button_bar_height" /> + android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> diff --git a/core/res/res/layout/alert_dialog_progress_material.xml b/core/res/res/layout/alert_dialog_progress_material.xml index b9d0814..d005a44 100644 --- a/core/res/res/layout/alert_dialog_progress_material.xml +++ b/core/res/res/layout/alert_dialog_progress_material.xml @@ -17,32 +17,27 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" - android:layout_height="match_parent"> - <ProgressBar android:id="@+id/progress" - style="?android:attr/progressBarStyleHorizontal" + android:layout_height="match_parent" + android:paddingStart="@dimen/alert_dialog_padding_material" + android:paddingTop="@dimen/alert_dialog_padding_top_material" + android:paddingEnd="@dimen/alert_dialog_padding_material" + android:paddingBottom="@dimen/alert_dialog_padding_top_material"> + <ProgressBar + android:id="@+id/progress" + style="?attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dip" - android:layout_marginBottom="1dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/progress_percent" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="16dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" android:layout_alignParentStart="true" android:layout_below="@id/progress" /> <TextView android:id="@+id/progress_number" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingBottom="16dip" - android:layout_marginStart="16dip" - android:layout_marginEnd="16dip" android:layout_alignParentEnd="true" android:layout_below="@id/progress" /> </RelativeLayout> diff --git a/core/res/res/layout/dialog_custom_title_material.xml b/core/res/res/layout/dialog_custom_title_material.xml index 550b72e..248a05e 100644 --- a/core/res/res/layout/dialog_custom_title_material.xml +++ b/core/res/res/layout/dialog_custom_title_material.xml @@ -23,17 +23,17 @@ This is a custom layout for a dialog. android:fitsSystemWindows="true"> <FrameLayout android:id="@android:id/title_container" android:layout_width="match_parent" - android:layout_height="?android:attr/windowTitleSize" + android:layout_height="?attr/windowTitleSize" android:layout_weight="0" android:gravity="center_vertical|start" - style="?android:attr/windowTitleBackgroundStyle" /> + style="?attr/windowTitleBackgroundStyle" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" - android:foreground="?android:attr/windowContentOverlay"> - <FrameLayout android:id="@android:id/content" + android:foreground="?attr/windowContentOverlay"> + <FrameLayout android:id="@id/content" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> diff --git a/core/res/res/layout/dialog_title_icons_material.xml b/core/res/res/layout/dialog_title_icons_material.xml index 28e20d9..21396da 100644 --- a/core/res/res/layout/dialog_title_icons_material.xml +++ b/core/res/res/layout/dialog_title_icons_material.xml @@ -28,16 +28,16 @@ enabled. android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center_vertical" - android:paddingStart="16dip" - android:paddingEnd="16dip" - android:paddingTop="16dip"> + android:paddingStart="@dimen/alert_dialog_padding_material" + android:paddingEnd="@dimen/alert_dialog_padding_material" + android:paddingTop="@dimen/alert_dialog_padding_material"> <ImageView android:id="@+id/left_icon" android:layout_width="32dip" android:layout_height="32dip" android:scaleType="fitCenter" android:layout_marginEnd="8dip" /> - <TextView android:id="@android:id/title" - style="?android:attr/windowTitleStyle" + <TextView android:id="@id/title" + style="?attr/windowTitleStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0" /> @@ -52,8 +52,8 @@ enabled. android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" - android:foreground="?android:attr/windowContentOverlay"> - <FrameLayout android:id="@android:id/content" + android:foreground="?attr/windowContentOverlay"> + <FrameLayout android:id="@id/content" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> diff --git a/core/res/res/layout/dialog_title_material.xml b/core/res/res/layout/dialog_title_material.xml index 918c8f1..fcf6164 100644 --- a/core/res/res/layout/dialog_title_material.xml +++ b/core/res/res/layout/dialog_title_material.xml @@ -29,15 +29,15 @@ enabled. android:layout_width="match_parent" android:layout_height="wrap_content" android:textAlignment="viewStart" - android:paddingStart="16dip" - android:paddingEnd="16dip" - android:paddingTop="16dip" /> + android:paddingStart="@dimen/alert_dialog_padding_material" + android:paddingEnd="@dimen/alert_dialog_padding_material" + android:paddingTop="@dimen/alert_dialog_padding_top_material" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" - android:foreground="?android:attr/windowContentOverlay"> - <FrameLayout android:id="@android:id/content" + android:foreground="?attr/windowContentOverlay"> + <FrameLayout android:id="@id/content" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml index 2382d18..8a66c3f 100644 --- a/core/res/res/layout/notification_template_material_inbox.xml +++ b/core/res/res/layout/notification_template_material_inbox.xml @@ -44,6 +44,7 @@ android:layout_width="match_parent" android:layout_weight="1" android:layout_height="0dp" + android:layout_marginEnd="8dp" android:orientation="horizontal" > <TextView android:id="@+id/inbox_text0" @@ -60,7 +61,6 @@ android:layout_height="@dimen/notification_badge_size" android:layout_weight="0" android:layout_marginStart="4dp" - android:layout_marginEnd="8dp" android:scaleType="fitCenter" android:visibility="gone" /> diff --git a/core/res/res/layout/notification_template_part_line2.xml b/core/res/res/layout/notification_template_part_line2.xml index 7e99c5e..aeef3ab 100644 --- a/core/res/res/layout/notification_template_part_line2.xml +++ b/core/res/res/layout/notification_template_part_line2.xml @@ -45,13 +45,13 @@ android:visibility="gone" /> </LinearLayout> - <ProgressBar + <ViewStub android:id="@android:id/progress" + android:layout="@layout/notification_template_progressbar" android:layout_width="match_parent" android:layout_height="15dp" android:layout_marginEnd="8dp" android:visibility="gone" android:layout_weight="0" - style="@style/Widget.Material.Light.ProgressBar.Horizontal" /> </merge> diff --git a/core/res/res/layout/notification_template_progressbar.xml b/core/res/res/layout/notification_template_progressbar.xml new file mode 100644 index 0000000..61480b8 --- /dev/null +++ b/core/res/res/layout/notification_template_progressbar.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> + +<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@android:id/progress" + android:layout_width="match_parent" + android:layout_height="match_parent" + style="@style/Widget.Material.Light.ProgressBar.Horizontal" + /> diff --git a/core/res/res/layout/progress_dialog_material.xml b/core/res/res/layout/progress_dialog_material.xml index 84d06b5..54af106 100644 --- a/core/res/res/layout/progress_dialog_material.xml +++ b/core/res/res/layout/progress_dialog_material.xml @@ -19,21 +19,27 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - <LinearLayout android:id="@+id/body" + <LinearLayout + android:id="@+id/body" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" - android:padding="16dip"> + android:paddingStart="@dimen/alert_dialog_padding_material" + android:paddingTop="@dimen/alert_dialog_padding_top_material" + android:paddingEnd="@dimen/alert_dialog_padding_material" + android:paddingBottom="@dimen/alert_dialog_padding_top_material"> - <ProgressBar android:id="@android:id/progress" + <ProgressBar + android:id="@id/progress" style="?android:attr/progressBarStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:max="10000" - android:layout_marginEnd="16dip" /> + android:layout_marginEnd="@dimen/alert_dialog_padding_material" /> - <TextView android:id="@+id/message" + <TextView + android:id="@+id/message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml index 7aa9a72..37c4270 100644 --- a/core/res/res/layout/resolve_list_item.xml +++ b/core/res/res/layout/resolve_list_item.xml @@ -18,9 +18,10 @@ */ --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" + android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="match_parent" + android:minHeight="?attr/listPreferredItemHeightSmall" android:paddingTop="4dp" android:paddingBottom="4dp" android:background="?attr/activatedBackgroundIndicator"> @@ -28,37 +29,40 @@ <!-- Activity icon when presenting dialog Size will be filled in by ResolverActivity --> <ImageView android:id="@+id/icon" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_gravity="center" - android:layout_margin="4dp" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="start|center_vertical" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp" android:scaleType="fitCenter" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:gravity="center" + android:gravity="start|center_vertical" android:orientation="vertical" + android:paddingStart="16dp" + android:paddingEnd="16dp" android:layout_height="wrap_content" android:layout_width="wrap_content" - android:layout_gravity="center"> + android:layout_gravity="start|center_vertical"> <!-- Activity name --> <TextView android:id="@android:id/text1" - android:textAppearance="?android:attr/textAppearanceSmall" - android:fontFamily="sans-serif-condensed" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:gravity="center" - android:minLines="2" - android:maxLines="2" /> + android:textAppearance="?attr/textAppearanceMedium" + android:textColor="?attr/textColorPrimary" + android:minLines="1" + android:maxLines="1" + android:ellipsize="marquee" /> <!-- Extended activity info to distinguish between duplicate activity names --> <TextView android:id="@android:id/text2" android:textAppearance="?android:attr/textAppearanceSmall" - android:fontFamily="sans-serif-condensed" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:gravity="center" - android:minLines="2" - android:maxLines="2" - android:paddingTop="4dip" /> + android:minLines="1" + android:maxLines="1" + android:ellipsize="marquee" /> </LinearLayout> </LinearLayout> diff --git a/core/res/res/layout/resolver_different_item_header.xml b/core/res/res/layout/resolver_different_item_header.xml new file mode 100644 index 0000000..5889136 --- /dev/null +++ b/core/res/res/layout/resolver_different_item_header.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_alwaysShow="true" + android:text="@string/use_a_different_app" + android:minHeight="56dp" + android:textAppearance="?android:attr/textAppearanceMedium" + android:gravity="start|center_vertical" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:background="@color/white" + android:elevation="8dp" + /> diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml index 8e57543..727f9c6 100644 --- a/core/res/res/layout/resolver_list.xml +++ b/core/res/res/layout/resolver_list.xml @@ -21,38 +21,36 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:maxWidth="@dimen/resolver_max_width" - android:maxCollapsedHeight="260dp" + android:maxCollapsedHeight="192dp" android:maxCollapsedHeightSmall="56dp" android:id="@id/contentPanel" > <TextView android:id="@+id/title" android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeight" + android:layout_height="wrap_content" android:layout_alwaysShow="true" + android:minHeight="56dp" android:textAppearance="?android:attr/textAppearanceMedium" android:gravity="start|center_vertical" - android:paddingLeft="32dp" - android:paddingRight="32dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" android:background="@color/white" android:elevation="8dp" /> - <GridView + <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/resolver_list" - android:numColumns="4" - android:columnWidth="128dp" android:clipToPadding="false" android:scrollbarStyle="outsideOverlay" - android:paddingLeft="32dp" - android:paddingRight="32dp" - android:paddingTop="16dp" - android:paddingBottom="16dp" android:background="@color/white" android:elevation="8dp" android:nestedScrollingEnabled="true" + android:divider="@null" /> <TextView android:id="@+id/empty" @@ -72,14 +70,15 @@ android:layout_height="wrap_content" android:layout_ignoreOffset="true" android:layout_alwaysShow="true" - android:gravity="end" + android:gravity="end|center_vertical" android:orientation="horizontal" android:layoutDirection="locale" android:measureWithLargestChild="true" android:background="@color/white" - android:paddingBottom="16dp" - android:paddingStart="32dp" - android:paddingEnd="32dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:paddingStart="12dp" + android:paddingEnd="12dp" android:elevation="8dp"> <Button android:id="@+id/button_once" android:layout_width="wrap_content" diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml index 0bd0e14..884f41e 100644 --- a/core/res/res/layout/resolver_list_with_default.xml +++ b/core/res/res/layout/resolver_list_with_default.xml @@ -21,7 +21,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:maxWidth="@dimen/resolver_max_width" - android:maxCollapsedHeight="48dp" + android:maxCollapsedHeight="144dp" android:id="@id/contentPanel" > @@ -35,26 +35,28 @@ <LinearLayout android:layout_width="match_parent" - android:layout_height="80dp" - android:paddingStart="32dp" - android:paddingEnd="32dp" + android:layout_height="64dp" android:orientation="horizontal" > + <ImageView android:id="@+id/icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="start|top" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginTop="20dp" + android:scaleType="fitCenter" + /> <TextView android:id="@+id/title" android:layout_width="0dp" android:layout_weight="1" android:layout_height="?android:attr/listPreferredItemHeight" + android:layout_marginStart="16dp" android:textAppearance="?android:attr/textAppearanceMedium" android:gravity="start|center_vertical" android:paddingEnd="16dp" /> - <ImageView android:id="@+id/icon" - android:layout_width="56dp" - android:layout_height="56dp" - android:layout_gravity="center_vertical" - android:scaleType="fitCenter" - /> </LinearLayout> <LinearLayout @@ -64,13 +66,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alwaysShow="true" - android:gravity="end" + android:gravity="end|center_vertical" android:orientation="horizontal" android:layoutDirection="locale" android:measureWithLargestChild="true" - android:paddingBottom="16dp" - android:paddingStart="32dp" - android:paddingEnd="32dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:paddingStart="12dp" + android:paddingEnd="12dp" android:background="@color/white" android:elevation="8dp"> <Button android:id="@+id/button_once" @@ -99,21 +102,16 @@ android:background="?android:attr/dividerVertical" /> </LinearLayout> - <GridView + <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/resolver_list" - android:numColumns="4" - android:columnWidth="128dp" android:clipToPadding="false" android:scrollbarStyle="outsideOverlay" - android:paddingLeft="32dp" - android:paddingRight="32dp" - android:paddingTop="16dp" - android:paddingBottom="16dp" android:background="@color/white" android:elevation="8dp" android:nestedScrollingEnabled="true" + android:divider="@null" /> </com.android.internal.widget.ResolverDrawerLayout> diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml index 5259152..06b6efe 100644 --- a/core/res/res/values-mcc302-mnc220/config.xml +++ b/core/res/res/values-mcc302-mnc220/config.xml @@ -25,4 +25,6 @@ <item>302720</item> <item>302780</item> </string-array> + + <integer name="config_mobile_mtu">1410</integer> </resources> diff --git a/core/res/res/values-mcc310-mnc004/config.xml b/core/res/res/values-mcc310-mnc004/config.xml index 2778b6e..423e250 100644 --- a/core/res/res/values-mcc310-mnc004/config.xml +++ b/core/res/res/values-mcc310-mnc004/config.xml @@ -34,11 +34,4 @@ </string-array> <bool name="config_auto_attach_data_on_creation">false</bool> - - <!-- Values for GPS configuration (Verizon) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x31</item> - <item>LPP_PROFILE=3</item> - <item>GPS_LOCK=3</item> - </string-array> </resources> diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml index 3b95db5..62001d9 100644 --- a/core/res/res/values-mcc310-mnc120/config.xml +++ b/core/res/res/values-mcc310-mnc120/config.xml @@ -25,10 +25,4 @@ --> <integer name="config_mobile_mtu">1422</integer> - <!-- Values for GPS configuration (Sprint) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x31</item> - <item>GPS_LOCK=3</item> - <item>LPP_PROFILE=2</item> - </string-array> </resources> diff --git a/core/res/res/values-mcc310-mnc150/config.xml b/core/res/res/values-mcc310-mnc150/config.xml index 00d2db8..f1936f4 100644 --- a/core/res/res/values-mcc310-mnc150/config.xml +++ b/core/res/res/values-mcc310-mnc150/config.xml @@ -33,10 +33,4 @@ <item>315</item> <item>316</item> </string-array> - <!-- Values for GPS configuration (AT&T) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x33</item> - <item>LPP_PROFILE=3</item> - <item>GPS_LOCK=1</item> - </string-array> </resources> diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml index f8fff3b..28cd695 100644 --- a/core/res/res/values-mcc310-mnc260/config.xml +++ b/core/res/res/values-mcc310-mnc260/config.xml @@ -29,11 +29,4 @@ carrier provisioning. If false: hard disabled. If true: then depends on carrier provisioning, availability etc --> <bool name="config_carrier_volte_vt_available">true</bool> - - <!-- Values for GPS configuration (T-Mobile) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITEIS=0x33</item> - <item>GPS_LOCK=1</item> - <item>LPP_PROFILE=2</item> - </string-array> </resources> diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml index edf6d9f..b863aae 100644 --- a/core/res/res/values-mcc310-mnc410/config.xml +++ b/core/res/res/values-mcc310-mnc410/config.xml @@ -40,12 +40,6 @@ <item>315</item> <item>316</item> </string-array> - <!-- Values for GPS configuration (AT&T) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x33</item> - <item>GPS_LOCK=1</item> - <item>LPP_PROFILE=3</item> - </string-array> <!-- Do not translate. Defines the slots is Two Digit Number for dialing normally not USSD --> <string-array name="config_twoDigitNumberPattern"> <item>"0"</item> diff --git a/core/res/res/values-mcc311-mnc190/config.xml b/core/res/res/values-mcc311-mnc190/config.xml index b4e436d..a6c4d1b 100644 --- a/core/res/res/values-mcc311-mnc190/config.xml +++ b/core/res/res/values-mcc311-mnc190/config.xml @@ -37,11 +37,4 @@ note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" --> <string translatable="false" name="config_tether_apndata">Tether,broadband.cellular1.net,,,,,,,,,311,190,,DUN</string> - <!-- Values for GPS configuration (Sprint) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x31</item> - <item>GPS_LOCK=3</item> - <item>LPP_PROFILE=2</item> - </string-array> - </resources> diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml index 57ecd31..cf19235 100644 --- a/core/res/res/values-mcc311-mnc480/config.xml +++ b/core/res/res/values-mcc311-mnc480/config.xml @@ -44,11 +44,4 @@ <bool name="config_carrier_volte_vt_available">false</bool> <bool name="config_auto_attach_data_on_creation">false</bool> - - <!-- Values for GPS configuration (Verizon) --> - <string-array translatable="false" name="config_gpsParameters"> - <item>CAPABILITIES=0x31</item> - <item>GPS_LOCK=3</item> - <item>LPP_PROFILE=3</item> - </string-array> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index cf4064f..a00ed5d 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4483,12 +4483,12 @@ <!-- The row boundary delimiting the top of the group of cells occupied by this view. --> <attr name="layout_row" format="integer" /> - <!-- The row span: the difference between the bottom and top + <!-- The row span: the difference between the top and bottom boundaries delimiting the group of cells occupied by this view. The default is one. See {@link android.widget.GridLayout.Spec}. --> <attr name="layout_rowSpan" format="integer" min="1" /> - <!-- The relative proportion of horizontal space that should be allocated to this view + <!-- The relative proportion of vertical space that should be allocated to this view during excess space distribution. --> <attr name="layout_rowWeight" format="float" /> <!-- The column boundary delimiting the left of the group of cells @@ -4499,7 +4499,7 @@ The default is one. See {@link android.widget.GridLayout.Spec}. --> <attr name="layout_columnSpan" format="integer" min="1" /> - <!-- The relative proportion of vertical space that should be allocated to this view + <!-- The relative proportion of horizontal space that should be allocated to this view during excess space distribution. --> <attr name="layout_columnWeight" format="float" /> <!-- Gravity specifies how a component should be placed in its group of cells. diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index f3b3077..b36387f 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -351,6 +351,9 @@ point on the move. A value of 0 means no periodic scans will be used in the framework. --> <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer> + <!-- Integer indicating associated scan interval in milliseconds --> + <integer translatable="false" name="config_wifi_framework_associated_scan_interval">10000</integer> + <!-- Wifi driver stop delay, in milliseconds. Default value is 2 minutes. --> <integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer> @@ -1611,6 +1614,10 @@ <!-- default window ShowCircularMask property --> <bool name="config_windowShowCircularMask">false</bool> + <!-- default value for whether circular emulators (ro.emulator.circular) + should show a display overlay on the screen --> + <bool name="config_windowEnableCircularEmulatorDisplayOverlay">false</bool> + <!-- Defines the default set of global actions. Actions may still be disabled or hidden based on the current state of the device. Each item must be one of the following strings: @@ -1715,16 +1722,22 @@ <string-array translatable="false" name="config_gpsParameters"> <item>SUPL_HOST=supl.google.com</item> <item>SUPL_PORT=7275</item> - <item>XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra2.bin</item> - <item>XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin</item> - <item>XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin</item> <item>NTP_SERVER=north-america.pool.ntp.org</item> <item>SUPL_VER=0x20000</item> - <item>CAPABILITIES=0x33</item> - <item>LPP_PROFILE=0</item> - <item>NMEA_PROVIDER=0</item> - <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> - <item>ERR_ESTIMATE=0</item> - <item>INTERMEDIATE_POS=0</item> </string-array> + + <!-- If there is no preload VM number in the sim card, carriers such as + Verizon require to load a default vm number from the configurantion. + Define config_default_vm_number for this purpose. And there are two + optional formats for this configuration as below: + (1)<item>voicemail number</item> + (2)<item>voicemail number;gid</item> + The logic to pick up the correct voicemail number: + (1) If the config_default_vm_number array has no gid special item, the last one will be + picked + (2) If the config_default_vm_number array has gid special item and it matches the current + sim's gid, it will be picked. + (3) If the config_default_vm_number array has gid special item but it doesn't match the + current sim's gid, the last one without gid will be picked --> + <string-array translatable="false" name="config_default_vm_number" /> </resources> diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml index 5f7f0ed..275a5ec 100644 --- a/core/res/res/values/dimens_material.xml +++ b/core/res/res/values/dimens_material.xml @@ -77,5 +77,6 @@ <!-- Default rounded corner for controls --> <dimen name="control_corner_material">2dp</dimen> - <dimen name="alert_dialog_padding_material">18dp</dimen> + <dimen name="alert_dialog_padding_material">24dp</dimen> + <dimen name="alert_dialog_padding_top_material">18dp</dimen> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f1ec5d2..50da1fa 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3443,6 +3443,9 @@ <string name="whichHomeApplication">Select a home app</string> <!-- Option to always use the selected application resolution in the future. See the "Complete action using" dialog title--> <string name="alwaysUse">Use by default for this action.</string> + <!-- Title of the list of alternate options to complete an action shown when the + last used option is being displayed separately. --> + <string name="use_a_different_app">Use a different app</string> <!-- Text displayed when the user selects the check box for setting default application. See the "Use by default for this action" check box. --> <string name="clearDefaultHintMsg">Clear default in System settings > Apps > Downloaded.</string> <!-- Default title for the activity chooser, when one is not given. Android allows multiple activities to perform an action. for example, there may be many ringtone pickers installed. A dialog is shown to the user allowing him to pick which activity should be used. This is the title. --> @@ -4874,4 +4877,19 @@ <!-- [CHAR_LIMIT=NONE] Zen mode: Condition summary for built-in downtime condition, if active --> <string name="downtime_condition_summary">Until your downtime ends at <xliff:g id="formattedTime" example="10.00 PM">%1$s</xliff:g></string> + + <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] --> + <plurals name="zen_mode_duration_minutes"> + <item quantity="one">For one minute</item> + <item quantity="other">For %d minutes</item> + </plurals> + + <!-- Zen mode condition: time duration in hours. [CHAR LIMIT=NONE] --> + <plurals name="zen_mode_duration_hours"> + <item quantity="one">For one hour</item> + <item quantity="other">For %d hours</item> + </plurals> + + <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] --> + <string name="zen_mode_forever">Indefinitely</string> </resources> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index a7335af..26c7d10 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -474,6 +474,13 @@ please see styles_device_defaults.xml. <item name="stateListAnimator">@anim/disabled_anim_material</item> </style> + <!-- Alert dialog button bar button --> + <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored"> + <item name="minWidth">64dp</item> + <item name="maxLines">2</item> + <item name="minHeight">@dimen/alert_dialog_button_bar_height</item> + </style> + <!-- Small borderless ink button --> <style name="Widget.Material.Button.Borderless.Small"> <item name="minHeight">48dip</item> @@ -496,7 +503,6 @@ please see styles_device_defaults.xml. <style name="Widget.Material.ButtonBar.AlertDialog"> <item name="background">@null</item> - <item name="minHeight">@dimen/alert_dialog_button_bar_height</item> </style> <style name="Widget.Material.SearchView"> @@ -936,6 +942,7 @@ please see styles_device_defaults.xml. <style name="Widget.Material.Light.Button.Small" parent="Widget.Material.Button.Small"/> <style name="Widget.Material.Light.Button.Borderless" parent="Widget.Material.Button.Borderless"/> <style name="Widget.Material.Light.Button.Borderless.Colored" parent="Widget.Material.Button.Borderless.Colored"/> + <style name="Widget.Material.Light.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.ButtonBar.AlertDialog" /> <style name="Widget.Material.Light.Button.Borderless.Small" parent="Widget.Material.Button.Borderless.Small"/> <style name="Widget.Material.Light.Button.Inset" parent="Widget.Material.Button.Inset"/> <style name="Widget.Material.Light.Button.Toggle" parent="Widget.Material.Button.Toggle" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 01e6e76..556c07f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -293,6 +293,7 @@ <java-symbol type="bool" name="config_windowIsRound" /> <java-symbol type="bool" name="config_hasRecents" /> <java-symbol type="bool" name="config_windowShowCircularMask" /> + <java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" /> <java-symbol type="integer" name="config_bluetooth_max_advertisers" /> <java-symbol type="integer" name="config_bluetooth_max_scan_filters" /> @@ -312,6 +313,7 @@ <java-symbol type="integer" name="config_shortPressOnPowerBehavior" /> <java-symbol type="integer" name="config_toastDefaultGravity" /> <java-symbol type="integer" name="config_wifi_framework_scan_interval" /> + <java-symbol type="integer" name="config_wifi_framework_associated_scan_interval" /> <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" /> <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" /> <java-symbol type="integer" name="db_connection_pool_size" /> @@ -1155,6 +1157,7 @@ <java-symbol type="drawable" name="ic_corp_badge" /> <java-symbol type="drawable" name="ic_corp_icon_badge" /> <java-symbol type="drawable" name="ic_corp_icon" /> + <java-symbol type="drawable" name="emulator_circular_window_overlay" /> <java-symbol type="drawable" name="sim_light_blue" /> <java-symbol type="drawable" name="sim_light_green" /> @@ -1915,6 +1918,9 @@ <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" /> <java-symbol type="string" name="battery_saver_description" /> <java-symbol type="string" name="downtime_condition_summary" /> + <java-symbol type="string" name="zen_mode_forever" /> + <java-symbol type="plurals" name="zen_mode_duration_minutes" /> + <java-symbol type="plurals" name="zen_mode_duration_hours" /> <java-symbol type="string" name="item_is_selected" /> <java-symbol type="string" name="day_of_week_label_typeface" /> @@ -2004,4 +2010,6 @@ <java-symbol type="bool" name="config_auto_attach_data_on_creation" /> <java-symbol type="id" name="date_picker_month_day_year_layout" /> <java-symbol type="attr" name="closeItemLayout" /> + <java-symbol type="layout" name="resolver_different_item_header" /> + <java-symbol type="array" name="config_default_vm_number" /> </resources> diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml index ab5cd5a..4aca02e 100644 --- a/core/res/res/values/themes_material.xml +++ b/core/res/res/values/themes_material.xml @@ -333,7 +333,7 @@ please see themes_device_defaults.xml. <item name="dividerVertical">?attr/listDivider</item> <item name="dividerHorizontal">?attr/listDivider</item> <item name="buttonBarStyle">@style/Widget.Material.ButtonBar</item> - <item name="buttonBarButtonStyle">@style/Widget.Material.Button.Borderless.Colored</item> + <item name="buttonBarButtonStyle">@style/Widget.Material.Button.ButtonBar.AlertDialog</item> <item name="segmentedButtonStyle">@style/Widget.Material.SegmentedButton</item> <!-- SearchView attributes --> @@ -679,7 +679,7 @@ please see themes_device_defaults.xml. <item name="dividerVertical">?attr/listDivider</item> <item name="dividerHorizontal">?attr/listDivider</item> <item name="buttonBarStyle">@style/Widget.Material.Light.ButtonBar</item> - <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.Borderless.Colored</item> + <item name="buttonBarButtonStyle">@style/Widget.Material.Light.Button.ButtonBar.AlertDialog</item> <item name="segmentedButtonStyle">@style/Widget.Material.Light.SegmentedButton</item> <!-- SearchView attributes --> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java index 77e1c53..80d5668 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java @@ -322,8 +322,13 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { * If the device is already associated with a WiFi, disconnect and forget it, * We don't verify whether the connection is successful or not, leave this to the test */ - protected boolean connectToWifi(String knownSSID) { - WifiConfiguration config = WifiConfigurationHelper.createOpenConfig(knownSSID); + protected boolean connectToWifi(String ssid, String password) { + WifiConfiguration config; + if (password == null) { + config = WifiConfigurationHelper.createOpenConfig(ssid); + } else { + config = WifiConfigurationHelper.createPskConfig(ssid, password); + } return connectToWifiWithConfiguration(config); } diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java index b94306a..b6eb674 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java @@ -35,8 +35,9 @@ import junit.framework.TestSuite; */ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner { - public boolean mWifiOnlyFlag = false; - public String mTestSsid = null; + public boolean mWifiOnly = false; + public String mSsid = null; + public String mPassword = null; @Override public TestSuite getAllTests() { @@ -54,13 +55,29 @@ public class ConnectivityManagerTestRunner extends InstrumentationTestRunner { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - String testSSID = (String) icicle.get("ssid"); - if (testSSID != null) { - mTestSsid = testSSID; + String ssid = icicle.getString("ssid"); + if (ssid != null) { + mSsid = ssid; + } + String password = (String) icicle.get("password"); + if (password != null) { + mPassword = password; } String wifiOnlyFlag = (String) icicle.get("wifi-only"); if (wifiOnlyFlag != null) { - mWifiOnlyFlag = true; + mWifiOnly = true; } } + + public String getWifiSsid() { + return mSsid; + } + + public String getWifiPassword() { + return mPassword; + } + + public boolean isWifiOnly() { + return mWifiOnly; + } } diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java index b280106..d5051df 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java @@ -33,7 +33,8 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase super(ConnectivityManagerMobileTest.class.getSimpleName()); } - private String mTestAccessPoint; + private String mSsid; + private String mPassword; private boolean mWifiOnlyFlag; @Override @@ -41,8 +42,9 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase super.setUp(); ConnectivityManagerTestRunner mRunner = (ConnectivityManagerTestRunner)getInstrumentation(); - mTestAccessPoint = mRunner.mTestSsid; - mWifiOnlyFlag = mRunner.mWifiOnlyFlag; + mSsid = mRunner.getWifiSsid(); + mPassword = mRunner.getWifiPassword(); + mWifiOnlyFlag = mRunner.isWifiOnly(); // Each test case will start with cellular connection if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(), @@ -120,11 +122,10 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase // Test case 2: test connection to a given AP @LargeTest public void testConnectToWifi() { - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // assert that we are able to connect to the ap - assertTrue("failed to connect to " + mTestAccessPoint, - connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); // assert that WifiManager reports correct state assertTrue("wifi not enabled", waitForWifiState( WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT)); @@ -144,14 +145,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase // Test case 3: connect & reconnect to Wifi with known AP @LargeTest public void testConnectToWifWithKnownAP() { - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // enable WiFi assertTrue("failed to enable wifi", enableWifi()); // wait for wifi enable assertTrue("wifi not enabled", waitForWifiState( WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT)); // Connect to AP - assertTrue("failed to connect to " + mTestAccessPoint, connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); // verify wifi connected as reported by ConnectivityManager assertTrue("wifi not connected", waitForNetworkState( ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); @@ -191,7 +192,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase // Test case 4: test disconnect and clear wifi settings @LargeTest public void testDisconnectWifi() { - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // enable WiFi assertTrue("failed to enable wifi", enableWifi()); @@ -199,8 +200,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase assertTrue("wifi not enabled", waitForWifiState( WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT)); // connect to Wifi - assertTrue("failed to connect to " + mTestAccessPoint, - connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); assertTrue("wifi not connected", waitForNetworkState( ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); @@ -257,7 +257,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase // Test case 6: test connectivity with airplane mode on but wifi enabled @LargeTest public void testDataConnectionOverAMWithWifi() { - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // enable airplane mode mCm.setAirplaneMode(true); // assert there is active network connection after airplane mode disabled @@ -265,8 +265,7 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase waitUntilNoActiveNetworkConnection(LONG_TIMEOUT)); // connect to Wifi - assertTrue("failed to connect to " + mTestAccessPoint, - connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); assertTrue("wifi not connected", waitForNetworkState( ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); // verify that connection actually works @@ -280,15 +279,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase @LargeTest public void testDataConnectionWithWifiToAMToWifi () { // connect to mTestAccessPoint - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // enable WiFi assertTrue("failed to enable wifi", enableWifi()); // wait for wifi enable assertTrue("wifi not enabled", waitForWifiState( WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT)); // connect to Wifi - assertTrue("failed to connect to " + mTestAccessPoint, - connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); assertTrue("wifi not connected", waitForNetworkState( ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); @@ -313,15 +311,14 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase // Test case 8: test wifi state change while connecting/disconnecting to/from an AP @LargeTest public void testWifiStateChange () { - assertNotNull("SSID is null", mTestAccessPoint); + assertNotNull("SSID is null", mSsid); // enable WiFi assertTrue("failed to enable wifi", enableWifi()); // wait for wifi enable assertTrue("wifi not enabled", waitForWifiState( WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT)); // connect to Wifi - assertTrue("failed to connect to " + mTestAccessPoint, - connectToWifi(mTestAccessPoint)); + assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword)); assertTrue("wifi not connected", waitForNetworkState( ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); assertNotNull("not associated with any AP", mWifiManager.getConnectionInfo().getBSSID()); diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java index bcf2e45..db547e2 100644 --- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java +++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java @@ -60,10 +60,10 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { super.setUp(); DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation(); externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue); - assertNotNull(externalDownloadUriValue); + assertNotNull("download url is null", externalDownloadUriValue); externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue); - assertNotNull(externalLargeDownloadUriValue); + assertNotNull("large download url is null", externalLargeDownloadUriValue); } /** @@ -140,7 +140,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { dlRequest = mDownloadManager.enqueue(request); waitForDownloadToStart(dlRequest); - assertTrue(dlRequest != -1); + assertTrue("request id is -1 from download manager", dlRequest != -1); // Store ID of download for later retrieval outputFile = new DataOutputStream(fileOutput); @@ -183,7 +183,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { mContext.deleteFile(DOWNLOAD_STARTED_FLAG); } - assertTrue(dlRequest != -1); + assertTrue("request id is -1 from download manager", dlRequest != -1); Cursor cursor = getCursor(dlRequest); ParcelFileDescriptor pfd = null; try { @@ -193,7 +193,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { int status = cursor.getInt(columnIndex); int currentWaitTime = 0; - assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000)); + assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000)); Log.i(LOG_TAG, "Verifying download information..."); // Verify specific info about the file (size, name, etc)... @@ -233,7 +233,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { dlRequest = mDownloadManager.enqueue(request); // Rather large file, so wait up to 15 mins... - assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000)); + assertTrue("download not finished", waitForDownload(dlRequest, 15 * 60 * 1000)); Cursor cursor = getCursor(dlRequest); ParcelFileDescriptor pfd = null; @@ -317,7 +317,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { Log.i(LOG_TAG, "Turning on WiFi..."); setWiFiStateOn(true); Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete..."); - assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000)); + assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000)); ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); verifyFileSize(pfd, filesize); } finally { @@ -385,7 +385,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { setWiFiStateOn(true); Log.i(LOG_TAG, "Waiting up to 10 minutes for download to complete..."); - assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000)); + assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000)); ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); verifyFileSize(pfd, filesize); } finally { @@ -456,7 +456,7 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { setAirplaneModeOn(false); Log.i(LOG_TAG, "Waiting up to 10 minutes for donwload to complete..."); - assertTrue(waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins + assertTrue("download not finished", waitForDownload(dlRequest, 10 * 60 * 1000)); // wait up to 10 mins ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest); verifyFileSize(pfd, filesize); } finally { @@ -489,11 +489,11 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest { Request request = new Request(remoteUri); request.setTitle(filename); dlRequest = mDownloadManager.enqueue(request); - assertTrue(dlRequest != -1); + assertTrue("request id is -1 from download manager", dlRequest != -1); downloadIds.add(dlRequest); } - assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max + assertTrue("download not finished", waitForMultipleDownloads(downloadIds, 15 * 60 * 2000)); // wait 15 mins max } finally { removeAllCurrentDownloads(); } diff --git a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java index b6a03d9..d4244ba 100644 --- a/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java +++ b/core/tests/inputmethodtests/src/android/os/CursorAnchorInfoTest.java @@ -116,16 +116,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase { assertEquals(TRANSFORM_MATRIX, info.getMatrix()); for (int i = 0; i < MANY_BOUNDS.length; i++) { final RectF expectedBounds = MANY_BOUNDS[i]; - assertEquals(expectedBounds, info.getCharacterRect(i)); + assertEquals(expectedBounds, info.getCharacterBounds(i)); } - assertNull(info.getCharacterRect(-1)); - assertNull(info.getCharacterRect(MANY_BOUNDS.length + 1)); + assertNull(info.getCharacterBounds(-1)); + assertNull(info.getCharacterBounds(MANY_BOUNDS.length + 1)); for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { final int expectedFlags = MANY_FLAGS_ARRAY[i]; - assertEquals(expectedFlags, info.getCharacterRectFlags(i)); + assertEquals(expectedFlags, info.getCharacterBoundsFlags(i)); } - assertEquals(0, info.getCharacterRectFlags(-1)); - assertEquals(0, info.getCharacterRectFlags(MANY_BOUNDS.length + 1)); + assertEquals(0, info.getCharacterBoundsFlags(-1)); + assertEquals(0, info.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); // Make sure that the builder can reproduce the same object. final CursorAnchorInfo info2 = builder.build(); @@ -141,16 +141,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase { assertEquals(TRANSFORM_MATRIX, info2.getMatrix()); for (int i = 0; i < MANY_BOUNDS.length; i++) { final RectF expectedBounds = MANY_BOUNDS[i]; - assertEquals(expectedBounds, info2.getCharacterRect(i)); + assertEquals(expectedBounds, info2.getCharacterBounds(i)); } - assertNull(info2.getCharacterRect(-1)); - assertNull(info2.getCharacterRect(MANY_BOUNDS.length + 1)); + assertNull(info2.getCharacterBounds(-1)); + assertNull(info2.getCharacterBounds(MANY_BOUNDS.length + 1)); for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { final int expectedFlags = MANY_FLAGS_ARRAY[i]; - assertEquals(expectedFlags, info2.getCharacterRectFlags(i)); + assertEquals(expectedFlags, info2.getCharacterBoundsFlags(i)); } - assertEquals(0, info2.getCharacterRectFlags(-1)); - assertEquals(0, info2.getCharacterRectFlags(MANY_BOUNDS.length + 1)); + assertEquals(0, info2.getCharacterBoundsFlags(-1)); + assertEquals(0, info2.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); assertEquals(info, info2); assertEquals(info.hashCode(), info2.hashCode()); @@ -168,16 +168,16 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase { assertEquals(TRANSFORM_MATRIX, info3.getMatrix()); for (int i = 0; i < MANY_BOUNDS.length; i++) { final RectF expectedBounds = MANY_BOUNDS[i]; - assertEquals(expectedBounds, info3.getCharacterRect(i)); + assertEquals(expectedBounds, info3.getCharacterBounds(i)); } - assertNull(info3.getCharacterRect(-1)); - assertNull(info3.getCharacterRect(MANY_BOUNDS.length + 1)); + assertNull(info3.getCharacterBounds(-1)); + assertNull(info3.getCharacterBounds(MANY_BOUNDS.length + 1)); for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) { final int expectedFlags = MANY_FLAGS_ARRAY[i]; - assertEquals(expectedFlags, info3.getCharacterRectFlags(i)); + assertEquals(expectedFlags, info3.getCharacterBoundsFlags(i)); } - assertEquals(0, info3.getCharacterRectFlags(-1)); - assertEquals(0, info3.getCharacterRectFlags(MANY_BOUNDS.length + 1)); + assertEquals(0, info3.getCharacterBoundsFlags(-1)); + assertEquals(0, info3.getCharacterBoundsFlags(MANY_BOUNDS.length + 1)); assertEquals(info.hashCode(), info3.hashCode()); builder.reset(); diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java index fa1bd8f..5958c3a 100644 --- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java +++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java @@ -26,6 +26,7 @@ import android.test.InstrumentationTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; +import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; import java.util.ArrayList; import java.util.List; @@ -159,8 +160,15 @@ public class InputMethodTest extends InstrumentationTestCase { private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode, boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) { - return new InputMethodSubtype(0, 0, locale, mode, "", isAuxiliary, - overridesImplicitlyEnabledSubtype); + return new InputMethodSubtypeBuilder() + .setSubtypeNameResId(0) + .setSubtypeIconResId(0) + .setSubtypeLocale(locale) + .setSubtypeMode(mode) + .setSubtypeExtraValue("") + .setIsAuxiliary(isAuxiliary) + .setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype) + .build(); } private static InputMethodInfo createDefaultAutoDummyVoiceIme() { diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index cfc1484..f10ba96 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -405,6 +405,7 @@ key 484 B FUNCTION # key 504 KEY_BRL_DOT8 key 580 APP_SWITCH +key 582 VOICE_ASSIST # Keys defined by HID usages key usage 0x0c006F BRIGHTNESS_UP diff --git a/docs/html/about/dashboards/index.jd b/docs/html/about/dashboards/index.jd index 1e5fc4d..808f04a 100644 --- a/docs/html/about/dashboards/index.jd +++ b/docs/html/about/dashboards/index.jd @@ -64,7 +64,7 @@ Platform Versions</a>.</p> </div> -<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014. +<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014. <br/>Any versions with less than 0.1% distribution are not shown.</em> </p> @@ -95,7 +95,8 @@ Screens</a>.</p> </div> -<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014. +<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014. + <br/>Any screen configurations with less than 0.1% distribution are not shown.</em></p> @@ -114,7 +115,7 @@ support for any lower version (for example, support for version 2.0 also implies <img alt="" style="float:right" -src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A0.1%2C80.2%2C19.7&chf=bg%2Cs%2C00000000&chl=GL%201.1%20only%7CGL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" /> +src="//chart.googleapis.com/chart?chs=400x250&cht=p&chd=t%3A77.5%2C22.5&chf=bg%2Cs%2C00000000&chl=GL%202.0%7CGL%203.0&chco=c4df9b%2C6fad0c" /> <p>To declare which version of OpenGL ES your application requires, you should use the {@code android:glEsVersion} attribute of the <a @@ -131,22 +132,18 @@ uses.</p> <th scope="col">Distribution</th> </tr> <tr> -<td>1.1 only</th> -<td>0.1%</td> -</tr> -<tr> -<td>2.0</th> -<td>80.2%</td> +<td>2.0</td> +<td>77.5%</td> </tr> <tr> -<td>3.0</th> -<td>19.7%</td> +<td>3.0</td> +<td>22.5%</td> </tr> </table> -<p style="clear:both"><em>Data collected during a 7-day period ending on August 12, 2014</em></p> +<p style="clear:both"><em>Data collected during a 7-day period ending on September 9, 2014</em></p> @@ -164,7 +161,7 @@ uses.</p> var VERSION_DATA = [ { - "chart": "//chart.googleapis.com/chart?cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.7%2C13.6%2C10.6%2C54.2%2C20.9&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c", + "chart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=500x250&chl=Froyo%7CGingerbread%7CIce%20Cream%20Sandwich%7CJelly%20Bean%7CKitKat&chd=t%3A0.7%2C11.4%2C9.6%2C53.8%2C24.5&chf=bg%2Cs%2C00000000", "data": [ { "api": 8, @@ -174,41 +171,38 @@ var VERSION_DATA = { "api": 10, "name": "Gingerbread", - "perc": "13.6" + "perc": "11.4" }, { "api": 15, "name": "Ice Cream Sandwich", - "perc": "10.6" + "perc": "9.6" }, { "api": 16, "name": "Jelly Bean", - "perc": "26.5" + "perc": "25.1" }, { "api": 17, "name": "Jelly Bean", - "perc": "19.8" + "perc": "20.7" }, { "api": 18, "name": "Jelly Bean", - "perc": "7.9" + "perc": "8.0" }, { "api": 19, "name": "KitKat", - "perc": "20.9" + "perc": "24.5" } ] } ]; - - - var SCREEN_DATA = [ { @@ -216,27 +210,27 @@ var SCREEN_DATA = "Large": { "hdpi": "0.6", "ldpi": "0.5", - "mdpi": "4.2", - "tvdpi": "1.6", - "xhdpi": "0.5" + "mdpi": "4.3", + "tvdpi": "1.7", + "xhdpi": "0.6" }, "Normal": { - "hdpi": "35.5", - "mdpi": "11.8", - "xhdpi": "18.4", - "xxhdpi": "15.2" + "hdpi": "35.7", + "mdpi": "10.6", + "xhdpi": "19.2", + "xxhdpi": "16.2" }, "Small": { - "ldpi": "7.4" + "ldpi": "6.2" }, "Xlarge": { "hdpi": "0.3", - "mdpi": "3.6", + "mdpi": "3.7", "xhdpi": "0.4" } }, - "densitychart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A7.9%2C19.6%2C1.6%2C36.4%2C19.3%2C15.2&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c", - "layoutchart": "//chart.googleapis.com/chart?cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.3%2C7.4%2C80.9%2C7.4&chf=bg%2Cs%2C00000000&chco=c4df9b%2C6fad0c" + "densitychart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=ldpi%7Cmdpi%7Ctvdpi%7Chdpi%7Cxhdpi%7Cxxhdpi&chd=t%3A6.7%2C18.6%2C1.7%2C36.6%2C20.2%2C16.2&chf=bg%2Cs%2C00000000", + "layoutchart": "//chart.googleapis.com/chart?chco=c4df9b%2C6fad0c&cht=p&chs=400x250&chl=Xlarge%7CLarge%7CNormal%7CSmall&chd=t%3A4.4%2C7.7%2C81.7%2C6.2&chf=bg%2Cs%2C00000000" } ]; diff --git a/docs/html/google/play/billing/api.jd b/docs/html/google/play/billing/api.jd index 3d46715..bc710f9 100644 --- a/docs/html/google/play/billing/api.jd +++ b/docs/html/google/play/billing/api.jd @@ -1,6 +1,7 @@ -page.title=In-app Billing Version 3 +page.title=In-app Billing API parent.title=In-app Billing parent.link=index.html +page.tags="billing, inapp, iap" @jd:body <div id="qv-wrapper"> diff --git a/docs/html/google/play/billing/billing_integrate.jd b/docs/html/google/play/billing/billing_integrate.jd index dba43cd..052cf75 100644 --- a/docs/html/google/play/billing/billing_integrate.jd +++ b/docs/html/google/play/billing/billing_integrate.jd @@ -1,6 +1,7 @@ -page.title=Implementing In-app Billing <span style="font-size:16px;">(IAB Version 3)</span> +page.title=Implementing In-app Billing parent.title=In-app Billing parent.link=index.html +page.tags="inapp, billing, iap" @jd:body <div id="qv-wrapper"> @@ -141,15 +142,17 @@ ServiceConnection mServiceConn = new ServiceConnection() { }; </pre> -<p>In your activity’s {@link android.app.Activity#onCreate onCreate} method, perform the binding by calling the {@link android.content.Context#bindService bindService} method. Pass the method an {@link android.content.Intent} that references the In-app Billing service and an instance of the {@link android.content.ServiceConnection} that you created.</p> -<pre> -@Override -public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - bindService(new - Intent("com.android.vending.billing.InAppBillingService.BIND"), - mServiceConn, Context.BIND_AUTO_CREATE); +<p>In your activity’s {@link android.app.Activity#onCreate onCreate} method, perform the binding by calling the {@link android.content.Context#bindService bindService} method. Pass the method an {@link android.content.Intent} that references the In-app Billing service and an instance of the {@link android.content.ServiceConnection} that you created, and explicitly set the Intent's target package name to <code>com.android.vending</code> — the package name of Google Play app.</p> + +<p class="caution"><strong>Caution:</strong> To protect the security of billing transactions, always make sure to explicitly set the intent's target package name to <code>com.android.vending</code>, using {@link android.content.Intent#setPackage(java.lang.String) setPackage()} as shown in the example below. Setting the package name explicitly ensures that <em>only</em> the Google Play app can handle billing requests from your app, preventing other apps from intercepting those requests.</p> + +<pre>@Override +public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); + serviceIntent.setPackage("com.android.vending"); + bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); </pre> <p>You can now use the mService reference to communicate with the Google Play service.</p> <p class="note"><strong>Important:</strong> Remember to unbind from the In-app Billing service when you are done with your {@link android.app.Activity}. If you don’t unbind, the open service connection could cause your device’s performance to degrade. This example shows how to perform the unbind operation on a service connection to In-app Billing called {@code mServiceConn} by overriding the activity’s {@link android.app.Activity#onDestroy onDestroy} method.</p> @@ -269,7 +272,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } } </pre> -<p class="note"><strong>Security Recommendation:</strong> When you send a purchase request, create a String token that uniquely identifies this purchase request and include this token in the {@code developerPayload}.You can use a randomly generated string as the token. When you receive the purchase response from Google Play, make sure to check the returned data signature, the {@code orderId}, and the {@code developerPayload} String. For added security, you should perform the checking on your own secure server. Make sure to verify that the {@code orderId} is a unique value that you have not previously processed, and the {@code developerPayload} String matches the token that you sent previously with the purchase request.</p> +<p class="note"><strong>Security Recommendation:</strong> When you send a purchase request, create a String token that uniquely identifies this purchase request and include this token in the {@code developerPayload}.You can use a randomly generated string as the token. When you receive the purchase response from Google Play, make sure to check the returned data signature, the {@code orderId}, and the {@code developerPayload} String. For added security, you should perform the checking on your own secure server. Make sure to verify that the {@code orderId} is a unique value that you have not previously processed, and the {@code developerPayload} String matches the token that you sent previously with the purchase request.</p> <h3 id="QueryPurchases">Querying for Purchased Items</h3> <p>To retrieve information about purchases made by a user from your app, call the {@code getPurchases} method on the In-app Billing Version 3 service. Pass in to the method the In-app Billing API version (“3”), the package name of your calling app, and the purchase type (“inapp” or "subs").</p> diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd index 4f5e65c..4d80964 100644 --- a/docs/html/google/play/billing/billing_reference.jd +++ b/docs/html/google/play/billing/billing_reference.jd @@ -1,4 +1,4 @@ -page.title=In-app Billing Reference <span style="font-size:16px;">(IAB Version 3)</span> +page.title=In-app Billing Reference parent.title=In-app Billing parent.link=index.html @jd:body diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd index 3c72da1..2b78ab3 100644 --- a/docs/html/google/play/billing/billing_subscriptions.jd +++ b/docs/html/google/play/billing/billing_subscriptions.jd @@ -1,9 +1,9 @@ -page.title=Google Play In-App Subscriptions +page.title=In-App Subscriptions parent.title=In-app Billing parent.link=index.html page.metaDescription=Subscriptions let you sell content or features in your app with automated, recurring billing. page.image=/images/play_dev.jpg -page.tags="inapp, iap, billing" +page.tags="subscriptions, billing, inapp, iap" meta.tags="monetization, inappbilling, subscriptions" @jd:body diff --git a/docs/html/google/play/billing/billing_testing.jd b/docs/html/google/play/billing/billing_testing.jd index 8a49433..10f5326 100644 --- a/docs/html/google/play/billing/billing_testing.jd +++ b/docs/html/google/play/billing/billing_testing.jd @@ -1,6 +1,7 @@ page.title=Testing In-app Billing parent.title=In-app Billing parent.link=index.html +page.tags="inapp, billing, iap" @jd:body <div id="qv-wrapper"> diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd index 18b1523..875271f 100644 --- a/docs/html/google/play/billing/index.jd +++ b/docs/html/google/play/billing/index.jd @@ -2,7 +2,7 @@ page.title=Google Play In-app Billing page.metaDescription=In-app Billing lets you sell digital content as one-time purchases or subscriptions. page.image=/images/play_dev.jpg meta.tags="monetizing, inappbilling, subscriptions" -page.tags="inapp, iap, subscriptions" +page.tags="billing, inapp, iap" @jd:body <p>In-app Billing is a Google Play service that lets you sell digital content from inside diff --git a/docs/html/google/play/billing/versions.jd b/docs/html/google/play/billing/versions.jd index 1271a15..dbe3ea3 100644 --- a/docs/html/google/play/billing/versions.jd +++ b/docs/html/google/play/billing/versions.jd @@ -1,3 +1,4 @@ +excludeFromSuggestions=true page.title=In-app Billing Version Notes @jd:body diff --git a/docs/html/reference/renderscript/rs__matrix_8rsh.html b/docs/html/reference/renderscript/rs__matrix_8rsh.html index 69cc373..3b8e047 100644 --- a/docs/html/reference/renderscript/rs__matrix_8rsh.html +++ b/docs/html/reference/renderscript/rs__matrix_8rsh.html @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> -<title>/usr/local/google/home/srhines/android_trees/jb-mr2-dev/frameworks/rs/scriptc/rs_matrix.rsh File Reference</title> +<title>frameworks/rs/scriptc/rs_matrix.rsh File Reference</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css" /> @@ -27,18 +27,18 @@ <div class="summary"> <a href="#func-members">Functions</a> </div> <div class="headertitle"> -<div class="title">/usr/local/google/home/srhines/android_trees/jb-mr2-dev/frameworks/rs/scriptc/rs_matrix.rsh File Reference</div> </div> +<div class="title">frameworks/rs/scriptc/rs_matrix.rsh File Reference</div> </div> </div> <div class="contents"> <table class="memberdecls"> <tr><td colspan="2"><h2><a name="func-members"></a> Functions</h2></td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ad6ea242218e0f1a031f754df0317e6e7">rsMatrixSet</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, float v)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ab69543f85a673f23fbb5f893e5824395">rsMatrixSet</a> (<a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, float v)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a0a85c8d3607f1b75019f6991c5b19fca">rsMatrixSet</a> (<a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, float v)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a22e983b67d3089c5cb97032e249ca335">rsMatrixGet</a> (const <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ad485084684991796cffdd8a008557569">rsMatrixGet</a> (const <a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top">float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#aaa86b029d5c5c15fead5338bba02e4c3">rsMatrixGet</a> (const <a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#aca88832ed720e301780152c60884393e">rsMatrixSet</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, float v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a08a247cdf2e70e78310bf04f9ecd5144">rsMatrixSet</a> (<a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, float v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#af9707d7be5945bf55ed53683624176ff">rsMatrixSet</a> (<a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, float v)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#af26fdbf8b8f0ed5d1b53f62b2aef5110">rsMatrixGet</a> (const <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#acfebfc7b97e7282b78cd9c65b791932a">rsMatrixGet</a> (const <a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME float </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a683b4537b98103c50cc66780dfe8cd69">rsMatrixGet</a> (const <a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a5b31e83553efa947db2198674d5db043">rsMatrixLoadIdentity</a> (<a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ad2954a5ac11d2370227296be89e92471">rsMatrixLoadIdentity</a> (<a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m)</td></tr> @@ -65,9 +65,9 @@ Functions</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a4c59884a0e534dbbcdc5655842732d43">rsMatrixLoadOrtho</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, float left, float right, float bottom, float top, float near, float far)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ad25760aaf01e95d0055237afab41bbb3">rsMatrixLoadFrustum</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, float left, float right, float bottom, float top, float near, float far)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#aa404c34d7478f2921f7415d2da95d02b">rsMatrixLoadPerspective</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, float fovy, float aspect, float near, float far)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a2f11c3d7cc34ddce90ba785b93af8da2">rsMatrixMultiply</a> (const <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a88ae2ed203769cb4a7917f84f6c1a2e2">rsMatrixMultiply</a> (const <a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in)</td></tr> -<tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a8d81a7143d5d45f60f7e91f955579bab">rsMatrixMultiply</a> (const <a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a47b6abbf32ffaf77bb13d96c3f05779f">rsMatrixMultiply</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m, <a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a716bc2d29b80eb25388aba3ba8845aef">rsMatrixMultiply</a> (<a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> *m, <a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in)</td></tr> +<tr><td class="memItemLeft" align="right" valign="top">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a> (<a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m, <a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a00b6a334ba5ac94d84850f22ec9f4de5">rsMatrixInverse</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#ac05080d52da2d99a759ef34fa0655e82">rsMatrixInverseTranspose</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m)</td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a> (<a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> *m)</td></tr> @@ -75,16 +75,30 @@ Functions</h2></td></tr> <tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="rs__matrix_8rsh.html#a49164dd4d4e85b212196028b1fd89dc1">rsMatrixTranspose</a> (<a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> *m)</td></tr> </table> <hr/><a name="details" id="details"></a><h2>Detailed Description</h2> -<div class="textblock"><p>Matrix routines. </p> +<div class="textblock"><p>Matrix functions. </p> +<p>These functions let you manipulate square matrices of rank 2x2, 3x3, and 4x4. They are particularly useful for graphical transformations and are compatible with OpenGL.</p> +<p>A few general notes:</p> +<ul> +<li>We use a zero-based index for rows and columns. E.g. the last element of a <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> is found at (3, 3).</li> +</ul> +<ul> +<li>RenderScript uses column-based vectors. Transforming a vector is done by postmultiplying the vector, e.g. <em>(matrix * vector)</em>, as provided by <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</li> +</ul> +<ul> +<li>To create a transformation matrix that performs two transformations at once, multiply the two source matrices, with the first transformation as the right argument. E.g. to create a transformation matrix that applies the transformation <em>s1</em> followed by <em>s2</em>, call rsMatrixLoadMultiply(&combined, &s2, &s1). This derives from <em>s2 * (s1 * v)</em>, which is <em>(s2 * s1) * v</em>.</li> +</ul> +<ul> +<li>We have two style of functions to create transformation matrices: rsMatrixLoad<em>Transformation</em> and rsMatrix<em>Transformation</em>. The former style simply stores the transformation matrix in the first argument. The latter modifies a pre-existing transformation matrix so that the new transformation happens first. E.g. if you call <a class="el" href="rs__matrix_8rsh.html#a4df5f9b5bb6044f3c3426f2f58b94405">rsMatrixTranslate</a> on a matrix that already does a scaling, the resulting matrix when applied to a vector will first do the translation then the scaling. </li> +</ul> <p>Definition in file <a class="el" href="rs__matrix_8rsh_source.html">rs_matrix.rsh</a>.</p> </div><hr/><h2>Function Documentation</h2> -<a class="anchor" id="a22e983b67d3089c5cb97032e249ca335"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="a22e983b67d3089c5cb97032e249ca335" args="(const rs_matrix4x4 *m, uint32_t row, uint32_t col)" --> +<a class="anchor" id="af26fdbf8b8f0ed5d1b53f62b2aef5110"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="af26fdbf8b8f0ed5d1b53f62b2aef5110" args="(const rs_matrix4x4 *m, uint32_t col, uint32_t row)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">float rsMatrixGet </td> + <td class="memname">_RS_RUNTIME float rsMatrixGet </td> <td>(</td> <td class="paramtype">const <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -93,13 +107,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em> </td> + <td class="paramname"><em>row</em> </td> </tr> <tr> <td></td> @@ -109,25 +123,26 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Get one element of a matrix.</p> +<p>Returns one element of a matrix.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td>The matrix to read from </td></tr> - <tr><td class="paramname">row</td><td></td></tr> - <tr><td class="paramname">col</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to extract the element from. </td></tr> + <tr><td class="paramname">col</td><td>The zero-based column of the element to be extracted. </td></tr> + <tr><td class="paramname">row</td><td>The zero-based row of the element to extracted.</td></tr> </table> </dd> </dl> +<dl class="warning"><dt><b>Warning:</b></dt><dd>The order of the column and row parameters may be unexpected.</dd></dl> <dl class="return"><dt><b>Returns:</b></dt><dd>float </dd></dl> </div> </div> -<a class="anchor" id="ad485084684991796cffdd8a008557569"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="ad485084684991796cffdd8a008557569" args="(const rs_matrix3x3 *m, uint32_t row, uint32_t col)" --> +<a class="anchor" id="acfebfc7b97e7282b78cd9c65b791932a"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="acfebfc7b97e7282b78cd9c65b791932a" args="(const rs_matrix3x3 *m, uint32_t col, uint32_t row)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">float rsMatrixGet </td> + <td class="memname">_RS_RUNTIME float rsMatrixGet </td> <td>(</td> <td class="paramtype">const <a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -136,13 +151,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em> </td> + <td class="paramname"><em>row</em> </td> </tr> <tr> <td></td> @@ -156,12 +171,12 @@ Functions</h2></td></tr> </div> </div> -<a class="anchor" id="aaa86b029d5c5c15fead5338bba02e4c3"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="aaa86b029d5c5c15fead5338bba02e4c3" args="(const rs_matrix2x2 *m, uint32_t row, uint32_t col)" --> +<a class="anchor" id="a683b4537b98103c50cc66780dfe8cd69"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixGet" ref="a683b4537b98103c50cc66780dfe8cd69" args="(const rs_matrix2x2 *m, uint32_t col, uint32_t row)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">float rsMatrixGet </td> + <td class="memname">_RS_RUNTIME float rsMatrixGet </td> <td>(</td> <td class="paramtype">const <a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -170,13 +185,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em> </td> + <td class="paramname"><em>row</em> </td> </tr> <tr> <td></td> @@ -204,10 +219,11 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Returns true if the matrix was successfully inversed</p> +<p>Inverts a matrix in place.</p> +<p>Returns true if the matrix was successfully inversed.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to invert. </td></tr> </table> </dd> </dl> @@ -228,10 +244,11 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Returns true if the matrix was successfully inversed and transposed.</p> +<p>Inverts and transpose a matrix in place.</p> +<p>The matrix is first inverted then transposed. Returns true if the matrix was successfully inverted.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to modify. </td></tr> </table> </dd> </dl> @@ -263,9 +280,11 @@ Functions</h2></td></tr> </div> <div class="memdoc"> <p>Set the elements of a matrix from an array of floats.</p> +<p>The array of floats should be in row-major order, i.e. the element a <em>row 0, column 0</em> should be first, followed by the element at <em>row 0, column 1</em>, etc.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">v</td><td>The array of values to set the matrix to. These arrays should be 4, 9, or 16 floats long, depending on the matrix size. </td></tr> </table> </dd> </dl> @@ -352,7 +371,20 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </p> +<p>Set the elements of a matrix from another matrix.</p> +<p>If the source matrix is smaller than the destination, the rest of the destination is filled with elements of the identity matrix. E.g. loading a <a class="el" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> into a <a class="el" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> will give:</p> + <table> + <tr><td>m00</td><td>m01</td><td>0.0</td><td>0.0</td></tr> + <tr><td>m10</td><td>m11</td><td>0.0</td><td>0.0</td></tr> + <tr><td>0.0</td><td>0.0</td><td>1.0</td><td>0.0</td></tr> + <tr><td>0.0</td><td>0.0</td><td>0.0</td><td>1.0</td></tr> + </table><dl><dt><b>Parameters:</b></dt><dd> + <table class="params"> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">v</td><td>The source matrix. </td></tr> + </table> + </dd> +</dl> </div> </div> @@ -408,13 +440,7 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Set the elements of a matrix from another matrix.</p> -<dl><dt><b>Parameters:</b></dt><dd> - <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - </table> - </dd> -</dl> +<p>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </p> </div> </div> @@ -528,10 +554,13 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Load an Frustum projection matrix constructed from the 6 planes</p> +<p>Load a frustum projection matrix.</p> +<p>Constructs a frustum projection matrix, transforming the box identified by the six clipping planes <em>left, right, bottom, top, near, far</em>.</p> +<p>To apply this projection to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> +<p>See <a href="https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf">https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf</a></p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> <tr><td class="paramname">left</td><td></td></tr> <tr><td class="paramname">right</td><td></td></tr> <tr><td class="paramname">bottom</td><td></td></tr> @@ -561,7 +590,7 @@ Functions</h2></td></tr> <p>Set the elements of a matrix to the identity matrix.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> </table> </dd> </dl> @@ -634,12 +663,15 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiply two matrix (lhs, rhs) and place the result in m.</p> +<p>Multiply two matrices.</p> +<p>Sets <em>m</em> to the matrix product of <em>lhs * rhs</em>.</p> +<p>To combine two 4x4 transformaton matrices, multiply the second transformation matrix by the first transformation matrix. E.g. to create a transformation matrix that applies the transformation <em>s1</em> followed by <em>s2</em>, call rsMatrixLoadMultiply(&combined, &s2, &s1).</p> +<dl class="warning"><dt><b>Warning:</b></dt><dd>As of version 21, storing the result back into right matrix is not supported and will result in undefined behavior. Use rsMatrixMulitply instead. E.g. instead of doing rsMatrixLoadMultiply (&m2r, &m2r, &m2l), use rsMatrixMultiply (&m2r, &m2l). rsMatrixLoadMultiply (&m2l, &m2r, &m2l) works as expected.</dd></dl> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">lhs</td><td></td></tr> - <tr><td class="paramname">rhs</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">lhs</td><td>The left matrix of the product. </td></tr> + <tr><td class="paramname">rhs</td><td>The right matrix of the product. </td></tr> </table> </dd> </dl> @@ -768,10 +800,13 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Load an Ortho projection matrix constructed from the 6 planes</p> +<p>Load an orthographic projection matrix.</p> +<p>Constructs an orthographic projection matrix, transforming the box identified by the six clipping planes <em>left, right, bottom, top, near, far</em> into a unit cube with a corner at <em>(-1, -1, -1)</em> and the opposite at <em>(1, 1, 1)</em>.</p> +<p>To apply this projection to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> +<p>See <a href="https://en.wikipedia.org/wiki/Orthographic_projection">https://en.wikipedia.org/wiki/Orthographic_projection</a> and <a href="https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf">https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf</a></p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> <tr><td class="paramname">left</td><td></td></tr> <tr><td class="paramname">right</td><td></td></tr> <tr><td class="paramname">bottom</td><td></td></tr> @@ -826,14 +861,17 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Load an perspective projection matrix constructed from the 6 planes</p> +<p>Load a perspective projection matrix.</p> +<p>Constructs a perspective projection matrix, assuming a symmetrical field of view.</p> +<p>To apply this projection to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> +<p>See <a href="https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf">https://www.opengl.org/documentation/specs/version2.0/glspec20.pdf</a></p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> <tr><td class="paramname">fovy</td><td>Field of view, in degrees along the Y axis. </td></tr> <tr><td class="paramname">aspect</td><td>Ratio of x / y. </td></tr> - <tr><td class="paramname">near</td><td></td></tr> - <tr><td class="paramname">far</td><td></td></tr> + <tr><td class="paramname">near</td><td>The near clipping plane. </td></tr> + <tr><td class="paramname">far</td><td>The far clipping plane. </td></tr> </table> </dd> </dl> @@ -883,13 +921,16 @@ Functions</h2></td></tr> </div> <div class="memdoc"> <p>Load a rotation matrix.</p> +<p>This function creates a rotation matrix. The axis of rotation is the <em>(x, y, z)</em> vector.</p> +<p>To rotate a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> +<p>See <a href="http://en.wikipedia.org/wiki/Rotation_matrix">http://en.wikipedia.org/wiki/Rotation_matrix</a> .</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">rot</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">rot</td><td>How much rotation to do, in degrees. </td></tr> + <tr><td class="paramname">x</td><td>The x component of the vector that is the axis of rotation. </td></tr> + <tr><td class="paramname">y</td><td>The y component of the vector that is the axis of rotation. </td></tr> + <tr><td class="paramname">z</td><td>The z component of the vector that is the axis of rotation. </td></tr> </table> </dd> </dl> @@ -933,12 +974,14 @@ Functions</h2></td></tr> </div> <div class="memdoc"> <p>Load a scale matrix.</p> +<p>This function creates a scaling matrix, where each component of a vector is multiplied by a number. This number can be negative.</p> +<p>To scale a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">x</td><td>The multiple to scale the x components by. </td></tr> + <tr><td class="paramname">y</td><td>The multiple to scale the y components by. </td></tr> + <tr><td class="paramname">z</td><td>The multiple to scale the z components by. </td></tr> </table> </dd> </dl> @@ -982,12 +1025,14 @@ Functions</h2></td></tr> </div> <div class="memdoc"> <p>Load a translation matrix.</p> +<p>This function creates a translation matrix, where a number is added to each element of a vector.</p> +<p>To translate a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to set. </td></tr> + <tr><td class="paramname">x</td><td>The number to add to each x component. </td></tr> + <tr><td class="paramname">y</td><td>The number to add to each y component. </td></tr> + <tr><td class="paramname">z</td><td>The number to add to each z component. </td></tr> </table> </dd> </dl> @@ -1018,11 +1063,13 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiply the matrix m by rhs and place the result back into m.</p> +<p>Multiply a matrix into another one.</p> +<p>Sets <em>m</em> to the matrix product <em>m * rhs</em>.</p> +<p>When combining two 4x4 transformation matrices using this function, the resulting matrix will correspond to performing the <em>rhs</em> transformation first followed by the original <em>m</em> transformation.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td>(lhs) </td></tr> - <tr><td class="paramname">rhs</td><td></td></tr> + <tr><td class="paramname">m</td><td>The left matrix of the product and the matrix to be set. </td></tr> + <tr><td class="paramname">rhs</td><td>The right matrix of the product. </td></tr> </table> </dd> </dl> @@ -1085,14 +1132,14 @@ Functions</h2></td></tr> </div> </div> -<a class="anchor" id="a2f11c3d7cc34ddce90ba785b93af8da2"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a2f11c3d7cc34ddce90ba785b93af8da2" args="(const rs_matrix4x4 *m, float4 in)" --> +<a class="anchor" id="a47b6abbf32ffaf77bb13d96c3f05779f"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a47b6abbf32ffaf77bb13d96c3f05779f" args="(rs_matrix4x4 *m, float4 in)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname"><a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> rsMatrixMultiply </td> + <td class="memname">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> rsMatrixMultiply </td> <td>(</td> - <td class="paramtype">const <a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> * </td> + <td class="paramtype"><a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> * </td> <td class="paramname"><em>m</em>, </td> </tr> <tr> @@ -1109,19 +1156,24 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiply a vector by a matrix and return the result vector. API version 14+</p> +<p>Multiply a vector by a matrix.</p> +<p>Returns the post-multiplication of the vector by the matrix, ie. <em>m * in</em>.</p> +<p>When multiplying a <em>float3</em> to a <em><a class="el" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a></em>, the vector is expanded with (1).</p> +<p>When multiplying a <em>float2</em> to a <em><a class="el" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a></em>, the vector is expanded with (0, 1).</p> +<p>When multiplying a <em>float2</em> to a <em><a class="el" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a></em>, the vector is expanded with (0).</p> +<p>This function is available in API version 10-13. Starting with API 14, the function takes a const matrix as the first argument.</p> <p>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </p> </div> </div> -<a class="anchor" id="a88ae2ed203769cb4a7917f84f6c1a2e2"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a88ae2ed203769cb4a7917f84f6c1a2e2" args="(const rs_matrix3x3 *m, float3 in)" --> +<a class="anchor" id="a716bc2d29b80eb25388aba3ba8845aef"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a716bc2d29b80eb25388aba3ba8845aef" args="(rs_matrix3x3 *m, float3 in)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname"><a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> rsMatrixMultiply </td> + <td class="memname">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> rsMatrixMultiply </td> <td>(</td> - <td class="paramtype">const <a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> * </td> + <td class="paramtype"><a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> * </td> <td class="paramname"><em>m</em>, </td> </tr> <tr> @@ -1142,14 +1194,14 @@ Functions</h2></td></tr> </div> </div> -<a class="anchor" id="a8d81a7143d5d45f60f7e91f955579bab"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a8d81a7143d5d45f60f7e91f955579bab" args="(const rs_matrix2x2 *m, float2 in)" --> +<a class="anchor" id="a4d9a8bb7c3f5d67b14fa349bdd531d13"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixMultiply" ref="a4d9a8bb7c3f5d67b14fa349bdd531d13" args="(rs_matrix2x2 *m, float2 in)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname"><a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> rsMatrixMultiply </td> + <td class="memname">_RS_RUNTIME <a class="el" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> rsMatrixMultiply </td> <td>(</td> - <td class="paramtype">const <a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> * </td> + <td class="paramtype"><a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> * </td> <td class="paramname"><em>m</em>, </td> </tr> <tr> @@ -1212,14 +1264,16 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiple matrix m with a rotation matrix</p> +<p>Multiply the matrix <em>m</em> with a rotation matrix.</p> +<p>This function modifies a transformation matrix to first do a rotation. The axis of rotation is the <em>(x, y, z)</em> vector.</p> +<p>To apply this combined transformation to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">rot</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to modify. </td></tr> + <tr><td class="paramname">rot</td><td>How much rotation to do, in degrees. </td></tr> + <tr><td class="paramname">x</td><td>The x component of the vector that is the axis of rotation. </td></tr> + <tr><td class="paramname">y</td><td>The y component of the vector that is the axis of rotation. </td></tr> + <tr><td class="paramname">z</td><td>The z component of the vector that is the axis of rotation. </td></tr> </table> </dd> </dl> @@ -1262,25 +1316,27 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiple matrix m with a scale matrix</p> +<p>Multiply the matrix <em>m</em> with a scaling matrix.</p> +<p>This function modifies a transformation matrix to first do a scaling. When scaling, each component of a vector is multiplied by a number. This number can be negative.</p> +<p>To apply this combined transformation to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to modify. </td></tr> + <tr><td class="paramname">x</td><td>The multiple to scale the x components by. </td></tr> + <tr><td class="paramname">y</td><td>The multiple to scale the y components by. </td></tr> + <tr><td class="paramname">z</td><td>The multiple to scale the z components by. </td></tr> </table> </dd> </dl> </div> </div> -<a class="anchor" id="ad6ea242218e0f1a031f754df0317e6e7"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="ad6ea242218e0f1a031f754df0317e6e7" args="(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v)" --> +<a class="anchor" id="aca88832ed720e301780152c60884393e"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="aca88832ed720e301780152c60884393e" args="(rs_matrix4x4 *m, uint32_t col, uint32_t row, float v)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">void rsMatrixSet </td> + <td class="memname">_RS_RUNTIME void rsMatrixSet </td> <td>(</td> <td class="paramtype"><a class="el" href="structrs__matrix4x4.html">rs_matrix4x4</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -1289,13 +1345,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em>, </td> + <td class="paramname"><em>row</em>, </td> </tr> <tr> <td class="paramkey"></td> @@ -1311,26 +1367,27 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Set one element of a matrix.</p> +<p>Set an element of a matrix.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td>The matrix to be set </td></tr> - <tr><td class="paramname">row</td><td></td></tr> - <tr><td class="paramname">col</td><td></td></tr> - <tr><td class="paramname">v</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix that will be modified. </td></tr> + <tr><td class="paramname">col</td><td>The zero-based column of the element to be set. </td></tr> + <tr><td class="paramname">row</td><td>The zero-based row of the element to be set. </td></tr> + <tr><td class="paramname">v</td><td>The value to set.</td></tr> </table> </dd> </dl> +<dl class="warning"><dt><b>Warning:</b></dt><dd>The order of the column and row parameters may be unexpected.</dd></dl> <dl class="return"><dt><b>Returns:</b></dt><dd>void </dd></dl> </div> </div> -<a class="anchor" id="ab69543f85a673f23fbb5f893e5824395"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="ab69543f85a673f23fbb5f893e5824395" args="(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v)" --> +<a class="anchor" id="a08a247cdf2e70e78310bf04f9ecd5144"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="a08a247cdf2e70e78310bf04f9ecd5144" args="(rs_matrix3x3 *m, uint32_t col, uint32_t row, float v)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">void rsMatrixSet </td> + <td class="memname">_RS_RUNTIME void rsMatrixSet </td> <td>(</td> <td class="paramtype"><a class="el" href="structrs__matrix3x3.html">rs_matrix3x3</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -1339,13 +1396,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em>, </td> + <td class="paramname"><em>row</em>, </td> </tr> <tr> <td class="paramkey"></td> @@ -1365,12 +1422,12 @@ Functions</h2></td></tr> </div> </div> -<a class="anchor" id="a0a85c8d3607f1b75019f6991c5b19fca"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="a0a85c8d3607f1b75019f6991c5b19fca" args="(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v)" --> +<a class="anchor" id="af9707d7be5945bf55ed53683624176ff"></a><!-- doxytag: member="rs_matrix.rsh::rsMatrixSet" ref="af9707d7be5945bf55ed53683624176ff" args="(rs_matrix2x2 *m, uint32_t col, uint32_t row, float v)" --> <div class="memitem"> <div class="memproto"> <table class="memname"> <tr> - <td class="memname">void rsMatrixSet </td> + <td class="memname">_RS_RUNTIME void rsMatrixSet </td> <td>(</td> <td class="paramtype"><a class="el" href="structrs__matrix2x2.html">rs_matrix2x2</a> * </td> <td class="paramname"><em>m</em>, </td> @@ -1379,13 +1436,13 @@ Functions</h2></td></tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>row</em>, </td> + <td class="paramname"><em>col</em>, </td> </tr> <tr> <td class="paramkey"></td> <td></td> <td class="paramtype"><a class="el" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> </td> - <td class="paramname"><em>col</em>, </td> + <td class="paramname"><em>row</em>, </td> </tr> <tr> <td class="paramkey"></td> @@ -1441,13 +1498,15 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Multiple matrix m with a translation matrix</p> +<p>Multiply the matrix <em>m</em> with a translation matrix.</p> +<p>This function modifies a transformation matrix to first do a translation. When translating, a number is added to each component of a vector.</p> +<p>To apply this combined transformation to a vector, multiply the vector by the created matrix using <a class="el" href="rs__matrix_8rsh.html#a4d9a8bb7c3f5d67b14fa349bdd531d13">rsMatrixMultiply</a>.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> - <tr><td class="paramname">x</td><td></td></tr> - <tr><td class="paramname">y</td><td></td></tr> - <tr><td class="paramname">z</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to modify. </td></tr> + <tr><td class="paramname">x</td><td>The number to add to each x component. </td></tr> + <tr><td class="paramname">y</td><td>The number to add to each y component. </td></tr> + <tr><td class="paramname">z</td><td>The number to add to each z component. </td></tr> </table> </dd> </dl> @@ -1468,10 +1527,10 @@ Functions</h2></td></tr> </table> </div> <div class="memdoc"> -<p>Transpose the matrix m.</p> +<p>Transpose the matrix m in place.</p> <dl><dt><b>Parameters:</b></dt><dd> <table class="params"> - <tr><td class="paramname">m</td><td></td></tr> + <tr><td class="paramname">m</td><td>The matrix to transpose. </td></tr> </table> </dd> </dl> diff --git a/docs/html/reference/renderscript/rs__matrix_8rsh_source.html b/docs/html/reference/renderscript/rs__matrix_8rsh_source.html index c1aaeb2..77144bd 100644 --- a/docs/html/reference/renderscript/rs__matrix_8rsh_source.html +++ b/docs/html/reference/renderscript/rs__matrix_8rsh_source.html @@ -3,7 +3,7 @@ <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> -<title>/usr/local/google/home/srhines/android_trees/jb-mr2-dev/frameworks/rs/scriptc/rs_matrix.rsh Source File</title> +<title>frameworks/rs/scriptc/rs_matrix.rsh Source File</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css" /> @@ -24,7 +24,7 @@ </div> <div class="header"> <div class="headertitle"> -<div class="title">/usr/local/google/home/srhines/android_trees/jb-mr2-dev/frameworks/rs/scriptc/rs_matrix.rsh</div> </div> +<div class="title">frameworks/rs/scriptc/rs_matrix.rsh</div> </div> </div> <div class="contents"> <a href="rs__matrix_8rsh.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span> @@ -43,129 +43,128 @@ <a name="l00014"></a>00014 <span class="comment"> * limitations under the License.</span> <a name="l00015"></a>00015 <span class="comment"> */</span> <a name="l00016"></a>00016 -<a name="l00023"></a>00023 <span class="preprocessor">#ifndef __RS_MATRIX_RSH__</span> -<a name="l00024"></a>00024 <span class="preprocessor"></span><span class="preprocessor">#define __RS_MATRIX_RSH__</span> -<a name="l00025"></a>00025 <span class="preprocessor"></span> -<a name="l00036"></a>00036 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00037"></a>00037 <a class="code" href="rs__matrix_8rsh.html#ad6ea242218e0f1a031f754df0317e6e7">rsMatrixSet</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <span class="keywordtype">float</span> v); -<a name="l00041"></a>00041 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00042"></a>00042 <a class="code" href="rs__matrix_8rsh.html#ad6ea242218e0f1a031f754df0317e6e7">rsMatrixSet</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <span class="keywordtype">float</span> v); -<a name="l00046"></a>00046 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00047"></a>00047 <a class="code" href="rs__matrix_8rsh.html#ad6ea242218e0f1a031f754df0317e6e7">rsMatrixSet</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <span class="keywordtype">float</span> v); -<a name="l00048"></a>00048 -<a name="l00058"></a>00058 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) -<a name="l00059"></a>00059 <a class="code" href="rs__matrix_8rsh.html#a22e983b67d3089c5cb97032e249ca335">rsMatrixGet</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col); -<a name="l00063"></a>00063 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) -<a name="l00064"></a>00064 <a class="code" href="rs__matrix_8rsh.html#a22e983b67d3089c5cb97032e249ca335">rsMatrixGet</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col); -<a name="l00068"></a>00068 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) -<a name="l00069"></a>00069 <a class="code" href="rs__matrix_8rsh.html#a22e983b67d3089c5cb97032e249ca335">rsMatrixGet</a>(const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col); -<a name="l00070"></a>00070 -<a name="l00076"></a>00076 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); -<a name="l00080"></a>00080 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m); -<a name="l00084"></a>00084 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m); -<a name="l00085"></a>00085 -<a name="l00091"></a>00091 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <span class="keywordtype">float</span> *v); -<a name="l00095"></a>00095 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <span class="keywordtype">float</span> *v); -<a name="l00099"></a>00099 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <span class="keywordtype">float</span> *v); -<a name="l00103"></a>00103 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *v); -<a name="l00107"></a>00107 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *v); -<a name="l00108"></a>00108 -<a name="l00114"></a>00114 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *v); -<a name="l00118"></a>00118 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *v); -<a name="l00122"></a>00122 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *v); -<a name="l00123"></a>00123 -<a name="l00133"></a>00133 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00134"></a>00134 <a class="code" href="rs__matrix_8rsh.html#a268032f3ac6d766b1d7fe72a6cb50464">rsMatrixLoadRotate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> rot, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00135"></a>00135 -<a name="l00144"></a>00144 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00145"></a>00145 <a class="code" href="rs__matrix_8rsh.html#acaf51d1f9ad5041ce01fbf8b7c5923fd">rsMatrixLoadScale</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00146"></a>00146 -<a name="l00155"></a>00155 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00156"></a>00156 <a class="code" href="rs__matrix_8rsh.html#a1b521c8a3d1260fa732cbf0a71af0e74">rsMatrixLoadTranslate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00157"></a>00157 -<a name="l00165"></a>00165 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00166"></a>00166 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *lhs, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *rhs); -<a name="l00170"></a>00170 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00171"></a>00171 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *lhs, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *rhs); -<a name="l00175"></a>00175 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00176"></a>00176 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *lhs, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *rhs); -<a name="l00177"></a>00177 -<a name="l00184"></a>00184 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00185"></a>00185 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *rhs); -<a name="l00189"></a>00189 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00190"></a>00190 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *rhs); -<a name="l00194"></a>00194 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00195"></a>00195 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *rhs); -<a name="l00196"></a>00196 -<a name="l00206"></a>00206 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00207"></a>00207 <a class="code" href="rs__matrix_8rsh.html#ad5ed05ca4880397fb29615e3c6798de1">rsMatrixRotate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> rot, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00208"></a>00208 -<a name="l00217"></a>00217 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00218"></a>00218 <a class="code" href="rs__matrix_8rsh.html#a94cc6b22bd1a6c07a9a1c1d21afb392c">rsMatrixScale</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00219"></a>00219 -<a name="l00228"></a>00228 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00229"></a>00229 <a class="code" href="rs__matrix_8rsh.html#a4df5f9b5bb6044f3c3426f2f58b94405">rsMatrixTranslate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); -<a name="l00230"></a>00230 -<a name="l00242"></a>00242 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00243"></a>00243 <a class="code" href="rs__matrix_8rsh.html#a4c59884a0e534dbbcdc5655842732d43">rsMatrixLoadOrtho</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> left, <span class="keywordtype">float</span> right, <span class="keywordtype">float</span> bottom, <span class="keywordtype">float</span> top, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); -<a name="l00244"></a>00244 -<a name="l00256"></a>00256 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00257"></a>00257 <a class="code" href="rs__matrix_8rsh.html#ad25760aaf01e95d0055237afab41bbb3">rsMatrixLoadFrustum</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> left, <span class="keywordtype">float</span> right, <span class="keywordtype">float</span> bottom, <span class="keywordtype">float</span> top, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); -<a name="l00258"></a>00258 -<a name="l00268"></a>00268 extern <span class="keywordtype">void</span> __attribute__((overloadable)) -<a name="l00269"></a>00269 <a class="code" href="rs__matrix_8rsh.html#aa404c34d7478f2921f7415d2da95d02b">rsMatrixLoadPerspective</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a>* m, <span class="keywordtype">float</span> fovy, <span class="keywordtype">float</span> aspect, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); -<a name="l00270"></a>00270 -<a name="l00271"></a>00271 <span class="preprocessor">#if !defined(RS_VERSION) || (RS_VERSION < 14)</span> -<a name="l00272"></a>00272 <span class="preprocessor"></span> -<a name="l00276"></a>00276 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00277"></a>00277 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in); -<a name="l00278"></a>00278 -<a name="l00282"></a>00282 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00283"></a>00283 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); +<a name="l00050"></a>00050 <span class="preprocessor">#ifndef __RS_MATRIX_RSH__</span> +<a name="l00051"></a>00051 <span class="preprocessor"></span><span class="preprocessor">#define __RS_MATRIX_RSH__</span> +<a name="l00052"></a>00052 <span class="preprocessor"></span> +<a name="l00066"></a>00066 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00067"></a>00067 <a class="code" href="rs__matrix_8rsh.html#aca88832ed720e301780152c60884393e">rsMatrixSet</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <span class="keywordtype">float</span> v); +<a name="l00071"></a>00071 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00072"></a>00072 <a class="code" href="rs__matrix_8rsh.html#aca88832ed720e301780152c60884393e">rsMatrixSet</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <span class="keywordtype">float</span> v); +<a name="l00076"></a>00076 _RS_RUNTIME <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00077"></a>00077 <a class="code" href="rs__matrix_8rsh.html#aca88832ed720e301780152c60884393e">rsMatrixSet</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row, <span class="keywordtype">float</span> v); +<a name="l00078"></a>00078 +<a name="l00091"></a>00091 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) +<a name="l00092"></a>00092 <a class="code" href="rs__matrix_8rsh.html#af26fdbf8b8f0ed5d1b53f62b2aef5110">rsMatrixGet</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row); +<a name="l00096"></a>00096 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) +<a name="l00097"></a>00097 <a class="code" href="rs__matrix_8rsh.html#af26fdbf8b8f0ed5d1b53f62b2aef5110">rsMatrixGet</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row); +<a name="l00101"></a>00101 _RS_RUNTIME <span class="keywordtype">float</span> __attribute__((overloadable)) +<a name="l00102"></a>00102 <a class="code" href="rs__matrix_8rsh.html#af26fdbf8b8f0ed5d1b53f62b2aef5110">rsMatrixGet</a>(const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> col, <a class="code" href="rs__types_8rsh.html#a435d1572bf3f880d55459d9805097f62">uint32_t</a> row); +<a name="l00103"></a>00103 +<a name="l00109"></a>00109 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); +<a name="l00113"></a>00113 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m); +<a name="l00117"></a>00117 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a0ffd9de971cf10d0a663ff565be8d3cc">rsMatrixLoadIdentity</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m); +<a name="l00118"></a>00118 +<a name="l00130"></a>00130 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <span class="keywordtype">float</span> *v); +<a name="l00134"></a>00134 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <span class="keywordtype">float</span> *v); +<a name="l00138"></a>00138 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <span class="keywordtype">float</span> *v); +<a name="l00156"></a>00156 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *v); +<a name="l00160"></a>00160 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *v); +<a name="l00164"></a>00164 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *v); +<a name="l00168"></a>00168 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *v); +<a name="l00172"></a>00172 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac380c4117e047da494a74f0dad20fab3">rsMatrixLoad</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *v); +<a name="l00173"></a>00173 +<a name="l00191"></a>00191 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00192"></a>00192 <a class="code" href="rs__matrix_8rsh.html#a268032f3ac6d766b1d7fe72a6cb50464">rsMatrixLoadRotate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> rot, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); +<a name="l00193"></a>00193 +<a name="l00208"></a>00208 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00209"></a>00209 <a class="code" href="rs__matrix_8rsh.html#acaf51d1f9ad5041ce01fbf8b7c5923fd">rsMatrixLoadScale</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); +<a name="l00210"></a>00210 +<a name="l00225"></a>00225 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00226"></a>00226 <a class="code" href="rs__matrix_8rsh.html#a1b521c8a3d1260fa732cbf0a71af0e74">rsMatrixLoadTranslate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); +<a name="l00227"></a>00227 +<a name="l00247"></a>00247 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00248"></a>00248 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *lhs, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *rhs); +<a name="l00252"></a>00252 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00253"></a>00253 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *lhs, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *rhs); +<a name="l00257"></a>00257 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00258"></a>00258 <a class="code" href="rs__matrix_8rsh.html#a79f14c4c0f5ecc1bbd0bf54da8b653ef">rsMatrixLoadMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *lhs, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *rhs); +<a name="l00259"></a>00259 +<a name="l00272"></a>00272 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00273"></a>00273 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *rhs); +<a name="l00277"></a>00277 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00278"></a>00278 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *rhs); +<a name="l00282"></a>00282 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00283"></a>00283 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *rhs); <a name="l00284"></a>00284 -<a name="l00288"></a>00288 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00289"></a>00289 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); -<a name="l00290"></a>00290 -<a name="l00294"></a>00294 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) -<a name="l00295"></a>00295 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); -<a name="l00296"></a>00296 -<a name="l00300"></a>00300 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) -<a name="l00301"></a>00301 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00300"></a>00300 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00301"></a>00301 <a class="code" href="rs__matrix_8rsh.html#ad5ed05ca4880397fb29615e3c6798de1">rsMatrixRotate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> rot, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); <a name="l00302"></a>00302 -<a name="l00306"></a>00306 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> __attribute__((overloadable)) -<a name="l00307"></a>00307 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); -<a name="l00308"></a>00308 <span class="preprocessor">#else</span> -<a name="l00309"></a>00309 <span class="preprocessor"></span> -<a name="l00313"></a>00313 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00314"></a>00314 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in); -<a name="l00315"></a>00315 -<a name="l00319"></a>00319 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00320"></a>00320 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); -<a name="l00321"></a>00321 -<a name="l00325"></a>00325 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) -<a name="l00326"></a>00326 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); -<a name="l00327"></a>00327 -<a name="l00331"></a>00331 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) -<a name="l00332"></a>00332 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); -<a name="l00333"></a>00333 -<a name="l00337"></a>00337 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) -<a name="l00338"></a>00338 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); -<a name="l00339"></a>00339 -<a name="l00343"></a>00343 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> __attribute__((overloadable)) -<a name="l00344"></a>00344 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); -<a name="l00345"></a>00345 <span class="preprocessor">#endif</span> -<a name="l00346"></a>00346 <span class="preprocessor"></span> -<a name="l00347"></a>00347 -<a name="l00353"></a>00353 <span class="keyword">extern</span> <span class="keywordtype">bool</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a00b6a334ba5ac94d84850f22ec9f4de5">rsMatrixInverse</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); -<a name="l00354"></a>00354 -<a name="l00360"></a>00360 extern <span class="keywordtype">bool</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac05080d52da2d99a759ef34fa0655e82">rsMatrixInverseTranspose</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); -<a name="l00361"></a>00361 -<a name="l00367"></a>00367 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); -<a name="l00371"></a>00371 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m); -<a name="l00375"></a>00375 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m); -<a name="l00376"></a>00376 -<a name="l00377"></a>00377 -<a name="l00378"></a>00378 <span class="preprocessor">#endif</span> +<a name="l00318"></a>00318 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00319"></a>00319 <a class="code" href="rs__matrix_8rsh.html#a94cc6b22bd1a6c07a9a1c1d21afb392c">rsMatrixScale</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); +<a name="l00320"></a>00320 +<a name="l00336"></a>00336 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00337"></a>00337 <a class="code" href="rs__matrix_8rsh.html#a4df5f9b5bb6044f3c3426f2f58b94405">rsMatrixTranslate</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> x, <span class="keywordtype">float</span> y, <span class="keywordtype">float</span> z); +<a name="l00338"></a>00338 +<a name="l00361"></a>00361 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00362"></a>00362 <a class="code" href="rs__matrix_8rsh.html#a4c59884a0e534dbbcdc5655842732d43">rsMatrixLoadOrtho</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> left, <span class="keywordtype">float</span> right, <span class="keywordtype">float</span> bottom, <span class="keywordtype">float</span> top, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); +<a name="l00363"></a>00363 +<a name="l00384"></a>00384 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00385"></a>00385 <a class="code" href="rs__matrix_8rsh.html#ad25760aaf01e95d0055237afab41bbb3">rsMatrixLoadFrustum</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <span class="keywordtype">float</span> left, <span class="keywordtype">float</span> right, <span class="keywordtype">float</span> bottom, <span class="keywordtype">float</span> top, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); +<a name="l00386"></a>00386 +<a name="l00403"></a>00403 extern <span class="keywordtype">void</span> __attribute__((overloadable)) +<a name="l00404"></a>00404 <a class="code" href="rs__matrix_8rsh.html#aa404c34d7478f2921f7415d2da95d02b">rsMatrixLoadPerspective</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a>* m, <span class="keywordtype">float</span> fovy, <span class="keywordtype">float</span> aspect, <span class="keywordtype">float</span> near, <span class="keywordtype">float</span> far); +<a name="l00405"></a>00405 +<a name="l00406"></a>00406 <span class="preprocessor">#if !defined(RS_VERSION) || (RS_VERSION < 14)</span> +<a name="l00407"></a>00407 <span class="preprocessor"></span> +<a name="l00421"></a>00421 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00422"></a>00422 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in); +<a name="l00423"></a>00423 +<a name="l00427"></a>00427 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00428"></a>00428 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); +<a name="l00429"></a>00429 +<a name="l00433"></a>00433 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00434"></a>00434 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00435"></a>00435 +<a name="l00439"></a>00439 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) +<a name="l00440"></a>00440 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); +<a name="l00441"></a>00441 +<a name="l00445"></a>00445 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) +<a name="l00446"></a>00446 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00447"></a>00447 +<a name="l00451"></a>00451 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> __attribute__((overloadable)) +<a name="l00452"></a>00452 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00453"></a>00453 <span class="preprocessor">#else</span> +<a name="l00454"></a>00454 <span class="preprocessor"></span> +<a name="l00467"></a>00467 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00468"></a>00468 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> in); +<a name="l00469"></a>00469 +<a name="l00473"></a>00473 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00474"></a>00474 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); +<a name="l00475"></a>00475 +<a name="l00479"></a>00479 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#adb5162dc168ddd471d948faa60b37c5e">float4</a> __attribute__((overloadable)) +<a name="l00480"></a>00480 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00481"></a>00481 +<a name="l00485"></a>00485 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) +<a name="l00486"></a>00486 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> in); +<a name="l00487"></a>00487 +<a name="l00491"></a>00491 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a0046fa0f208d0899adbcf1f8b5aafadd">float3</a> __attribute__((overloadable)) +<a name="l00492"></a>00492 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00493"></a>00493 +<a name="l00497"></a>00497 _RS_RUNTIME <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> __attribute__((overloadable)) +<a name="l00498"></a>00498 <a class="code" href="rs__matrix_8rsh.html#a97953ab2606900a839e5816c619abe66">rsMatrixMultiply</a>(const <a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m, <a class="code" href="rs__types_8rsh.html#a5086d0fcb71f916c936af486ccf0dd41">float2</a> in); +<a name="l00499"></a>00499 <span class="preprocessor">#endif</span> +<a name="l00500"></a>00500 <span class="preprocessor"></span> +<a name="l00501"></a>00501 +<a name="l00509"></a>00509 <span class="keyword">extern</span> <span class="keywordtype">bool</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a00b6a334ba5ac94d84850f22ec9f4de5">rsMatrixInverse</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); +<a name="l00510"></a>00510 +<a name="l00519"></a>00519 extern <span class="keywordtype">bool</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#ac05080d52da2d99a759ef34fa0655e82">rsMatrixInverseTranspose</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); +<a name="l00520"></a>00520 +<a name="l00526"></a>00526 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix4x4.html" title="4x4 float matrix">rs_matrix4x4</a> *m); +<a name="l00530"></a>00530 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix3x3.html" title="3x3 float matrix">rs_matrix3x3</a> *m); +<a name="l00534"></a>00534 extern <span class="keywordtype">void</span> __attribute__((overloadable)) <a class="code" href="rs__matrix_8rsh.html#a88095c70f1550c760844b3e32e41a31a">rsMatrixTranspose</a>(<a class="code" href="structrs__matrix2x2.html" title="2x2 float matrix">rs_matrix2x2</a> *m); +<a name="l00535"></a>00535 +<a name="l00536"></a>00536 +<a name="l00537"></a>00537 <span class="preprocessor">#endif</span> </pre></div></div> </div> diff --git a/docs/html/tools/sdk/ndk/index.jd b/docs/html/tools/sdk/ndk/index.jd index 71b15d5..e75f451 100644 --- a/docs/html/tools/sdk/ndk/index.jd +++ b/docs/html/tools/sdk/ndk/index.jd @@ -2,59 +2,59 @@ ndk=true page.template=sdk -ndk.mac64_download=android-ndk32-r10-darwin-x86_64.tar.bz2 -ndk.mac64_bytes=411610468 -ndk.mac64_checksum=3ce1fa3dbe7a188f5d2640fd2f7ca944 +ndk.mac64_download=android-ndk32-r10b-darwin-x86_64.tar.bz2 +ndk.mac64_bytes=413652124 +ndk.mac64_checksum=7ca4a84e9c56c38acdafb007e7cd33c5 -ndk.mac32_download=android-ndk32-r10-darwin-x86.tar.bz2 -ndk.mac32_bytes=404768263 -ndk.mac32_checksum=1824eec1f6749b6cb7bb306a3b924c33 +ndk.mac32_download=android-ndk32-r10b-darwin-x86.tar.bz2 +ndk.mac32_bytes=406998070 +ndk.mac32_checksum=db3626b2c5f3245d90e2724f7bcf4c3e -ndk.linux64_download=android-ndk32-r10-linux-x86_64.tar.bz2 -ndk.linux64_bytes=420671390 -ndk.linux64_checksum=e3ff629d212a8106a43415862fa39baf +ndk.linux64_download=android-ndk32-r10b-linux-x86_64.tar.bz2 +ndk.linux64_bytes=422237011 +ndk.linux64_checksum=5c0f301aa789a1a747d5d2aeb8c69ef3 -ndk.linux32_download=android-ndk32-r10-linux-x86.tar.bz2 -ndk.linux32_bytes=420078216 -ndk.linux32_checksum=8d9a5faa6e77b43bfae0f169079b21c4 +ndk.linux32_download=android-ndk32-r10b-linux-x86.tar.bz2 +ndk.linux32_bytes=421052081 +ndk.linux32_checksum=e8f55daa5c9de7ab79aaaf5d7d751b69 -ndk.win64_download=android-ndk32-r10-windows-x86_64.zip -ndk.win64_bytes=529850429 -ndk.win64_checksum=b11f9239344f7c377ed5b627f0fb236e +ndk.win64_download=android-ndk32-r10b-windows-x86_64.zip +ndk.win64_bytes=531912027 +ndk.win64_checksum=e4dd2e0c6f38e3ad936c366bdf6b1d4e -ndk.win32_download=android-ndk32-r10-windows-x86.zip -ndk.win32_bytes=500135685 -ndk.win32_checksum=0a3c01147abba945cc4ef5837519ec97 +ndk.win32_download=android-ndk32-r10b-windows-x86.zip +ndk.win32_bytes=502720425 +ndk.win32_checksum=9fa4f19bca7edd6eefa63fe788737987 -ndk.mac64_64_download=android-ndk64-r10-darwin-x86_64.tar.bz2 -ndk.mac64_64_bytes=327740247 -ndk.mac64_64_checksum=72561b27acc6192a2e81b345ea128a20 +ndk.mac64_64_download=android-ndk64-r10b-darwin-x86_64.tar.bz2 +ndk.mac64_64_bytes=346423776 +ndk.mac64_64_checksum=5bae7feed20ebf0762c0baefe6b84b6d -ndk.mac32_64_download=android-ndk64-r10-darwin-x86.tar.bz2 -ndk.mac32_64_bytes=323736411 -ndk.mac32_64_checksum=5bbaf9d8051ba5d2c0fff74cfd87c374 +ndk.mac32_64_download=android-ndk64-r10b-darwin-x86.tar.bz2 +ndk.mac32_64_bytes=344052876 +ndk.mac32_64_checksum=4447049ac2b5877176b9b6b1cf3bcdb2 -ndk.linux64_64_download=android-ndk64-r10-linux-x86_64.tar.bz2 -ndk.linux64_64_bytes=339708042 -ndk.linux64_64_checksum=737290195583268b7fbff4aa56465ab6 +ndk.linux64_64_download=android-ndk64-r10b-linux-x86_64.tar.bz2 +ndk.linux64_64_bytes=358835298 +ndk.linux64_64_checksum=2aa12a0d9a70bcab83e42d010a685136 -ndk.linux32_64_download=android-ndk64-r10-linux-x86.tar.bz2 -ndk.linux32_64_bytes=338544906 -ndk.linux32_64_checksum=bea5d027baeb948cbff6af840d26b80d +ndk.linux32_64_download=android-ndk64-r10b-linux-x86.tar.bz2 +ndk.linux32_64_bytes=358060577 +ndk.linux32_64_checksum=b77eb583626d8c7f5c11e49181fd5eac -ndk.win64_64_download=android-ndk64-r10-windows-x86_64.zip -ndk.win64_64_bytes=417411195 -ndk.win64_64_checksum=91879ec85539b45313a21b9526b911a8 +ndk.win64_64_download=android-ndk64-r10b-windows-x86_64.zip +ndk.win64_64_bytes=437152652 +ndk.win64_64_checksum=df39185e6c5a4d72eb9fca3f9aaabc46 -ndk.win32_64_download=android-ndk64-r10-windows-x86.zip -ndk.win32_64_bytes=396751892 -ndk.win32_64_checksum=f79070ace2cde9ebf6a2e2be4a61ac7a +ndk.win32_64_download=android-ndk64-r10b-windows-x86.zip +ndk.win32_64_bytes=417290468 +ndk.win32_64_checksum=0f0324cb11f04e8b2641e5422ee39c81 -ndk.debug_info_download=android-ndk-r10-cxx-stl-libs-with-debug-info.zip -ndk.debug_info_bytes=253198908 -ndk.debug_info_checksum=c2a90c43d17dbb5f0609cc8237491788 +ndk.debug_info_download=android-ndk-r10b-cxx-stl-libs-with-debug-info.zip +ndk.debug_info_bytes=227302317 +ndk.debug_info_checksum=bed1bb855a41bdb572a804dbf6d45aa6 page.title=Android NDK @@ -357,15 +357,6 @@ injunctive remedies (or an equivalent type of urgent legal relief) in any jurisd </div> </div> - - - - - - - - - <div id="qv-wrapper"> <div id="qv"> <h2>In this document</h2> @@ -418,7 +409,7 @@ $('#Downloads').after($('#download-table')); <p>With NDK revision 9 and higher, the release packages have been split to reduce download size. - The first download for each platform contains the default NDK toolchain. The second download + The first download for each platform contains the default NDK toolchain. The additional download contains legacy NDK toolchains for that platform, which is only required if you are not using the current, recommended toolchain for your NDK builds.</p> @@ -426,10 +417,91 @@ $('#Downloads').after($('#download-table')); <p>The following sections provide information about releases of the NDK.</p> + <div class="toggle-content opened"> <p> <a href="#" onclick="return toggleContent(this)"> <img src="/assets/images/triangle-opened.png" class="toggle-content-img" alt="" + >Android NDK, Revision 10b</a> <em>(September 2014)</em> + </p> + <div class="toggle-content-toggleme"> + <dl> + + <dt>Important notes:</dt> + <dd> + <ul> + <li>Because of the 512MB size restriction on downloadable packages, the following 32-bit items are not in the 32-bit NDK download packages. Instead, they reside in the 64-bit ones:</li> + <ul> + <li>Android-L headers</li> + <li>GCC 4.9</li> + </ul> + <li>Currently, the only Renderscript support provided by the NDK is for 32-bit Renderscript with Android 4.4 (API level 19). You cannot build HelloComputeNDK (the only Renderscript sample) with any other combination of Renderscript (32- or 64-bit) and Android version.</li> + <li>To compile native-codec, you must use a 64-bit NDK package, which is where all the Android-L headers are located. </li> + </ul> + </dd> + + + <dt>Important bug fixes:</dt> + <dd> + <ul> + <li>Fixed gdb 7.6 in GCC 4.8/4.9. (Issues <a href="http://b.android.com/74112">74112</a> and <a href="http://b.android.com/74371">74371</a>.)</li> + <li>Fixed GCC 4.8/4.9 for x86, so that they no longer enable <code>-msse4.2</code> and <code>-mpopcnt</code> by default. (Issue <a href="http://b.android.com/73843">73843</a>.)</li> + </ul> + </dd> + + <dt>Other bug fixes:</dt> + <dd> + <ul> + <li>Removed <code>stdio.h</code> from the <code>include-fixed/</code> directories of all versions of GCC. (Issue <a href="http://b.android.com/73728">73728</a>.)</li> + <li>Removed duplicate header files from the Windows packages in the <code>platforms/android-L/arch-*/usr/include/linux/netfilter*/</code> directories. (Issue <a href="https://code.google.com/p/android/issues/detail?id=73704">73704</a>.)</li> + <li>Fixed a problem that prevented Clang from building HelloComputeNDK.</li> + <li>Fixed atexit. (Issue <a href="http://b.android.com/66595">66595</a>.)</li> + <li>Made various fixes to the docs in <code>docs/</code> and <code>sources/third_party/googletest/README.NDK</code>. (Issue <a href="http://b.android.com/74069">74069</a>.)</li> + <li>Made the following fixes to the Android-L headers:</li> + <ol> + <li>Added the following functions to <code>ctype.h</code> and <code>wchar.h</code>: <code>dn_expand()</code>, <code>grantpt()</code>, <code> inet_nsap_addr()</code>, <code>inet_nsap_ntoa()</code>, <code>insque()</code>, <code>nsdispatch()</code>, <code>posix_openpt()</code>, <code>__pthread_cleanup_pop()</code>, <code>__pthread_cleanup_push()</code>, <code>remque()</code>, <code>setfsgid()</code>, <code>setfsuid()</code>, <code>splice()</code>, <code>tee()</code>, <code>twalk()</code> (Issue <a href = "http://b.android.com/73719">73719</a>), and 42 <code>*_l()</code> functions.</li> + + <li>Renamed <code>cmsg_nxthdr</code> to <code>__cmsg_nxthdr</code>.</li> + + <li>Removed <code>__libc_malloc_dispatch</code>.</li> + + <li>Changed the <code>ptrace()</code> prototype to <code>long ptrace(int, ...);</code>.</li> + + <li>Removed <code>sha1.h</code>.</li> + + <li>Extended <code>android_dlextinfo</code> in <code>android/dlext.h</code>.</li> + + <li>Annotated <code>__NDK_FPABI__</code> for functions receiving or returning float- or double-type values in <code>stdlib.h</code>, <code>time.h</code>, <code>wchar.h</code>, and <code>complex.h</code>.</li> + </ol> + </ul> + </dd> + + <dt>Other changes:</dt> + <dd> + <ul> + <li>Updated <code>mipsel-linux-android-4.9</code> and <code>mips64el-linux-android-4.9</code>, implementing a new multilib directory layout, and providing support for gdb-7.7</li> + <li>Enhanced <code>cpu-features</code> to detect more arm64 features. (Change list <a href="https://android-review.googlesource.com/#/c/100339">100339</a>.)</li> + </dd> + </ul> + + + + </dl> + </div> +</div> + + + + + + + + + +<div class="toggle-content closed"> + <p> + <a href="#" onclick="return toggleContent(this)"> <img + src="/assets/images/triangle-closed.png" class="toggle-content-img" alt="" >Android NDK, Revision 10</a> <em>(July 2014)</em> </p> <div class="toggle-content-toggleme"> @@ -442,7 +514,7 @@ $('#Downloads').after($('#download-table')); <li>GCC 4.9 is the default compiler for 64-bit ABIs. Clang is currently version 3.4. <code>NDK_TOOLCHAIN_VERSION=clang</code> may not work for arm64-v8a and mips64.</li> - <li>Android API level L is the first level with 64-bit support. Note that this API + <li>Android-L is the first level with 64-bit support. Note that this API level is a temporary one, and only for L-preview. An actual API level number will replace it at L-release.</li> <li>This release includes now includes <code>all32</code> and <code>all64</code> @@ -479,7 +551,7 @@ GCC 4.6 is still the default.</li> <li>For ndk-build, enable 32-bit, GCC 4.9 building either by adding <code>NDK_TOOLCHAIN_VERSION=4.9</code> to <code>Application.mk</code>, or exporting it as an environment variable from the command line.</li> - <li>For a standalone toolchain, use the <code> --toolchain=</code> option in the + <li>For a standalone toolchain, use the <code>--toolchain=</code> option in the <code>make-standalone-toolchain.sh</code> script. For example: <code>--toolchain=arm-linux-androideabi-4.9.</code></li> </ul> <li>Upgraded GDB to version 7.6 in GCC 4.8/4.9 and x86*. Since GDB is still at version GDB-7.3.x in diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index ba22550..e5e2f18 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -252,6 +252,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { throws XmlPullParserException, IOException { int eventType = parser.getEventType(); + float pathErrorScale = 1; while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG) { final String tagName = parser.getName(); @@ -261,9 +262,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { int drawableRes = a.getResourceId( R.styleable.AnimatedVectorDrawable_drawable, 0); if (drawableRes != 0) { - mAnimatedVectorState.mVectorDrawable = (VectorDrawable) res.getDrawable( + VectorDrawable vectorDrawable = (VectorDrawable) res.getDrawable( drawableRes, theme).mutate(); - mAnimatedVectorState.mVectorDrawable.setAllowCaching(false); + vectorDrawable.setAllowCaching(false); + pathErrorScale = vectorDrawable.getPixelSize(); + mAnimatedVectorState.mVectorDrawable = vectorDrawable; } a.recycle(); } else if (TARGET.equals(tagName)) { @@ -275,7 +278,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable { int id = a.getResourceId( R.styleable.AnimatedVectorDrawableTarget_animation, 0); if (id != 0) { - Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id); + Animator objectAnimator = AnimatorInflater.loadAnimator(res, theme, id, + pathErrorScale); setupAnimatorsForTarget(target, objectAnimator); } a.recycle(); diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 042da5b..a07ccc4 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -368,6 +368,29 @@ public class VectorDrawable extends Drawable { } } + /** + * The size of a pixel when scaled from the intrinsic dimension to the viewport dimension. + * This is used to calculate the path animation accuracy. + * + * @hide + */ + public float getPixelSize() { + if (mVectorState == null && mVectorState.mVPathRenderer == null || + mVectorState.mVPathRenderer.mBaseWidth == 0 || + mVectorState.mVPathRenderer.mBaseHeight == 0 || + mVectorState.mVPathRenderer.mViewportHeight == 0 || + mVectorState.mVPathRenderer.mViewportWidth == 0) { + return 1; // fall back to 1:1 pixel mapping. + } + float intrinsicWidth = mVectorState.mVPathRenderer.mBaseWidth; + float intrinsicHeight = mVectorState.mVPathRenderer.mBaseHeight; + float viewportWidth = mVectorState.mVPathRenderer.mViewportWidth; + float viewportHeight = mVectorState.mVPathRenderer.mViewportHeight; + float scaleX = viewportWidth / intrinsicWidth; + float scaleY = viewportHeight / intrinsicHeight; + return Math.min(scaleX, scaleY); + } + /** @hide */ public static VectorDrawable create(Resources resources, int rid) { try { diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java new file mode 100644 index 0000000..9837139 --- /dev/null +++ b/graphics/java/android/graphics/pdf/PdfEditor.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.graphics.pdf; + +import android.annotation.NonNull; +import android.os.ParcelFileDescriptor; +import android.system.ErrnoException; +import android.system.OsConstants; +import dalvik.system.CloseGuard; +import libcore.io.IoUtils; +import libcore.io.Libcore; + +import java.io.IOException; + +/** + * Class for editing PDF files. + * + * @hide + */ +public final class PdfEditor { + + private final CloseGuard mCloseGuard = CloseGuard.get(); + + private final long mNativeDocument; + + private int mPageCount; + + private ParcelFileDescriptor mInput; + + /** + * Creates a new instance. + * <p> + * <strong>Note:</strong> The provided file descriptor must be <strong>seekable</strong>, + * i.e. its data being randomly accessed, e.g. pointing to a file. After finishing + * with this class you must call {@link #close()}. + * </p> + * <p> + * <strong>Note:</strong> This class takes ownership of the passed in file descriptor + * and is responsible for closing it when the editor is closed. + * </p> + * + * @param input Seekable file descriptor to read from. + * + * @see #close() + */ + public PdfEditor(@NonNull ParcelFileDescriptor input) throws IOException { + if (input == null) { + throw new NullPointerException("input cannot be null"); + } + + final long size; + try { + Libcore.os.lseek(input.getFileDescriptor(), 0, OsConstants.SEEK_SET); + size = Libcore.os.fstat(input.getFileDescriptor()).st_size; + } catch (ErrnoException ee) { + throw new IllegalArgumentException("file descriptor not seekable"); + } + + mInput = input; + mNativeDocument = nativeOpen(mInput.getFd(), size); + mPageCount = nativeGetPageCount(mNativeDocument); + mCloseGuard.open("close"); + } + + /** + * Gets the number of pages in the document. + * + * @return The page count. + */ + public int getPageCount() { + throwIfClosed(); + return mPageCount; + } + + /** + * Removes the page with a given index. + * + * @param pageIndex The page to remove. + */ + public void removePage(int pageIndex) { + throwIfClosed(); + throwIfPageNotInDocument(pageIndex); + mPageCount = nativeRemovePage(mNativeDocument, pageIndex); + } + + /** + * Writes the PDF file to the provided destination. + * <p> + * <strong>Note:</strong> This method takes ownership of the passed in file + * descriptor and is responsible for closing it when writing completes. + * </p> + * @param output The destination. + */ + public void write(ParcelFileDescriptor output) throws IOException { + try { + throwIfClosed(); + nativeWrite(mNativeDocument, output.getFd()); + } finally { + IoUtils.closeQuietly(output); + } + } + + /** + * Closes this editor. You should not use this instance + * after this method is called. + */ + public void close() { + throwIfClosed(); + doClose(); + } + + @Override + protected void finalize() throws Throwable { + try { + mCloseGuard.warnIfOpen(); + if (mInput != null) { + doClose(); + } + } finally { + super.finalize(); + } + } + + private void doClose() { + nativeClose(mNativeDocument); + IoUtils.closeQuietly(mInput); + mInput = null; + mCloseGuard.close(); + } + + private void throwIfClosed() { + if (mInput == null) { + throw new IllegalStateException("Already closed"); + } + } + + private void throwIfPageNotInDocument(int pageIndex) { + if (pageIndex < 0 || pageIndex >= mPageCount) { + throw new IllegalArgumentException("Invalid page index"); + } + } + + private static native long nativeOpen(int fd, long size); + private static native void nativeClose(long documentPtr); + private static native int nativeGetPageCount(long documentPtr); + private static native int nativeRemovePage(long documentPtr, int pageIndex); + private static native void nativeWrite(long documentPtr, int fd); +} diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java index 1072b3c..359c294 100644 --- a/graphics/java/android/graphics/pdf/PdfRenderer.java +++ b/graphics/java/android/graphics/pdf/PdfRenderer.java @@ -239,7 +239,7 @@ public final class PdfRenderer implements AutoCloseable { } private void throwIfPageNotInDocument(int pageIndex) { - if (pageIndex >= mPageCount) { + if (pageIndex < 0 || pageIndex >= mPageCount) { throw new IllegalArgumentException("Invalid page index"); } } diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl index 60fd7f7..a93891a 100644 --- a/keystore/java/android/security/IKeyChainService.aidl +++ b/keystore/java/android/security/IKeyChainService.aidl @@ -15,6 +15,8 @@ */ package android.security; +import android.content.pm.ParceledListSlice; + /** * Caller is required to ensure that {@link KeyStore#unlock * KeyStore.unlock} was successful. @@ -32,6 +34,11 @@ interface IKeyChainService { // APIs used by Settings boolean deleteCaCertificate(String alias); boolean reset(); + ParceledListSlice getUserCaAliases(); + ParceledListSlice getSystemCaAliases(); + boolean containsCaAlias(String alias); + byte[] getEncodedCaCertificate(String alias, boolean includeDeletedSystem); + List<String> getCaCertificateChainAliases(String rootAlias, boolean includeDeletedSystem); // APIs used by KeyChainActivity void setGrant(int uid, String alias, boolean value); diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java index 0da2b99..131e689 100644 --- a/keystore/java/android/security/KeyChain.java +++ b/keystore/java/android/security/KeyChain.java @@ -397,7 +397,8 @@ public final class KeyChain { return KeyStore.getInstance().isHardwareBacked(algorithm); } - private static X509Certificate toCertificate(byte[] bytes) { + /** @hide */ + public static X509Certificate toCertificate(byte[] bytes) { if (bytes == null) { throw new IllegalArgumentException("bytes == null"); } diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 9855f71..f853d1f 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -551,9 +551,13 @@ void Caches::bindTexture(GLuint texture) { } void Caches::bindTexture(GLenum target, GLuint texture) { - if (mBoundTextures[mTextureUnit] != texture) { + if (target == GL_TEXTURE_2D) { + bindTexture(texture); + } else { + // GLConsumer directly calls glBindTexture() with + // target=GL_TEXTURE_EXTERNAL_OES, don't cache this target + // since the cached state could be stale glBindTexture(target, texture); - mBoundTextures[mTextureUnit] = texture; } } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 726b74d..7aa628c 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -431,6 +431,7 @@ private: uint32_t mFunctorsCount; + // Caches texture bindings for the GL_TEXTURE_2D target GLuint mBoundTextures[REQUIRED_TEXTURE_UNITS_COUNT]; OverdrawColorSet mOverdrawDebugColorSet; diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 25caae3..91c4aee 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -29,15 +29,15 @@ namespace android { namespace uirenderer { -Layer::Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight) +Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight) : caches(Caches::getInstance()) , renderState(renderState) - , texture(caches) { + , texture(caches) + , type(layerType) { mesh = NULL; meshElementCount = 0; cacheable = true; dirty = false; - textureLayer = false; renderTarget = GL_TEXTURE_2D; texture.width = layerWidth; texture.height = layerHeight; @@ -55,11 +55,17 @@ Layer::Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t caches.resourceCache.incrementRefcount(this); rendererLightPosDirty = true; wasBuildLayered = false; - renderState.registerLayer(this); + if (!isTextureLayer()) { + // track only non-texture layer lifecycles in renderstate, + // because texture layers are destroyed via finalizer + renderState.registerLayer(this); + } } Layer::~Layer() { - renderState.unregisterLayer(this); + if (!isTextureLayer()) { + renderState.unregisterLayer(this); + } SkSafeUnref(colorFilter); removeFbo(); deleteTexture(); diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 911b99880..36a4ed1 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -54,7 +54,12 @@ class DeferStateStruct; */ class Layer { public: - Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight); + enum Type { + kType_Texture, + kType_DisplayList, + }; + + Layer(Type type, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight); ~Layer(); static uint32_t computeIdealWidth(uint32_t layerWidth); @@ -219,11 +224,7 @@ public: } inline bool isTextureLayer() const { - return textureLayer; - } - - inline void setTextureLayer(bool textureLayer) { - this->textureLayer = textureLayer; + return type == kType_Texture; } inline SkColorFilter* getColorFilter() const { @@ -343,10 +344,9 @@ private: bool cacheable; /** - * When set to true, this layer must be treated as a texture - * layer. + * Denotes whether the layer is a DisplayList, or Texture layer. */ - bool textureLayer; + const Type type; /** * When set to true, this layer is dirty and should be cleared diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp index efa30ac..d49daf6 100644 --- a/libs/hwui/LayerCache.cpp +++ b/libs/hwui/LayerCache.cpp @@ -112,7 +112,7 @@ Layer* LayerCache::get(RenderState& renderState, const uint32_t width, const uin } else { LAYER_LOGD("Creating new layer %dx%d", entry.mWidth, entry.mHeight); - layer = new Layer(renderState, entry.mWidth, entry.mHeight); + layer = new Layer(Layer::kType_DisplayList, renderState, entry.mWidth, entry.mHeight); layer->setBlend(true); layer->setEmpty(true); layer->setFbo(0); diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index e3b0daf..103c843 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -272,9 +272,8 @@ bool LayerRenderer::resizeLayer(Layer* layer, uint32_t width, uint32_t height) { Layer* LayerRenderer::createTextureLayer(RenderState& renderState) { LAYER_RENDERER_LOGD("Creating new texture layer"); - Layer* layer = new Layer(renderState, 0, 0); + Layer* layer = new Layer(Layer::kType_Texture, renderState, 0, 0); layer->setCacheable(false); - layer->setTextureLayer(true); layer->setEmpty(true); layer->setFbo(0); layer->setAlpha(255, SkXfermode::kSrcOver_Mode); diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp index e30ac19..281ca02 100644 --- a/libs/hwui/PathTessellator.cpp +++ b/libs/hwui/PathTessellator.cpp @@ -162,14 +162,21 @@ public: } /** - * Outset the bounds of point data (for line endpoints or points) to account for AA stroke + * Outset the bounds of point data (for line endpoints or points) to account for stroke * geometry. + * + * bounds are in pre-scaled space. */ void expandBoundsForStroke(Rect* bounds) const { - float outset = halfStrokeWidth; - if (outset == 0) outset = 0.5f; - bounds->outset(outset * inverseScaleX + Vertex::GeometryFudgeFactor(), - outset * inverseScaleY + Vertex::GeometryFudgeFactor()); + if (halfStrokeWidth == 0) { + // hairline, outset by (0.5f + fudge factor) in post-scaling space + bounds->outset(fabs(inverseScaleX) * (0.5f + Vertex::GeometryFudgeFactor()), + fabs(inverseScaleY) * (0.5f + Vertex::GeometryFudgeFactor())); + } else { + // non hairline, outset by half stroke width pre-scaled, and fudge factor post scaled + bounds->outset(halfStrokeWidth + fabs(inverseScaleX) * Vertex::GeometryFudgeFactor(), + halfStrokeWidth + fabs(inverseScaleY) * Vertex::GeometryFudgeFactor()); + } } }; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index a10e70f..254492f 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -872,6 +872,8 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { handler(new (alloc) DrawLayerOp(mLayer, 0, 0), renderer.getSaveCount() - 1, properties().getClipToBounds()); } else { + const int saveCountOffset = renderer.getSaveCount() - 1; + const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); for (size_t chunkIndex = 0; chunkIndex < mDisplayListData->getChunks().size(); chunkIndex++) { const DisplayListData::Chunk& chunk = mDisplayListData->getChunks()[chunkIndex]; @@ -882,8 +884,6 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { issueOperationsOf3dChildren(kNegativeZChildren, initialTransform, zTranslatedNodes, renderer, handler); - const int saveCountOffset = renderer.getSaveCount() - 1; - const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; for (int opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { DisplayListOp *op = mDisplayListData->displayListOps[opIndex]; diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 082a158..2c805bb 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -1109,9 +1109,9 @@ public class LocationManager { * {@link #requestLocationUpdates(String, long, float, LocationListener)}. * * <p> - * Before API version 20, this method would throw {@link SecurityException} - * if the location permissions were not sufficient to use the specified - * provider. + * Before API version {@link android.os.Build.VERSION_CODES#L}, this + * method would throw {@link SecurityException} if the location permissions + * were not sufficient to use the specified provider. * * @param provider the name of the provider * @return true if the provider exists and is enabled @@ -1119,7 +1119,6 @@ public class LocationManager { * @throws IllegalArgumentException if provider is null */ public boolean isProviderEnabled(String provider) { - // STOPSHIP: finalize API version number in javadoc checkProvider(provider); try { diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java index 5a286ee..e0901d0 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -21,15 +21,24 @@ import java.io.UnsupportedEncodingException; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.location.LocationManager; +import android.location.INetInitiatedListener; +import android.telephony.TelephonyManager; +import android.telephony.PhoneNumberUtils; +import android.telephony.PhoneStateListener; import android.os.Bundle; +import android.os.RemoteException; import android.os.UserHandle; +import android.os.SystemProperties; import android.util.Log; import com.android.internal.R; import com.android.internal.telephony.GsmAlphabet; +import com.android.internal.telephony.TelephonyProperties; /** * A GPS Network-initiated Handler class used by LocationManager. @@ -45,55 +54,67 @@ public class GpsNetInitiatedHandler { // NI verify activity for bringing up UI (not used yet) public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY"; - + // string constants for defining data fields in NI Intent public static final String NI_INTENT_KEY_NOTIF_ID = "notif_id"; public static final String NI_INTENT_KEY_TITLE = "title"; public static final String NI_INTENT_KEY_MESSAGE = "message"; public static final String NI_INTENT_KEY_TIMEOUT = "timeout"; public static final String NI_INTENT_KEY_DEFAULT_RESPONSE = "default_resp"; - + // the extra command to send NI response to GpsLocationProvider public static final String NI_RESPONSE_EXTRA_CMD = "send_ni_response"; - + // the extra command parameter names in the Bundle public static final String NI_EXTRA_CMD_NOTIF_ID = "notif_id"; public static final String NI_EXTRA_CMD_RESPONSE = "response"; - + // these need to match GpsNiType constants in gps_ni.h public static final int GPS_NI_TYPE_VOICE = 1; public static final int GPS_NI_TYPE_UMTS_SUPL = 2; public static final int GPS_NI_TYPE_UMTS_CTRL_PLANE = 3; - - // these need to match GpsUserResponseType constants in gps_ni.h + public static final int GPS_NI_TYPE_EMERGENCY_SUPL = 4; + + // these need to match GpsUserResponseType constants in gps_ni.h public static final int GPS_NI_RESPONSE_ACCEPT = 1; public static final int GPS_NI_RESPONSE_DENY = 2; - public static final int GPS_NI_RESPONSE_NORESP = 3; - + public static final int GPS_NI_RESPONSE_NORESP = 3; + public static final int GPS_NI_RESPONSE_IGNORE = 4; + // these need to match GpsNiNotifyFlags constants in gps_ni.h public static final int GPS_NI_NEED_NOTIFY = 0x0001; public static final int GPS_NI_NEED_VERIFY = 0x0002; public static final int GPS_NI_PRIVACY_OVERRIDE = 0x0004; - + // these need to match GpsNiEncodingType in gps_ni.h public static final int GPS_ENC_NONE = 0; public static final int GPS_ENC_SUPL_GSM_DEFAULT = 1; public static final int GPS_ENC_SUPL_UTF8 = 2; public static final int GPS_ENC_SUPL_UCS2 = 3; public static final int GPS_ENC_UNKNOWN = -1; - + private final Context mContext; - + private final TelephonyManager mTelephonyManager; + private final PhoneStateListener mPhoneStateListener; + // parent gps location provider private final LocationManager mLocationManager; - + // configuration of notificaiton behavior private boolean mPlaySounds = false; private boolean mPopupImmediately = true; - - // Set to true if string from HAL is encoded as Hex, e.g., "3F0039" + + // read the SUPL_ES form gps.conf + private volatile boolean mIsSuplEsEnabled; + + // Set to true if the phone is having emergency call. + private volatile boolean mIsInEmergency; + + private final INetInitiatedListener mNetInitiatedListener; + + // Set to true if string from HAL is encoded as Hex, e.g., "3F0039" static private boolean mIsHexInput = true; - + public static class GpsNiNotification { public int notificationId; @@ -109,58 +130,95 @@ public class GpsNetInitiatedHandler { public int textEncoding; public Bundle extras; }; - + public static class GpsNiResponse { /* User reponse, one of the values in GpsUserResponseType */ int userResponse; /* Optional extra data to pass with the user response */ Bundle extras; }; - + + private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { + + @Override public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) { + String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); + /* + Emergency Mode is when during emergency call or in emergency call back mode. + For checking if it is during emergency call: + mIsInEmergency records if the phone is in emergency call or not. It will + be set to true when the phone is having emergency call, and then will + be set to false by mPhoneStateListener when the emergency call ends. + For checking if it is in emergency call back mode: + Emergency call back mode will be checked by reading system properties + when necessary: SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE) + */ + mIsInEmergency |= PhoneNumberUtils.isEmergencyNumber(phoneNumber); + if (DEBUG) Log.v(TAG, "ACTION_NEW_OUTGOING_CALL - " + mIsInEmergency); + } + } + }; + /** * The notification that is shown when a network-initiated notification - * (and verification) event is received. + * (and verification) event is received. * <p> * This is lazily created, so use {@link #setNINotification()}. */ private Notification mNiNotification; - - public GpsNetInitiatedHandler(Context context) { + + public GpsNetInitiatedHandler(Context context, + INetInitiatedListener netInitiatedListener, + boolean isSuplEsEnabled) { mContext = context; - mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); - } - - // Handles NI events from HAL - public void handleNiNotification(GpsNiNotification notif) - { - if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId - + " requestorId: " + notif.requestorId + " text: " + notif.text); - // Notify and verify with immediate pop-up - if (notif.needNotify && notif.needVerify && mPopupImmediately) - { - // Popup the dialog box now - openNiDialog(notif); + if (netInitiatedListener == null) { + throw new IllegalArgumentException("netInitiatedListener is null"); + } else { + mNetInitiatedListener = netInitiatedListener; } - // Notify only, or delayed pop-up (change mPopupImmediately to FALSE) - if (notif.needNotify && !notif.needVerify || - notif.needNotify && notif.needVerify && !mPopupImmediately) - { - // Show the notification + mIsSuplEsEnabled = isSuplEsEnabled; + mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); + mTelephonyManager = + (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); + + mPhoneStateListener = new PhoneStateListener() { + @Override + public void onCallStateChanged(int state, String incomingNumber) { + if (DEBUG) Log.d(TAG, "onCallStateChanged(): state is "+ state); + // listening for emergency call ends + if (state == TelephonyManager.CALL_STATE_IDLE) { + mIsInEmergency = false; + } + } + }; + mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); - // if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened - // when the user opens the notification message + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL); + mContext.registerReceiver(mBroadcastReciever, intentFilter); + } - setNiNotification(notif); - } + public void setSuplEsEnablement(boolean isEnabled) + { + mIsSuplEsEnabled = isEnabled; + } - // ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override. - if ( notif.needNotify && !notif.needVerify || - !notif.needNotify && !notif.needVerify || - notif.privacyOverride) - { - mLocationManager.sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT); + // Handles NI events from HAL + public void handleNiNotification(GpsNiNotification notif) + { + if (DEBUG) Log.d(TAG, "in handleNiNotification () :" + + " notificationId: " + notif.notificationId + + " requestorId: " + notif.requestorId + + " text: " + notif.text + + " mIsSuplEsEnabled" + mIsSuplEsEnabled); + + if (mIsSuplEsEnabled == false) { + handleNi(notif); + } else { + handleNiInEs(notif); } ////////////////////////////////////////////////////////////////////////// @@ -176,6 +234,72 @@ public class GpsNetInitiatedHandler { // } + // handle NI form HAL when SUPL_ES is disabled. + private void handleNi(GpsNiNotification notif) { + if (DEBUG) Log.d(TAG, "in handleNi () :" + + " needNotify: " + notif.needNotify + + " needVerify: " + notif.needVerify + + " privacyOverride: " + notif.privacyOverride + + " mPopupImmediately: " + mPopupImmediately); + + // legacy behaviour + if (notif.needNotify) { + // If NI does not need verify or the dialog is not requested + // to pop up immediately, the dialog box will not pop up. + if (notif.needVerify && mPopupImmediately) { + // Popup the dialog box now + openNiDialog(notif); + } else { + // Show the notification + setNiNotification(notif); + } + } + // ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; + // 3. privacy override. + if (!notif.needVerify || notif.privacyOverride) { + try { + mNetInitiatedListener.sendNiResponse(notif.notificationId, + GPS_NI_RESPONSE_ACCEPT); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in sendNiResponse"); + } + } + } + + // handle NI from HAL when the SUPL_ES is enabled + private void handleNiInEs(GpsNiNotification notif) { + + if (DEBUG) Log.d(TAG, "in handleNiInEs () :" + + " niType: " + notif.niType + + " notificationId: " + notif.notificationId); + + // UE is in emergency mode when in emergency call mode or in emergency call back mode + boolean isUEInEmergencyMode = mIsInEmergency || + Boolean.parseBoolean(SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)); + + /* + 1. When SUPL ES bit is off and UE is not in emergency mode: + Call handleNi() to do legacy behaviour. + 2. When SUPL ES bit is on and UE is in emergency mode: + Call handleNi() to do acceptance behaviour. + 3. When SUPL ES bit is off but UE is in emergency mode: + Ignore the emergency SUPL INIT. + 4. When SUPL ES bit is on but UE is not in emergency mode: + Ignore the emergency SUPL INIT. + */ + boolean isNiTypeES = (notif.niType == GPS_NI_TYPE_EMERGENCY_SUPL); + if (isNiTypeES != isUEInEmergencyMode) { + try { + mNetInitiatedListener.sendNiResponse(notif.notificationId, + GPS_NI_RESPONSE_IGNORE); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in sendNiResponse"); + } + } else { + handleNi(notif); + } + } + // Sets the NI notification. private synchronized void setNiNotification(GpsNiNotification notif) { NotificationManager notificationManager = (NotificationManager) mContext @@ -202,7 +326,7 @@ public class GpsNetInitiatedHandler { mNiNotification.defaults |= Notification.DEFAULT_SOUND; } else { mNiNotification.defaults &= ~Notification.DEFAULT_SOUND; - } + } mNiNotification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_AUTO_CANCEL; mNiNotification.tickerText = getNotifTicker(notif, mContext); @@ -230,7 +354,7 @@ public class GpsNetInitiatedHandler { mContext.startActivity(intent); } - // Construct the intent for bringing up the dialog activity, which shows the + // Construct the intent for bringing up the dialog activity, which shows the // notification and takes user input private Intent getDlgIntent(GpsNiNotification notif) { @@ -239,7 +363,7 @@ public class GpsNetInitiatedHandler { String message = getDialogMessage(notif, mContext); // directly bring up the NI activity - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class); // put data in the intent @@ -409,7 +533,7 @@ public class GpsNetInitiatedHandler { decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding), decodeString(notif.text, mIsHexInput, notif.textEncoding)); return message; - } + } // change this to configure dialog display (for verification) static public String getDialogTitle(GpsNiNotification notif, Context context) diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index 9b644f4..d7ede34 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -162,16 +162,13 @@ public final class AudioAttributes implements Parcelable { public final static int FLAG_BEACON = 0x1 << 3; /** - * @hide - * CANDIDATE FOR PUBLIC API * Flag requesting the use of an output stream supporting hardware A/V synchronization. */ - // TODO add in FLAG_ALL_PUBLIC when in public API public final static int FLAG_HW_AV_SYNC = 0x1 << 4; private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO | FLAG_BEACON | FLAG_HW_AV_SYNC; - private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED; + private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC; private int mUsage = USAGE_UNKNOWN; private int mContentType = CONTENT_TYPE_UNKNOWN; diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index e3b8985..6da3c0b 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -36,6 +36,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.ServiceManager; @@ -1959,7 +1960,42 @@ public class AudioManager { return; } - if (!querySoundEffectsEnabled()) { + if (!querySoundEffectsEnabled(Process.myUserHandle().getIdentifier())) { + return; + } + + IAudioService service = getService(); + try { + service.playSoundEffect(effectType); + } catch (RemoteException e) { + Log.e(TAG, "Dead object in playSoundEffect"+e); + } + } + + /** + * Plays a sound effect (Key clicks, lid open/close...) + * @param effectType The type of sound effect. One of + * {@link #FX_KEY_CLICK}, + * {@link #FX_FOCUS_NAVIGATION_UP}, + * {@link #FX_FOCUS_NAVIGATION_DOWN}, + * {@link #FX_FOCUS_NAVIGATION_LEFT}, + * {@link #FX_FOCUS_NAVIGATION_RIGHT}, + * {@link #FX_KEYPRESS_STANDARD}, + * {@link #FX_KEYPRESS_SPACEBAR}, + * {@link #FX_KEYPRESS_DELETE}, + * {@link #FX_KEYPRESS_RETURN}, + * {@link #FX_KEYPRESS_INVALID}, + * @param userId The current user to pull sound settings from + * NOTE: This version uses the UI settings to determine + * whether sounds are heard or not. + * @hide + */ + public void playSoundEffect(int effectType, int userId) { + if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) { + return; + } + + if (!querySoundEffectsEnabled(userId)) { return; } @@ -2006,8 +2042,9 @@ public class AudioManager { /** * Settings has an in memory cache, so this is fast. */ - private boolean querySoundEffectsEnabled() { - return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0; + private boolean querySoundEffectsEnabled(int user) { + return Settings.System.getIntForUser(mContext.getContentResolver(), + Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0; } diff --git a/media/java/android/media/CamcorderProfile.java b/media/java/android/media/CamcorderProfile.java index 8883d28..5651fc9 100644 --- a/media/java/android/media/CamcorderProfile.java +++ b/media/java/android/media/CamcorderProfile.java @@ -177,9 +177,15 @@ public class CamcorderProfile */ public static final int QUALITY_HIGH_SPEED_1080P = 2004; + /** + * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160) + * resolution. + */ + public static final int QUALITY_HIGH_SPEED_2160P = 2005; + // Start and end of high speed quality list private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW; - private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_1080P; + private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_2160P; /** * Default recording duration in seconds before the session is terminated. @@ -313,6 +319,7 @@ public class CamcorderProfile * @see #QUALITY_HIGH_SPEED_480P * @see #QUALITY_HIGH_SPEED_720P * @see #QUALITY_HIGH_SPEED_1080P + * @see #QUALITY_HIGH_SPEED_2160P */ public static CamcorderProfile get(int cameraId, int quality) { if (!((quality >= QUALITY_LIST_START && diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 675916b..1c7c9ea 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -672,6 +672,11 @@ final public class MediaCodec { super(detailMessage); mErrorCode = errorCode; mActionCode = actionCode; + + // TODO get this from codec + final String sign = errorCode < 0 ? "neg_" : ""; + mDiagnosticInfo = + "android.media.MediaCodec.error_" + sign + Math.abs(errorCode); } /** @@ -696,15 +701,28 @@ final public class MediaCodec { * Retrieve the error code associated with a CodecException. * This is opaque diagnostic information and may depend on * hardware or API level. + * + * @hide */ public int getErrorCode() { return mErrorCode; } + /** + * Retrieve a human readable diagnostic information string + * associated with the exception. DO NOT SHOW THIS TO END-USERS! + * This string will not be localized or generally comprehensible + * to end-users. + */ + public String getDiagnosticInfo() { + return mDiagnosticInfo; + } + /* Must be in sync with android_media_MediaCodec.cpp */ private final static int ACTION_TRANSIENT = 1; private final static int ACTION_RECOVERABLE = 2; + private final String mDiagnosticInfo; private final int mErrorCode; private final int mActionCode; } @@ -737,6 +755,13 @@ final public class MediaCodec { public static final int ERROR_RESOURCE_BUSY = 3; /** + * This indicates that the output protection levels supported by the + * device are not sufficient to meet the requirements set by the + * content owner in the license policy. + */ + public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4; + + /** * Retrieve the error code associated with a CryptoException */ public int getErrorCode() { diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java index 85e9b16..0dcbd65 100644 --- a/media/java/android/media/MediaCodecList.java +++ b/media/java/android/media/MediaCodecList.java @@ -118,6 +118,7 @@ final public class MediaCodecList { /** @hide */ public static MediaCodecInfo getInfoFor(String codec) { + initCodecList(); return sAllCodecInfos[findCodecByName(codec)]; } diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index ca707d8..1490732 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -188,18 +188,37 @@ public final class MediaDrm { */ public static final class MediaDrmStateException extends java.lang.IllegalStateException { private final int mErrorCode; + private final String mDiagnosticInfo; public MediaDrmStateException(int errorCode, String detailMessage) { super(detailMessage); mErrorCode = errorCode; + + // TODO get this from DRM session + final String sign = errorCode < 0 ? "neg_" : ""; + mDiagnosticInfo = + "android.media.MediaDrm.error_" + sign + Math.abs(errorCode); + } /** * Retrieve the associated error code + * + * @hide */ public int getErrorCode() { return mErrorCode; } + + /** + * Retrieve a human readable diagnostic information string + * associated with the exception. DO NOT SHOW THIS TO END-USERS! + * This string will not be localized or generally comprehensible + * to end-users. + */ + public String getDiagnosticInfo() { + return mDiagnosticInfo; + } } /** diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 9343aa4..afa0b6e 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -1929,6 +1929,7 @@ public class MediaPlayer implements SubtitleController.Listener mSubtitleController.setAnchor(anchor); } + private final Object mInbandSubtitleLock = new Object(); private SubtitleTrack[] mInbandSubtitleTracks; private int mSelectedSubtitleTrackIndex = -1; private Vector<SubtitleTrack> mOutOfBandSubtitleTracks; @@ -2036,19 +2037,21 @@ public class MediaPlayer implements SubtitleController.Listener } TrackInfo[] tracks = getInbandTrackInfo(); - SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length]; - for (int i=0; i < tracks.length; i++) { - if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) { - if (i < mInbandSubtitleTracks.length) { - inbandTracks[i] = mInbandSubtitleTracks[i]; - } else { - SubtitleTrack track = mSubtitleController.addTrack( - tracks[i].getFormat()); - inbandTracks[i] = track; + synchronized (mInbandSubtitleLock) { + SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length]; + for (int i=0; i < tracks.length; i++) { + if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) { + if (i < mInbandSubtitleTracks.length) { + inbandTracks[i] = mInbandSubtitleTracks[i]; + } else { + SubtitleTrack track = mSubtitleController.addTrack( + tracks[i].getFormat()); + inbandTracks[i] = track; + } } } + mInbandSubtitleTracks = inbandTracks; } - mInbandSubtitleTracks = inbandTracks; mSubtitleController.selectDefaultTrack(); } @@ -2224,9 +2227,9 @@ public class MediaPlayer implements SubtitleController.Listener try { Libcore.os.lseek(fd3, offset2, OsConstants.SEEK_SET); byte[] buffer = new byte[4096]; - for (int total = 0; total < length2;) { - int remain = (int)length2 - total; - int bytes = IoBridge.read(fd3, buffer, 0, Math.min(buffer.length, remain)); + for (long total = 0; total < length2;) { + int bytesToRead = (int) Math.min(buffer.length, length2 - total); + int bytes = IoBridge.read(fd3, buffer, 0, bytesToRead); if (bytes < 0) { break; } else { @@ -2358,6 +2361,18 @@ public class MediaPlayer implements SubtitleController.Listener throws IllegalStateException { // handle subtitle track through subtitle controller SubtitleTrack track = null; + synchronized (mInbandSubtitleLock) { + if (mInbandSubtitleTracks.length == 0) { + TrackInfo[] tracks = getInbandTrackInfo(); + mInbandSubtitleTracks = new SubtitleTrack[tracks.length]; + for (int i=0; i < tracks.length; i++) { + if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) { + mInbandSubtitleTracks[i] = mSubtitleController.addTrack(tracks[i].getFormat()); + } + } + } + } + if (index < mInbandSubtitleTracks.length) { track = mInbandSubtitleTracks[index]; } else if (index < mInbandSubtitleTracks.length + mOutOfBandSubtitleTracks.size()) { @@ -3256,9 +3271,7 @@ public class MediaPlayer implements SubtitleController.Listener if (DEBUG) Log.d(TAG, "scheduleUpdate"); int i = registerListener(listener); - if (mStopped) { - scheduleNotification(NOTIFY_STOP, 0 /* delay */); - } else { + if (!mStopped) { mTimes[i] = 0; scheduleNotification(NOTIFY_TIME, 0 /* delay */); } diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java index 37adb8c..f82dbe0 100644 --- a/media/java/android/media/SubtitleController.java +++ b/media/java/android/media/SubtitleController.java @@ -275,7 +275,7 @@ public class SubtitleController { mSelectedTrack.getFormat().getInteger( MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) { show(); - } else { + } else if (mSelectedTrack != null && !mSelectedTrack.isTimedText()) { hide(); } mVisibilityIsExplicit = false; diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 8cb039a..2c38697 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -191,11 +191,8 @@ public final class MediaSession { return; } if (mCallback != null) { - if (mCallback.mCallback == callback) { - Log.w(TAG, "Tried to set same callback, ignoring"); - return; - } - // We're changing callbacks, clear the session from the old one. + // We're updating the callback, clear the session from the old + // one. mCallback.mCallback.mSession = null; } if (handler == null) { diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index aa196a9..06e40c5 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -467,10 +467,7 @@ public class MediaSessionLegacyHelper { mSessions.remove(mPi); } else if (mCb == null) { mCb = new SessionCallback(); - Handler handler = null; - if (Looper.myLooper() == null) { - handler = new Handler(Looper.getMainLooper()); - } + Handler handler = new Handler(Looper.getMainLooper()); mSession.setCallback(mCb, handler); } } diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java index 7d1c7c6..b4ec2b3 100644 --- a/media/java/android/media/tv/TvContentRating.java +++ b/media/java/android/media/tv/TvContentRating.java @@ -247,6 +247,10 @@ import java.util.Objects; * <td>TV content rating system for Iceland</td> * </tr> * <tr> + * <td>JP_TV</td> + * <td>TV content rating system for Japan</td> + * </tr> + * <tr> * <td>KR_TV</td> * <td>TV content rating system for South Korea</td> * </tr> @@ -912,6 +916,23 @@ import java.util.Objects; * <td>Programs suitable for ages 18 and older</td> * </tr> * <tr> + * <td valign="top" rowspan="4">JP_TV</td> + * <td>JP_TV_G</td> + * <td>General, suitable for all ages</td> + * </tr> + * <tr> + * <td>JP_TV_PG12</td> + * <td>Parental guidance requested for young people under 12 years</td> + * </tr> + * <tr> + * <td>JP_TV_R15</td> + * <td>For persons aged 15 and above only</td> + * </tr> + * <tr> + * <td>JP_TV_R18</td> + * <td>For persons aged 18 and above only</td> + * </tr> + * <tr> * <td valign="top" rowspan="5">KR_TV</td> * <td>KR_TV_ALL</td> * <td>Appropriate for all ages</td> diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index f1e1099..1cf589d 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -62,6 +62,7 @@ static struct CryptoErrorCodes { jint cryptoErrorNoKey; jint cryptoErrorKeyExpired; jint cryptoErrorResourceBusy; + jint cryptoErrorInsufficientOutputProtection; } gCryptoErrorCodes; static struct CodecActionCodes { @@ -756,6 +757,9 @@ static void throwCryptoException(JNIEnv *env, status_t err, const char *msg) { case ERROR_DRM_RESOURCE_BUSY: err = gCryptoErrorCodes.cryptoErrorResourceBusy; break; + case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: + err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection; + break; default: /* Other negative DRM error codes go out as is. */ break; } @@ -1434,6 +1438,11 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) { gCryptoErrorCodes.cryptoErrorResourceBusy = env->GetStaticIntField(clazz.get(), field); + field = env->GetStaticFieldID(clazz.get(), "ERROR_INSUFFICIENT_OUTPUT_PROTECTION", "I"); + CHECK(field != NULL); + gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection = + env->GetStaticIntField(clazz.get(), field); + clazz.reset(env->FindClass("android/media/MediaCodec$CodecException")); CHECK(clazz.get() != NULL); field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I"); diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk index c4a55d1..27d1b23 100644 --- a/packages/PrintSpooler/Android.mk +++ b/packages/PrintSpooler/Android.mk @@ -19,7 +19,9 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_SRC_FILES += src/com/android/printspooler/renderer/IPdfRenderer.aidl +LOCAL_SRC_FILES += \ + src/com/android/printspooler/renderer/IPdfRenderer.aidl \ + src/com/android/printspooler/renderer/IPdfEditor.aidl LOCAL_PACKAGE_NAME := PrintSpooler diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml index 9efda2f..adff596 100644 --- a/packages/PrintSpooler/AndroidManifest.xml +++ b/packages/PrintSpooler/AndroidManifest.xml @@ -54,7 +54,7 @@ </service> <service - android:name=".renderer.PdfRendererService" + android:name=".renderer.PdfManipulationService" android:isolatedProcess="true"> </service> diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java index a581e8a..1d8261b 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java @@ -37,7 +37,7 @@ import android.util.Log; import android.view.View; import com.android.internal.annotations.GuardedBy; import com.android.printspooler.renderer.IPdfRenderer; -import com.android.printspooler.renderer.PdfRendererService; +import com.android.printspooler.renderer.PdfManipulationService; import com.android.printspooler.util.BitmapSerializeUtils; import dalvik.system.CloseGuard; import libcore.io.IoUtils; @@ -490,7 +490,8 @@ public final class PageContentRepository { new AsyncTask<Void, Void, Integer>() { @Override protected void onPreExecute() { - Intent intent = new Intent(mContext, PdfRendererService.class); + Intent intent = new Intent(PdfManipulationService.ACTION_GET_RENDERER); + intent.setClass(mContext, PdfManipulationService.class); mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE); } @@ -555,7 +556,7 @@ public final class PageContentRepository { callback.run(); } } - }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null); + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); } public void destroy() { diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl new file mode 100644 index 0000000..b450ccb --- /dev/null +++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfEditor.aidl @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.printspooler.renderer; + +import android.os.ParcelFileDescriptor; +import android.print.PageRange; + +/** + * Interface for communication with a remote pdf editor. + */ +interface IPdfEditor { + int openDocument(in ParcelFileDescriptor source); + void removePages(in PageRange[] pages); + void write(in ParcelFileDescriptor destination); + void closeDocument(); +} diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl index 1fba2b1..8e595d7 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl +++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl @@ -29,5 +29,4 @@ interface IPdfRenderer { oneway void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight, in PrintAttributes attributes, in ParcelFileDescriptor destination); oneway void closeDocument(); - oneway void writePages(in PageRange[] pages); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java index 4d02c01..62716b2 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java @@ -23,6 +23,7 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Rect; +import android.graphics.pdf.PdfEditor; import android.graphics.pdf.PdfRenderer; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -32,15 +33,21 @@ import android.print.PrintAttributes; import android.print.PrintAttributes.Margins; import android.util.Log; import android.view.View; +import com.android.printspooler.util.PageRangeUtils; import libcore.io.IoUtils; import com.android.printspooler.util.BitmapSerializeUtils; import java.io.IOException; /** - * Service for rendering PDF documents in an isolated process. + * Service for manipulation of PDF documents in an isolated process. */ -public final class PdfRendererService extends Service { - private static final String LOG_TAG = "PdfRendererService"; +public final class PdfManipulationService extends Service { + public static final String ACTION_GET_RENDERER = + "com.android.printspooler.renderer.ACTION_GET_RENDERER"; + public static final String ACTION_GET_EDITOR = + "com.android.printspooler.renderer.ACTION_GET_EDITOR"; + + private static final String LOG_TAG = "PdfManipulationService"; private static final boolean DEBUG = false; private static final int MILS_PER_INCH = 1000; @@ -48,7 +55,18 @@ public final class PdfRendererService extends Service { @Override public IBinder onBind(Intent intent) { - return new PdfRendererImpl(); + String action = intent.getAction(); + switch (action) { + case ACTION_GET_RENDERER: { + return new PdfRendererImpl(); + } + case ACTION_GET_EDITOR: { + return new PdfEditorImpl(); + } + default: { + throw new IllegalArgumentException("Invalid intent action:" + action); + } + } } private final class PdfRendererImpl extends IPdfRenderer.Stub { @@ -60,15 +78,17 @@ public final class PdfRendererService extends Service { @Override public int openDocument(ParcelFileDescriptor source) throws RemoteException { synchronized (mLock) { - throwIfOpened(); - if (DEBUG) { - Log.i(LOG_TAG, "openDocument()"); - } try { + throwIfOpened(); + if (DEBUG) { + Log.i(LOG_TAG, "openDocument()"); + } mRenderer = new PdfRenderer(source); return mRenderer.getPageCount(); - } catch (IOException ioe) { - throw new RemoteException("Cannot open file"); + } catch (IOException|IllegalStateException e) { + IoUtils.closeQuietly(source); + Log.e(LOG_TAG, "Cannot open file", e); + throw new RemoteException(e.toString()); } } } @@ -108,7 +128,7 @@ public final class PdfRendererService extends Service { } matrix.postScale(displayScale, displayScale); - Configuration configuration = PdfRendererService.this.getResources() + Configuration configuration = PdfManipulationService.this.getResources() .getConfiguration(); if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { matrix.postTranslate(bitmapWidth - srcWidthPts * displayScale, 0); @@ -147,24 +167,13 @@ public final class PdfRendererService extends Service { synchronized (mLock) { throwIfNotOpened(); if (DEBUG) { - Log.i(LOG_TAG, "openDocument()"); + Log.i(LOG_TAG, "closeDocument()"); } mRenderer.close(); mRenderer = null; } } - @Override - public void writePages(PageRange[] pages) { - synchronized (mLock) { - throwIfNotOpened(); - if (DEBUG) { - Log.i(LOG_TAG, "writePages()"); - } - // TODO: Implement dropping undesired pages. - } - } - private Bitmap getBitmapForSize(int width, int height) { if (mBitmap != null) { if (mBitmap.getWidth() == width && mBitmap.getHeight() == height) { @@ -191,6 +200,91 @@ public final class PdfRendererService extends Service { } } + private final class PdfEditorImpl extends IPdfEditor.Stub { + private final Object mLock = new Object(); + + private PdfEditor mEditor; + + @Override + public int openDocument(ParcelFileDescriptor source) throws RemoteException { + synchronized (mLock) { + try { + throwIfOpened(); + if (DEBUG) { + Log.i(LOG_TAG, "openDocument()"); + } + mEditor = new PdfEditor(source); + return mEditor.getPageCount(); + } catch (IOException|IllegalStateException e) { + IoUtils.closeQuietly(source); + Log.e(LOG_TAG, "Cannot open file", e); + throw new RemoteException(e.toString()); + } + } + } + + @Override + public void removePages(PageRange[] ranges) { + synchronized (mLock) { + throwIfNotOpened(); + if (DEBUG) { + Log.i(LOG_TAG, "removePages()"); + } + + ranges = PageRangeUtils.normalize(ranges); + + final int rangeCount = ranges.length; + for (int i = rangeCount - 1; i >= 0; i--) { + PageRange range = ranges[i]; + for (int j = range.getEnd(); j >= range.getStart(); j--) { + mEditor.removePage(j); + } + } + } + } + + @Override + public void write(ParcelFileDescriptor destination) throws RemoteException { + synchronized (mLock) { + try { + throwIfNotOpened(); + if (DEBUG) { + Log.i(LOG_TAG, "write()"); + } + mEditor.write(destination); + } catch (IOException | IllegalStateException e) { + IoUtils.closeQuietly(destination); + Log.e(LOG_TAG, "Error writing PDF to file.", e); + throw new RemoteException(e.toString()); + } + } + } + + @Override + public void closeDocument() { + synchronized (mLock) { + throwIfNotOpened(); + if (DEBUG) { + Log.i(LOG_TAG, "closeDocument()"); + } + mEditor.close(); + mEditor = null; + } + } + + private void throwIfOpened() { + if (mEditor != null) { + throw new IllegalStateException("Already opened"); + } + } + + private void throwIfNotOpened() { + if (mEditor == null) { + throw new IllegalStateException("Not opened"); + } + } + } + private static int pointsFromMils(int mils) { return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH); } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 535081f..c517f2d 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -23,6 +23,7 @@ import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; @@ -30,9 +31,12 @@ import android.content.res.Configuration; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.RemoteException; import android.print.IPrintDocumentAdapter; import android.print.PageRange; import android.print.PrintAttributes; @@ -74,6 +78,8 @@ import com.android.printspooler.model.PrintSpoolerProvider; import com.android.printspooler.model.PrintSpoolerService; import com.android.printspooler.model.RemotePrintDocument; import com.android.printspooler.model.RemotePrintDocument.RemotePrintDocumentInfo; +import com.android.printspooler.renderer.IPdfEditor; +import com.android.printspooler.renderer.PdfManipulationService; import com.android.printspooler.util.MediaSizeUtils; import com.android.printspooler.util.MediaSizeUtils.MediaSizeComparator; import com.android.printspooler.util.PageRangeUtils; @@ -81,8 +87,15 @@ import com.android.printspooler.util.PrintOptionUtils; import com.android.printspooler.widget.PrintContentView; import com.android.printspooler.widget.PrintContentView.OptionsStateChangeListener; import com.android.printspooler.widget.PrintContentView.OptionsStateController; +import libcore.io.IoUtils; +import libcore.io.Streams; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -186,6 +199,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private ImageView mPrintButton; private ProgressMessageController mProgressMessageController; + private MutexFileProvider mFileProvider; private MediaSizeComparator mMediaSizeComparator; @@ -257,9 +271,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat setTitle(R.string.print_dialog); setContentView(R.layout.print_activity); - final MutexFileProvider fileProvider; try { - fileProvider = new MutexFileProvider( + mFileProvider = new MutexFileProvider( PrintSpoolerService.generateFileForPrintJob( PrintActivity.this, mPrintJob.getId())); } catch (IOException ioe) { @@ -268,12 +281,13 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } mPrintPreviewController = new PrintPreviewController(PrintActivity.this, - fileProvider); + mFileProvider); mPrintedDocument = new RemotePrintDocument(PrintActivity.this, IPrintDocumentAdapter.Stub.asInterface(documentAdapter), - fileProvider, new RemotePrintDocument.DocumentObserver() { + mFileProvider, new RemotePrintDocument.DocumentObserver() { @Override public void onDestroy() { + setState(STATE_PRINT_CANCELED); finish(); } }, PrintActivity.this); @@ -369,7 +383,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat @Override public void onRequestContentUpdate() { if (canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } } @@ -386,7 +400,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat @Override public void onActionPerformed() { if (mState == STATE_UPDATE_FAILED - && canUpdateDocument() && updateDocument(true, true)) { + && canUpdateDocument() && updateDocument(true)) { ensurePreviewUiShown(); setState(STATE_CONFIGURING); updateOptionsUi(); @@ -557,14 +571,13 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (resultCode == RESULT_OK && data != null) { setState(STATE_PRINT_COMPLETED); updateOptionsUi(); - Uri uri = data.getData(); - mPrintedDocument.writeContent(getContentResolver(), uri); + final Uri uri = data.getData(); // Calling finish here does not invoke lifecycle callbacks but we // update the print job in onPause if finishing, hence post a message. mDestinationSpinner.post(new Runnable() { @Override public void run() { - finish(); + shredPagesAndFinish(uri); } }); } else if (resultCode == RESULT_CANCELED) { @@ -708,7 +721,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat // Update the content if needed. if (canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } } @@ -840,7 +853,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (mCurrentPrinter == mDestinationSpinnerAdapter.getPdfPrinter()) { startCreateDocumentActivity(); } else { - finish(); + shredPagesAndFinish(null); } } @@ -893,7 +906,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat attributes.setMinMargins(defaults.getMinMargins()); } - private boolean updateDocument(boolean preview, boolean clearLastError) { + private boolean updateDocument(boolean clearLastError) { if (!clearLastError && mPrintedDocument.hasUpdateError()) { return false; } @@ -902,6 +915,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPrintedDocument.clearUpdateError(); } + final boolean preview = mState != STATE_PRINT_CONFIRMED; final PageRange[] pages; if (preview) { pages = mPrintPreviewController.getRequestedPages(); @@ -959,7 +973,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mPrintPreviewController.closeOptions(); if (canUpdateDocument()) { - updateDocument(false, false); + updateDocument(false); } if (!mPrintedDocument.isUpdating()) { @@ -1433,7 +1447,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat if (mCurrentPrinter.equals(printer)) { setState(STATE_CONFIGURING); if (canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } ensurePreviewUiShown(); updateOptionsUi(); @@ -1492,6 +1506,18 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat return true; } + private void shredPagesAndFinish(final Uri writeToUri) { + new PageShredder(this, mPrintJob, mFileProvider, new Runnable() { + @Override + public void run() { + if (writeToUri != null) { + mPrintedDocument.writeContent(getContentResolver(), writeToUri); + } + finish(); + } + }).shred(); + } + private final class SpinnerItem<T> { final T value; final CharSequence label; @@ -1942,7 +1968,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat || (becameActive && hasCapab) || (isActive && gotCapab)); if (updateNeeded && canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } updateOptionsUi(); @@ -2033,7 +2059,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } if (canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } updateOptionsUi(); @@ -2158,7 +2184,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat updateOptionsUi(); if (hadErrors && canUpdateDocument()) { - updateDocument(true, false); + updateDocument(false); } } } @@ -2198,4 +2224,176 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat updateOptionsUi(); } } + + private static final class PageShredder implements ServiceConnection { + private static final String TEMP_FILE_PREFIX = "print_job"; + private static final String TEMP_FILE_EXTENSION = ".pdf"; + + private final Context mContext; + + private final MutexFileProvider mFileProvider; + + private final PrintJobInfo mPrintJob; + + private final PageRange[] mPagesToShred; + + private final Runnable mCallback; + + public PageShredder(Context context, PrintJobInfo printJob, + MutexFileProvider fileProvider, Runnable callback) { + mContext = context; + mPrintJob = printJob; + mFileProvider = fileProvider; + mCallback = callback; + mPagesToShred = computePagesToShred(mPrintJob); + } + + public void shred() { + // If we have only the pages we want, done. + if (mPagesToShred.length <= 0) { + mCallback.run(); + return; + } + + // Bind to the manipulation service and the work + // will be performed upon connection to the service. + Intent intent = new Intent(PdfManipulationService.ACTION_GET_EDITOR); + intent.setClass(mContext, PdfManipulationService.class); + mContext.bindService(intent, this, Context.BIND_AUTO_CREATE); + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + final IPdfEditor editor = IPdfEditor.Stub.asInterface(service); + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... params) { + try { + // It's OK to access the data members as they are + // final and this code is the last one to touch + // them as shredding is the very last step, so the + // UI is not interactive at this point. + shredPages(editor); + updatePrintJob(); + } finally { + mContext.unbindService(PageShredder.this); + mCallback.run(); + } + return null; + } + }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + /* do nothing */ + } + + private void shredPages(IPdfEditor editor) { + File tempFile = null; + ParcelFileDescriptor src = null; + ParcelFileDescriptor dst = null; + InputStream in = null; + OutputStream out = null; + try { + File jobFile = mFileProvider.acquireFile(null); + src = ParcelFileDescriptor.open(jobFile, ParcelFileDescriptor.MODE_READ_WRITE); + + // Open the document. + editor.openDocument(src); + + // We passed the fd over IPC, close this one. + src.close(); + + // Drop the pages. + editor.removePages(mPagesToShred); + + // Write the modified PDF to a temp file. + tempFile = File.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_EXTENSION, + mContext.getCacheDir()); + dst = ParcelFileDescriptor.open(tempFile, ParcelFileDescriptor.MODE_READ_WRITE); + editor.write(dst); + dst.close(); + + // Close the document. + editor.closeDocument(); + + // Copy the temp file over the print job file. + jobFile.delete(); + in = new FileInputStream(tempFile); + out = new FileOutputStream(jobFile); + Streams.copy(in, out); + } catch (IOException|RemoteException e) { + Log.e(LOG_TAG, "Error dropping pages", e); + } finally { + IoUtils.closeQuietly(src); + IoUtils.closeQuietly(dst); + IoUtils.closeQuietly(in); + IoUtils.closeQuietly(out); + if (tempFile != null) { + tempFile.delete(); + } + } + } + + private void updatePrintJob() { + // Update the print job pages. + final int newPageCount = PageRangeUtils.getNormalizedPageCount( + mPrintJob.getPages(), 0); + mPrintJob.setPages(new PageRange[]{PageRange.ALL_PAGES}); + + // Update the print job document info. + PrintDocumentInfo oldDocInfo = mPrintJob.getDocumentInfo(); + PrintDocumentInfo newDocInfo = new PrintDocumentInfo + .Builder(oldDocInfo.getName()) + .setContentType(oldDocInfo.getContentType()) + .setPageCount(newPageCount) + .build(); + mPrintJob.setDocumentInfo(newDocInfo); + } + + private static PageRange[] computePagesToShred(PrintJobInfo printJob) { + List<PageRange> rangesToShred = new ArrayList<>(); + PageRange previousRange = null; + + final int pageCount = printJob.getDocumentInfo().getPageCount(); + + PageRange[] printedPages = printJob.getPages(); + final int rangeCount = printedPages.length; + for (int i = 0; i < rangeCount; i++) { + PageRange range = PageRangeUtils.asAbsoluteRange(printedPages[i], pageCount); + + if (previousRange == null) { + final int startPageIdx = 0; + final int endPageIdx = range.getStart() - 1; + if (startPageIdx <= endPageIdx) { + PageRange removedRange = new PageRange(startPageIdx, endPageIdx); + rangesToShred.add(removedRange); + } + } else { + final int startPageIdx = previousRange.getEnd() + 1; + final int endPageIdx = range.getStart() - 1; + if (startPageIdx <= endPageIdx) { + PageRange removedRange = new PageRange(startPageIdx, endPageIdx); + rangesToShred.add(removedRange); + } + } + + if (i == rangeCount - 1) { + final int startPageIdx = range.getEnd() + 1; + final int endPageIdx = printJob.getDocumentInfo().getPageCount() - 1; + if (startPageIdx <= endPageIdx) { + PageRange removedRange = new PageRange(startPageIdx, endPageIdx); + rangesToShred.add(removedRange); + } + } + + previousRange = range; + } + + PageRange[] result = new PageRange[rangesToShred.size()]; + rangesToShred.toArray(result); + return result; + } + } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java index a25e05e..5d858ca 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java @@ -185,8 +185,10 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba public void run() { // At this point the other end will write to the file, hence // we have to close it and reopen after the write completes. - Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE); - mHandler.enqueueOperation(operation); + if (mPageAdapter.isOpened()) { + Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE); + mHandler.enqueueOperation(operation); + } } }); } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 17593fe..6d08970 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -70,7 +70,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 110; + private static final int DATABASE_VERSION = 111; private Context mContext; private int mUserHandle; @@ -1770,6 +1770,24 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 110; } + if (upgradeVersion < 111) { + // reset ringer mode, so it doesn't force zen mode to follow + if (mUserHandle == UserHandle.USER_OWNER) { + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)" + + " VALUES(?,?);"); + loadSetting(stmt, Settings.Global.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + } + upgradeVersion = 111; + } + // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml new file mode 100644 index 0000000..a571cbc --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_bounce.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal"> + + <alpha android:fromAlpha="1.0" android:toAlpha="0.6" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/accelerate_cubic" + android:duration="133"/> + + <translate android:fromYDelta="0" android:toYDelta="10%" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/accelerate_cubic" + android:duration="350"/> + + <scale android:fromXScale="1.0" android:toXScale="0.9" + android:fromYScale="1.0" android:toYScale="0.9" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:pivotX="50%p" android:pivotY="50%p" + android:interpolator="@android:interpolator/fast_out_slow_in" + android:duration="350" /> + + <alpha android:fromAlpha="1.0" android:toAlpha="1.6666666666" + android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true" + android:interpolator="@android:interpolator/decelerate_cubic" + android:startOffset="350" + android:duration="133"/> + + <translate android:fromYDelta="0%" android:toYDelta="-8.8888888888%" + android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true" + android:interpolator="@android:interpolator/decelerate_cubic" + android:startOffset="350" + android:duration="350"/> + + <scale android:fromXScale="1.0" android:toXScale="1.1111111111" + android:fromYScale="1.0" android:toYScale="1.1111111111" + android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true" + android:pivotX="50%p" android:pivotY="50%p" + android:interpolator="@android:interpolator/decelerate_cubic" + android:startOffset="350" + android:duration="350" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml new file mode 100644 index 0000000..f0fd684 --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_source.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal"> + + <alpha android:fromAlpha="1.0" android:toAlpha="0.6" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/accelerate_cubic" + android:duration="150"/> + + <scale android:fromXScale="1.0" android:toXScale="0.9" + android:fromYScale="1.0" android:toYScale="0.9" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:pivotX="50%p" android:pivotY="50%p" + android:interpolator="@android:interpolator/fast_out_slow_in" + android:duration="300" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml new file mode 100644 index 0000000..170ac82 --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_next_affiliated_task_target.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top"> + + <translate android:fromYDelta="110%" android:toYDelta="0%" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/decelerate_quint" + android:startOffset="50" + android:duration="250" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml new file mode 100644 index 0000000..46045ac --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_bounce.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top"> + + <translate android:fromYDelta="0%" android:toYDelta="10%" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/decelerate_quint" + android:duration="300" /> + + <translate android:fromYDelta="10%" android:toYDelta="0%" + android:fillEnabled="true" android:fillBefore="false" android:fillAfter="true" + android:interpolator="@android:interpolator/accelerate_quint" + android:startOffset="300" + android:duration="300" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml new file mode 100644 index 0000000..ad5341b --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_source.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="top"> + + <translate android:fromYDelta="0%" android:toYDelta="110%" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/accelerate_quint" + android:duration="300" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml new file mode 100644 index 0000000..7687f02 --- /dev/null +++ b/packages/SystemUI/res/anim/recents_launch_prev_affiliated_task_target.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:background="#ff000000" android:shareInterpolator="false" android:zAdjustment="normal"> + + <alpha android:fromAlpha="0.6" android:toAlpha="1.0" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/decelerate_cubic" + android:startOffset="75" + android:duration="150"/> + + <scale android:fromXScale="0.9" android:toXScale="1.0" + android:fromYScale="0.9" android:toYScale="1.0" + android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true" + android:interpolator="@android:interpolator/linear_out_slow_in" + android:pivotX="50%p" android:pivotY="50%p" + android:startOffset="75" + android:duration="225" /> +</set>
\ No newline at end of file diff --git a/packages/SystemUI/res/drawable/recents_button_bg.xml b/packages/SystemUI/res/drawable/recents_button_bg.xml index a4cb088..7456365 100644 --- a/packages/SystemUI/res/drawable/recents_button_bg.xml +++ b/packages/SystemUI/res/drawable/recents_button_bg.xml @@ -15,4 +15,5 @@ --> <ripple xmlns:android="http://schemas.android.com/apk/res/android" - android:color="?android:attr/colorControlHighlight" />
\ No newline at end of file + android:color="#40ffffff"> +</ripple> diff --git a/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml new file mode 100644 index 0000000..7ca8c40 --- /dev/null +++ b/packages/SystemUI/res/drawable/stat_sys_vpn_ic.xml @@ -0,0 +1,24 @@ +<!-- +Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="17.0dp" + android:height="17.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M12.700000,10.000000c-0.800000,-2.300000 -3.000000,-4.000000 -5.700000,-4.000000c-3.300000,0.000000 -6.000000,2.700000 -6.000000,6.000000s2.700000,6.000000 6.000000,6.000000c2.600000,0.000000 4.800000,-1.700000 5.700000,-4.000000L17.000000,14.000000l0.000000,4.000000l4.000000,0.000000l0.000000,-4.000000l2.000000,0.000000l0.000000,-4.000000L12.700000,10.000000zM7.000000,14.000000c-1.100000,0.000000 -2.000000,-0.900000 -2.000000,-2.000000c0.000000,-1.100000 0.900000,-2.000000 2.000000,-2.000000s2.000000,0.900000 2.000000,2.000000C9.000000,13.100000 8.100000,14.000000 7.000000,14.000000z"/> +</vector> diff --git a/packages/SystemUI/res/layout/notification_public_default.xml b/packages/SystemUI/res/layout/notification_public_default.xml new file mode 100644 index 0000000..acfc4bb --- /dev/null +++ b/packages/SystemUI/res/layout/notification_public_default.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> + +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:internal="http://schemas.android.com/apk/prv/res/android" + android:id="@+id/status_bar_latest_event_content" + android:layout_width="match_parent" + android:layout_height="64dp" + internal:layout_minHeight="64dp" + internal:layout_maxHeight="64dp" + > + <ImageView android:id="@+id/icon" + android:layout_width="40dp" + android:layout_height="40dp" + android:layout_marginTop="12dp" + android:layout_marginStart="12dp" + android:layout_marginEnd="12dp" + android:scaleType="centerInside" + /> + <DateTimeView android:id="@+id/time" + android:textAppearance="@android:style/TextAppearance.Material.Notification.Time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:layout_alignParentEnd="true" + android:layout_alignBaseline="@id/title" + android:singleLine="true" + android:gravity="center" + android:paddingStart="8dp" + android:visibility="gone" + /> + <TextView android:id="@+id/title" + android:textAppearance="@android:style/TextAppearance.Material.Notification.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_toEndOf="@id/icon" + android:layout_toStartOf="@id/time" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <ImageView android:id="@+id/profile_badge_line3" + android:layout_width="@*android:dimen/notification_badge_size" + android:layout_height="@*android:dimen/notification_badge_size" + android:layout_below="@id/title" + android:layout_marginStart="4dp" + android:layout_marginEnd="8dp" + android:layout_alignParentEnd="true" + android:scaleType="fitCenter" + android:visibility="gone" + /> + <TextView android:id="@+id/text" + android:textAppearance="@android:style/TextAppearance.Material.Notification" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignStart="@id/title" + android:layout_below="@id/title" + android:layout_toStartOf="@id/profile_badge_line3" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> +</RelativeLayout> diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml index 1ef9cad..4b68e77 100644 --- a/packages/SystemUI/res/layout/recents_empty.xml +++ b/packages/SystemUI/res/layout/recents_empty.xml @@ -23,6 +23,6 @@ android:textSize="16sp" android:textColor="#ffffffff" android:text="@string/recents_empty_message" - android:fontFamily="sans-serif-light" + android:fontFamily="sans-serif" android:background="#80000000" android:visibility="gone" />
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml index 347c8a9..5889c55 100644 --- a/packages/SystemUI/res/layout/signal_cluster_view.xml +++ b/packages/SystemUI/res/layout/signal_cluster_view.xml @@ -25,6 +25,13 @@ android:gravity="center_vertical" android:orientation="horizontal" > + <ImageView + android:id="@+id/vpn" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingEnd="6dp" + android:src="@drawable/stat_sys_vpn_ic" + /> <FrameLayout android:id="@+id/wifi_combo" android:layout_height="wrap_content" @@ -36,6 +43,12 @@ android:layout_width="wrap_content" /> </FrameLayout> + <View + android:id="@+id/wifi_signal_spacer" + android:layout_width="4dp" + android:layout_height="4dp" + android:visibility="gone" + /> <FrameLayout android:layout_height="wrap_content" android:layout_width="wrap_content" diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml index 6b829e5..e9d86d6 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_row.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml @@ -52,9 +52,10 @@ android:paddingStart="8dp" /> - <include - layout="@layout/notification_guts" - android:id="@+id/notification_guts" + <ViewStub + android:layout="@layout/notification_guts" + android:id="@+id/notification_guts_stub" + android:inflatedId="@+id/notification_guts" android:layout_width="match_parent" android:layout_height="match_parent" /> diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml index 5aafb66..83477c0 100644 --- a/packages/SystemUI/res/values-sw600dp/config.xml +++ b/packages/SystemUI/res/values-sw600dp/config.xml @@ -33,6 +33,8 @@ <!-- Set to true to enable the user switcher on the keyguard. --> <bool name="config_keyguardUserSwitcher">true</bool> - <!-- Transposes the recents layout in landscape. --> - <bool name="recents_transpose_layout_with_orientation">false</bool> + <!-- Transposes the search bar layout in landscape. --> + <bool name="recents_has_transposed_search_bar">true</bool> + <!-- Transposes the nav bar in landscape (only used for purposes of layout). --> + <bool name="recents_has_transposed_nav_bar">false</bool> </resources> diff --git a/packages/SystemUI/res/values-sw720dp/config.xml b/packages/SystemUI/res/values-sw720dp/config.xml index d8bb8d7d..fbeadcd 100644 --- a/packages/SystemUI/res/values-sw720dp/config.xml +++ b/packages/SystemUI/res/values-sw720dp/config.xml @@ -39,5 +39,10 @@ <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow card. --> <integer name="keyguard_max_notification_count">5</integer> + + <!-- Transposes the search bar layout in landscape. --> + <bool name="recents_has_transposed_search_bar">false</bool> + <!-- Transposes the nav bar in landscape (only used for purposes of layout). --> + <bool name="recents_has_transposed_nav_bar">false</bool> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 0e18979..5a1c318 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -134,10 +134,13 @@ <integer name="recents_animate_task_exit_to_home_duration">225</integer> <!-- The min animation duration for animating the task bar out. --> <integer name="recents_animate_task_bar_exit_duration">125</integer> + <!-- The animation delay for animating the first task in. This should roughly be the animation + duration of the transition in to recents from home. --> + <integer name="recents_animate_task_enter_from_home_delay">150</integer> <!-- The min animation duration for animating the task in when transitioning from home. --> <integer name="recents_animate_task_enter_from_home_duration">275</integer> <!-- The animation stagger to apply to each task animation when transitioning from home. --> - <integer name="recents_animate_task_enter_from_home_delay">10</integer> + <integer name="recents_animate_task_enter_from_home_stagger_delay">10</integer> <!-- The short duration when animating in/out the lock to app button. --> <integer name="recents_animate_lock_to_app_button_short_duration">150</integer> <!-- The long duration when animating in/out the lock to app button. --> @@ -152,8 +155,10 @@ <integer name="recents_max_task_stack_view_dim">96</integer> <!-- The delay to enforce between each alt-tab key press. --> <integer name="recents_alt_tab_key_delay">200</integer> - <!-- Transposes the recents layout in landscape. --> - <bool name="recents_transpose_layout_with_orientation">true</bool> + <!-- Transposes the search bar layout in landscape. --> + <bool name="recents_has_transposed_search_bar">true</bool> + <!-- Transposes the nav bar in landscape (only used for purposes of layout). --> + <bool name="recents_has_transposed_nav_bar">true</bool> <!-- Whether to enable KeyguardService or not --> <bool name="config_enableKeyguardService">true</bool> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 8cd4ce6..4495318 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -476,4 +476,12 @@ <fraction name="battery_subpixel_smoothing_right">0%</fraction> <dimen name="battery_margin_bottom">0dp</dimen> + + <!-- Extra padding between the mobile data type icon and the strength indicator when the data + type icon is wide. --> + <dimen name="wide_type_icon_start_padding">2dp</dimen> + + <!-- Extra padding between the mobile data type icon and the strength indicator when the data + type icon is wide for the tile in quick settings. --> + <dimen name="wide_type_icon_start_padding_qs">3dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 23d9748..0445fe8 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -736,9 +736,6 @@ <!-- Shows when people have clicked at the right edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] --> <string name="camera_hint">Swipe left for camera</string> - <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] --> - <string name="zen_mode_forever">Indefinitely</string> - <!-- Interruption level: None. [CHAR LIMIT=20] --> <string name="interruption_level_none">None</string> @@ -798,18 +795,12 @@ <!-- Notification when resuming an existing guest session: Action that continues with the current session [CHAR LIMIT=35] --> <string name="guest_wipe_session_dontwipe">Yes, continue</string> + <!-- Title for add user confirmation dialog [CHAR LIMIT=30] --> + <string name="user_add_user_title" msgid="2108112641783146007">Add new user?</string> - <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] --> - <plurals name="zen_mode_duration_minutes"> - <item quantity="one">For one minute</item> - <item quantity="other">For %d minutes</item> - </plurals> + <!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] --> + <string name="user_add_user_message_short" msgid="1511354412249044381">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string> - <!-- Zen mode condition: time duration in hours. [CHAR LIMIT=NONE] --> - <plurals name="zen_mode_duration_hours"> - <item quantity="one">For one hour</item> - <item quantity="other">For %d hours</item> - </plurals> <!-- Battery saver notification title. [CHAR LIMIT=60]--> <string name="battery_saver_notification_title">Battery saver is on</string> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 8d35eb0..50ba68e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -17,6 +17,7 @@ package com.android.systemui.keyguard; import android.app.Activity; +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.PendingIntent; @@ -487,7 +488,7 @@ public class KeyguardViewMediator extends SystemUI { mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext); mLockPatternUtils = new LockPatternUtils(mContext); - mLockPatternUtils.setCurrentUser(UserHandle.USER_OWNER); + mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser()); // Assume keyguard is showing (unless it's disabled) until we know for sure... mShowing = (mUpdateMonitor.isDeviceProvisioned() || mLockPatternUtils.isSecure()) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java index 377fcc0..a9fdc86 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDualTileLabel.java @@ -23,7 +23,6 @@ import android.text.TextUtils; import android.text.TextUtils.TruncateAt; import android.view.Gravity; import android.view.View; -import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -41,7 +40,7 @@ import java.util.Objects; * truncate. * Second line: ellipsis if necessary */ -public class QSDualTileLabel extends FrameLayout { +public class QSDualTileLabel extends LinearLayout { private final Context mContext; private final TextView mFirstLine; @@ -54,12 +53,13 @@ public class QSDualTileLabel extends FrameLayout { public QSDualTileLabel(Context context) { super(context); mContext = context; + setOrientation(LinearLayout.VERTICAL); mHorizontalPaddingPx = mContext.getResources() .getDimensionPixelSize(R.dimen.qs_dual_tile_padding_horizontal); mFirstLine = initTextView(); - mFirstLine.setPadding(mHorizontalPaddingPx, 0, 0, 0); + mFirstLine.setPadding(mHorizontalPaddingPx, 0, mHorizontalPaddingPx, 0); final LinearLayout firstLineLayout = new LinearLayout(mContext); firstLineLayout.setPadding(0, 0, 0, 0); firstLineLayout.setOrientation(LinearLayout.HORIZONTAL); @@ -70,13 +70,13 @@ public class QSDualTileLabel extends FrameLayout { mFirstLineCaret.setScaleType(ImageView.ScaleType.MATRIX); mFirstLineCaret.setClickable(false); firstLineLayout.addView(mFirstLineCaret); - addView(firstLineLayout, newFrameLayoutParams()); + addView(firstLineLayout, newLinearLayoutParams()); mSecondLine = initTextView(); mSecondLine.setPadding(mHorizontalPaddingPx, 0, mHorizontalPaddingPx, 0); mSecondLine.setEllipsize(TruncateAt.END); mSecondLine.setVisibility(GONE); - addView(mSecondLine, newFrameLayoutParams()); + addView(mSecondLine, newLinearLayoutParams()); addOnLayoutChangeListener(new OnLayoutChangeListener() { @Override @@ -89,7 +89,7 @@ public class QSDualTileLabel extends FrameLayout { }); } - private static LayoutParams newFrameLayoutParams() { + private static LayoutParams newLinearLayoutParams() { final LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER_HORIZONTAL; @@ -104,6 +104,7 @@ public class QSDualTileLabel extends FrameLayout { lp.topMargin = h * 4 / 5; mSecondLine.setLayoutParams(lp); mFirstLine.setMinHeight(h); + mFirstLine.setPadding(mHorizontalPaddingPx, 0, 0, 0); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java index 2b071cc..cb685fe 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java @@ -373,6 +373,7 @@ public abstract class QSTile<TState extends State> implements Listenable { public boolean activityOut; public int overlayIconId; public boolean filter; + public boolean isOverlayIconWide; @Override public boolean copyTo(State other) { @@ -380,13 +381,15 @@ public abstract class QSTile<TState extends State> implements Listenable { final boolean changed = o.enabled != enabled || o.connected != connected || o.activityIn != activityIn || o.activityOut != activityOut - || o.overlayIconId != overlayIconId; + || o.overlayIconId != overlayIconId + || o.isOverlayIconWide != isOverlayIconWide; o.enabled = enabled; o.connected = connected; o.activityIn = activityIn; o.activityOut = activityOut; o.overlayIconId = overlayIconId; o.filter = filter; + o.isOverlayIconWide = isOverlayIconWide; return super.copyTo(other) || changed; } @@ -399,6 +402,7 @@ public abstract class QSTile<TState extends State> implements Listenable { rt.insert(rt.length() - 1, ",activityOut=" + activityOut); rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId); rt.insert(rt.length() - 1, ",filter=" + filter); + rt.insert(rt.length() - 1, ",wideOverlayIcon=" + isOverlayIconWide); return rt; } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java index e6175d2..8d7edb9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java @@ -230,7 +230,7 @@ public class QSTileView extends ViewGroup { final int w = MeasureSpec.getSize(widthMeasureSpec); final int h = MeasureSpec.getSize(heightMeasureSpec); final int iconSpec = exactly(mIconSizePx); - mIcon.measure(iconSpec, iconSpec); + mIcon.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.AT_MOST), iconSpec); labelView().measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.AT_MOST)); if (mDual) { mDivider.measure(widthMeasureSpec, exactly(mDivider.getLayoutParams().height)); diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java index 0ecdeaa..cfcd74e 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java @@ -37,11 +37,16 @@ public final class SignalTileView extends QSTileView { private ImageView mIn; private ImageView mOut; + private int mWideOverlayIconStartPadding; + public SignalTileView(Context context) { super(context); mIn = addTrafficView(R.drawable.ic_qs_signal_in); mOut = addTrafficView(R.drawable.ic_qs_signal_out); + + mWideOverlayIconStartPadding = context.getResources().getDimensionPixelSize( + R.dimen.wide_type_icon_start_padding_qs); } private ImageView addTrafficView(int icon) { @@ -106,6 +111,11 @@ public final class SignalTileView extends QSTileView { } else { mOverlay.setVisibility(GONE); } + if (s.overlayIconId > 0 && s.isOverlayIconWide) { + mSignal.setPaddingRelative(mWideOverlayIconStartPadding, 0, 0, 0); + } else { + mSignal.setPaddingRelative(0, 0, 0, 0); + } Drawable drawable = mSignal.getDrawable(); if (state.autoMirrorDrawable && drawable != null) { drawable.setAutoMirrored(true); @@ -122,10 +132,9 @@ public final class SignalTileView extends QSTileView { view.animate() .setDuration(visible ? SHORT_DURATION : DEFAULT_DURATION) .alpha(newAlpha) - .withLayer() .start(); } else { view.setAlpha(newAlpha); } } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index 8743207..359a259 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -23,10 +23,8 @@ import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; import com.android.systemui.R; -import com.android.systemui.qs.DataUsageGraph; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.QSTileView; import com.android.systemui.qs.SignalTileView; @@ -34,8 +32,6 @@ import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.statusbar.policy.NetworkController.DataUsageInfo; import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback; -import java.text.DecimalFormat; - /** Quick settings tile: Cellular **/ public class CellularTile extends QSTile<QSTile.SignalState> { private static final Intent CELLULAR_SETTINGS = new Intent().setComponent(new ComponentName( @@ -95,6 +91,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { : !cb.enabled || cb.airplaneModeEnabled ? R.drawable.ic_qs_signal_disabled : cb.mobileSignalIconId > 0 ? cb.mobileSignalIconId : R.drawable.ic_qs_signal_no_signal; + state.isOverlayIconWide = cb.isDataTypeIconWide; state.autoMirrorDrawable = !cb.noSim; state.overlayIconId = cb.enabled && (cb.dataTypeIconId > 0) && !cb.wifiConnected ? cb.dataTypeIconId @@ -142,6 +139,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { boolean activityOut; String enabledDesc; boolean noSim; + boolean isDataTypeIconWide; } private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() { @@ -162,7 +160,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> { int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, boolean noSim) { + String dataTypeContentDescriptionId, String description, boolean noSim, + boolean isDataTypeIconWide) { final CallbackInfo info = new CallbackInfo(); // TODO pool? info.enabled = enabled; info.wifiEnabled = mWifiEnabled; @@ -176,6 +175,7 @@ public class CellularTile extends QSTile<QSTile.SignalState> { info.activityOut = activityOut; info.enabledDesc = description; info.noSim = noSim; + info.isDataTypeIconWide = isDataTypeIconWide; refreshState(info); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java index 4fc2ee4..0985812 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java @@ -206,7 +206,8 @@ public class WifiTile extends QSTile<QSTile.SignalState> { int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, boolean noSim) { + String dataTypeContentDescriptionId, String description, boolean noSim, + boolean isDataTypeIconWide) { // noop } diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index 5fa9fa4..787de4e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -139,7 +139,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // Notify recents to hide itself Intent intent = new Intent(ACTION_HIDE_RECENTS_ACTIVITY); intent.setPackage(mContext.getPackageName()); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(EXTRA_TRIGGERED_FROM_ALT_TAB, triggeredFromAltTab); intent.putExtra(EXTRA_TRIGGERED_FROM_HOME_KEY, triggeredFromHomeKey); mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); @@ -190,10 +191,14 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta Task.TaskKey toTaskKey; if (showNextTask) { toTaskKey = group.getNextTaskInGroup(task); - // XXX: We will actually set the appropriate launch animations here + launchOpts = ActivityOptions.makeCustomAnimation(mContext, + R.anim.recents_launch_next_affiliated_task_target, + R.anim.recents_launch_next_affiliated_task_source); } else { toTaskKey = group.getPrevTaskInGroup(task); - // XXX: We will actually set the appropriate launch animations here + launchOpts = ActivityOptions.makeCustomAnimation(mContext, + R.anim.recents_launch_prev_affiliated_task_target, + R.anim.recents_launch_prev_affiliated_task_source); } if (toTaskKey != null) { toTask = stack.findTaskWithId(toTaskKey.id); @@ -204,7 +209,11 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // Return early if there is no next task if (toTask == null) { - // XXX: We will actually show a bounce animation here + if (showNextTask) { + // XXX: Show the next-task bounce animation + } else { + // XXX: Show the prev-task bounce animation + } return; } @@ -243,8 +252,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy); mConfig.updateOnConfigurationChange(); mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mStatusBarHeight, - mNavBarWidth, mTaskStackBounds); - if (mConfig.isLandscape && mConfig.transposeRecentsLayoutWithOrientation) { + (mConfig.hasTransposedNavBar ? mNavBarWidth : 0), mTaskStackBounds); + if (mConfig.isLandscape && mConfig.hasTransposedNavBar) { mSystemInsets.set(0, mStatusBarHeight, mNavBarWidth, 0); } else { mSystemInsets.set(0, mStatusBarHeight, 0, mNavBarHeight); @@ -316,7 +325,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // Notify recents to toggle itself Intent intent = new Intent(ACTION_TOGGLE_RECENTS_ACTIVITY); intent.setPackage(mContext.getPackageName()); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT); mLastToggleTime = System.currentTimeMillis(); return; @@ -590,7 +600,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // Send the broadcast to notify Recents that the animation has started Intent intent = new Intent(ACTION_START_ENTER_ANIMATION); intent.setPackage(mContext.getPackageName()); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, fallbackReceiver, null, Activity.RESULT_CANCELED, null, null); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 5d8181c..ed5c126 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -57,7 +57,8 @@ public class RecentsConfiguration { /** Layout */ boolean isLandscape; - boolean transposeRecentsLayoutWithOrientation; + boolean hasTransposedSearchBar; + boolean hasTransposedNavBar; /** Loading */ public int maxNumTasksToLoad; @@ -74,8 +75,9 @@ public class RecentsConfiguration { public float taskStackOverscrollPct; /** Task view animation and styles */ - public int taskViewEnterFromHomeDuration; public int taskViewEnterFromHomeDelay; + public int taskViewEnterFromHomeDuration; + public int taskViewEnterFromHomeStaggerDelay; public int taskViewExitToHomeDuration; public int taskViewRemoveAnimDuration; public int taskViewRemoveAnimTranslationXPx; @@ -173,8 +175,8 @@ public class RecentsConfiguration { // Layout isLandscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; - transposeRecentsLayoutWithOrientation = - res.getBoolean(R.bool.recents_transpose_layout_with_orientation); + hasTransposedSearchBar = res.getBoolean(R.bool.recents_has_transposed_search_bar); + hasTransposedNavBar = res.getBoolean(R.bool.recents_has_transposed_nav_bar); // Insets displayRect.set(0, 0, dm.widthPixels, dm.heightPixels); @@ -209,10 +211,12 @@ public class RecentsConfiguration { taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding); // Task view animation and styles - taskViewEnterFromHomeDuration = - res.getInteger(R.integer.recents_animate_task_enter_from_home_duration); taskViewEnterFromHomeDelay = res.getInteger(R.integer.recents_animate_task_enter_from_home_delay); + taskViewEnterFromHomeDuration = + res.getInteger(R.integer.recents_animate_task_enter_from_home_duration); + taskViewEnterFromHomeStaggerDelay = + res.getInteger(R.integer.recents_animate_task_enter_from_home_stagger_delay); taskViewExitToHomeDuration = res.getInteger(R.integer.recents_animate_task_exit_to_home_duration); taskViewRemoveAnimDuration = @@ -326,13 +330,12 @@ public class RecentsConfiguration { /** Returns whether the nav bar scrim should be visible. */ public boolean hasNavBarScrim() { // Only show the scrim if we have recent tasks, and if the nav bar is not transposed - return !launchedWithNoRecentTasks && - (!transposeRecentsLayoutWithOrientation || !isLandscape); + return !launchedWithNoRecentTasks && (!hasTransposedNavBar || !isLandscape); } /** Returns whether the current layout is horizontal. */ public boolean hasHorizontalLayout() { - return isLandscape && transposeRecentsLayoutWithOrientation; + return isLandscape && hasTransposedSearchBar; } /** @@ -343,7 +346,7 @@ public class RecentsConfiguration { Rect taskStackBounds) { Rect searchBarBounds = new Rect(); getSearchBarBounds(windowWidth, windowHeight, topInset, searchBarBounds); - if (isLandscape && transposeRecentsLayoutWithOrientation) { + if (isLandscape && hasTransposedSearchBar) { // In landscape, the search bar appears on the left taskStackBounds.set(searchBarBounds.right, topInset, windowWidth - rightInset, windowHeight); } else { @@ -364,7 +367,7 @@ public class RecentsConfiguration { searchBarSize = 0; } - if (isLandscape && transposeRecentsLayoutWithOrientation) { + if (isLandscape && hasTransposedSearchBar) { // In landscape, the search bar appears on the left searchBarSpaceBounds.set(0, topInset, searchBarSize, windowHeight); } else { diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index 887cbac..bbd0a0d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -56,6 +56,7 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.WindowManager; +import android.view.accessibility.AccessibilityManager; import com.android.systemui.recents.Constants; import java.io.IOException; @@ -73,6 +74,7 @@ public class SystemServicesProxy { final static BitmapFactory.Options sBitmapOptions; + AccessibilityManager mAccm; ActivityManager mAm; IActivityManager mIam; AppWidgetManager mAwm; @@ -97,6 +99,7 @@ public class SystemServicesProxy { /** Private constructor */ public SystemServicesProxy(Context context) { + mAccm = AccessibilityManager.getInstance(context); mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mIam = ActivityManagerNative.getDefault(); mAwm = AppWidgetManager.getInstance(context); @@ -442,6 +445,15 @@ public class SystemServicesProxy { } /** + * Returns whether touch exploration is currently enabled. + */ + public boolean isTouchExplorationEnabled() { + if (mAccm == null) return false; + + return mAccm.isEnabled() && mAccm.isTouchExplorationEnabled(); + } + + /** * Returns a global setting. */ public int getGlobalSetting(Context context, String setting) { 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 dbed136..895b9d1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -22,11 +22,15 @@ import android.graphics.Rect; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import com.android.systemui.R; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.DozeTrigger; +import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsPackageMonitor; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; @@ -67,6 +71,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal DebugOverlayView mDebugOverlay; Rect mTaskStackBounds = new Rect(); int mFocusedTaskIndex = -1; + int mPrevAccessibilityFocusedIndex = -1; // Optimizations int mStackViewsAnimationDuration; @@ -244,6 +249,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /** Synchronizes the views with the model */ boolean synchronizeStackViewsWithModel() { if (mStackViewsDirty) { + RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); + SystemServicesProxy ssp = loader.getSystemServicesProxy(); + // Get all the task transforms ArrayList<Task> tasks = mStack.getTasks(); float stackScroll = mStackScroller.getStackScroll(); @@ -293,6 +301,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Animate the task into place tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex), mStackViewsAnimationDuration); + + // Request accessibility focus on the next view if we removed the task + // that previously held accessibility focus + childCount = getChildCount(); + if (childCount > 0 && ssp.isTouchExplorationEnabled()) { + TaskView atv = (TaskView) getChildAt(childCount - 1); + int indexOfTask = mStack.indexOfTask(atv.getTask()); + if (mPrevAccessibilityFocusedIndex != indexOfTask) { + tv.requestAccessibilityFocus(); + mPrevAccessibilityFocusedIndex = indexOfTask; + } + } } // Reset the request-synchronize params @@ -432,6 +452,22 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } @Override + public void onInitializeAccessibilityEvent(AccessibilityEvent event) { + super.onInitializeAccessibilityEvent(event); + int childCount = getChildCount(); + if (childCount > 0) { + TaskView backMostTask = (TaskView) getChildAt(0); + TaskView frontMostTask = (TaskView) getChildAt(childCount - 1); + event.setFromIndex(mStack.indexOfTask(backMostTask.getTask())); + event.setToIndex(mStack.indexOfTask(frontMostTask.getTask())); + event.setContentDescription(frontMostTask.getTask().activityLabel); + } + event.setItemCount(mStack.getTaskCount()); + event.setScrollY(mStackScroller.mScroller.getCurrY()); + event.setMaxScrollY(mStackScroller.progressToScrollRange(mLayoutAlgorithm.mMaxScrollP)); + } + + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mTouchHandler.onInterceptTouchEvent(ev); } @@ -447,6 +483,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Synchronize the views synchronizeStackViewsWithModel(); clipTaskViews(); + // Notify accessibility + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SCROLLED); } /** Computes the stack and task rects */ @@ -623,6 +661,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mStartEnterAnimationCompleted = true; // Start dozing mUIDozeTrigger.startDozing(); + // Focus the first view if accessibility is enabled + RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); + SystemServicesProxy ssp = loader.getSystemServicesProxy(); + int childCount = getChildCount(); + if (childCount > 0 && ssp.isTouchExplorationEnabled()) { + TaskView tv = ((TaskView) getChildAt(childCount - 1)); + tv.requestAccessibilityFocus(); + mPrevAccessibilityFocusedIndex = mStack.indexOfTask(tv.getTask()); + } } }); } @@ -812,6 +859,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal public void prepareViewToEnterPool(TaskView tv) { Task task = tv.getTask(); + // Clear the accessibility focus for that view + if (tv.isAccessibilityFocused()) { + tv.clearAccessibilityFocus(); + } + // Report that this tasks's data is no longer being used RecentsTaskLoader.getInstance().unloadTaskData(task); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 49aa52b..4563597 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -284,7 +284,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, float scaledWindowInsetTop = (int) (taskScale * windowInsetTop); float scaledTranslationY = taskRect.top + transform.translationY - (scaledWindowInsetTop + scaledYOffset); - startDelay = mConfig.taskViewEnterFromHomeDelay; + startDelay = mConfig.taskViewEnterFromHomeStaggerDelay; // Animate the top clip mViewBounds.animateClipTop(windowInsetTop, duration, @@ -410,8 +410,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, } else if (mConfig.launchedFromHome) { // Animate the tasks up int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1); - int delay = mConfig.taskBarEnterAnimDelay + - frontIndex * mConfig.taskViewEnterFromHomeDelay; + int delay = mConfig.taskViewEnterFromHomeDelay + + frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay; if (Constants.DebugFlags.App.EnableShadows) { animate().translationZ(transform.translationZ); } @@ -840,7 +840,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, @Override public void onClick(final View v) { final TaskView tv = this; - final boolean delayViewClick = (v != this); + final boolean delayViewClick = (v != this) && (v != mActionButtonView); if (delayViewClick) { // We purposely post the handler delayed to allow for the touch feedback to draw postDelayed(new Runnable() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 1c4556f..907a13f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -39,6 +39,7 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; @@ -68,8 +69,10 @@ import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.view.ViewStub; import android.view.WindowManager; import android.view.WindowManagerGlobal; +import android.view.accessibility.AccessibilityManager; import android.view.animation.AnimationUtils; import android.widget.DateTimeView; import android.widget.ImageView; @@ -91,6 +94,7 @@ import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.policy.HeadsUpNotificationView; +import com.android.systemui.statusbar.policy.PreviewInflater; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import java.util.ArrayList; @@ -159,6 +163,7 @@ public abstract class BaseStatusBar extends SystemUI implements final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>(); protected int mLayoutDirection = -1; // invalid + protected AccessibilityManager mAccessibilityManager; private Locale mLocale; private float mFontScale; @@ -260,10 +265,12 @@ public abstract class BaseStatusBar extends SystemUI implements final boolean isActivity = pendingIntent.isActivity(); if (isActivity) { final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); + final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity( + mContext, pendingIntent.getIntent(), mCurrentUserId); dismissKeyguardThenExecute(new OnDismissAction() { @Override public boolean onDismiss() { - if (keyguardShowing) { + if (keyguardShowing && !afterKeyguardGone) { try { ActivityManagerNative.getDefault() .keyguardWaitingForActivityDrawn(); @@ -277,7 +284,7 @@ public abstract class BaseStatusBar extends SystemUI implements } boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent); - overrideActivityPendingAppTransition(keyguardShowing); + overrideActivityPendingAppTransition(keyguardShowing && !afterKeyguardGone); // close the shade if it was open if (handled) { @@ -287,7 +294,7 @@ public abstract class BaseStatusBar extends SystemUI implements // Wait for activity start. return handled; } - }, false /* afterKeyguardGone */); + }, afterKeyguardGone); return true; } else { return super.onClickHandler(view, pendingIntent, fillInIntent); @@ -438,6 +445,9 @@ public abstract class BaseStatusBar extends SystemUI implements mNotificationData = new NotificationData(this); + mAccessibilityManager = (AccessibilityManager) + mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); + mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); @@ -678,19 +688,11 @@ public abstract class BaseStatusBar extends SystemUI implements protected void applyColorsAndBackgrounds(StatusBarNotification sbn, NotificationData.Entry entry) { - PackageManager pmUser = getPackageManagerForUser( - entry.notification.getUser().getIdentifier()); - int version = 0; - try { - ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0); - version = info.targetSdkVersion; - } catch (NameNotFoundException ex) { - Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex); - } if (entry.expanded.getId() != com.android.internal.R.id.status_bar_latest_event_content) { // Using custom RemoteViews - if (version >= Build.VERSION_CODES.GINGERBREAD && version < Build.VERSION_CODES.L) { + if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD + && entry.targetSdk < Build.VERSION_CODES.L) { entry.row.setShowingLegacyBackground(true); entry.legacy = true; } @@ -706,7 +708,7 @@ public abstract class BaseStatusBar extends SystemUI implements } if (entry.icon != null) { - if (version >= Build.VERSION_CODES.L) { + if (entry.targetSdk >= Build.VERSION_CODES.L) { entry.icon.setColorFilter(mContext.getResources().getColor(android.R.color.white)); } else { entry.icon.setColorFilter(null); @@ -763,17 +765,95 @@ public abstract class BaseStatusBar extends SystemUI implements }, false /* afterKeyguardGone */); } + private void inflateGuts(ExpandableNotificationRow row) { + ViewStub stub = (ViewStub) row.findViewById(R.id.notification_guts_stub); + if (stub != null) { + stub.inflate(); + } + final StatusBarNotification sbn = row.getStatusBarNotification(); + PackageManager pmUser = getPackageManagerForUser( + sbn.getUser().getIdentifier()); + row.setTag(sbn.getPackageName()); + final View guts = row.findViewById(R.id.notification_guts); + final String pkg = sbn.getPackageName(); + String appname = pkg; + Drawable pkgicon = null; + int appUid = -1; + try { + final ApplicationInfo info = pmUser.getApplicationInfo(pkg, + PackageManager.GET_UNINSTALLED_PACKAGES + | PackageManager.GET_DISABLED_COMPONENTS); + if (info != null) { + appname = String.valueOf(pmUser.getApplicationLabel(info)); + pkgicon = pmUser.getApplicationIcon(info); + appUid = info.uid; + } + } catch (NameNotFoundException e) { + // app is gone, just show package name and generic icon + pkgicon = pmUser.getDefaultActivityIcon(); + } + ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(pkgicon); + ((DateTimeView) row.findViewById(R.id.timestamp)).setTime(sbn.getPostTime()); + ((TextView) row.findViewById(R.id.pkgname)).setText(appname); + final View settingsButton = guts.findViewById(R.id.notification_inspect_item); + final View appSettingsButton + = guts.findViewById(R.id.notification_inspect_app_provided_settings); + if (appUid >= 0) { + final int appUidF = appUid; + settingsButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + startAppNotificationSettingsActivity(pkg, appUidF); + } + }); + + final Intent appSettingsQueryIntent + = new Intent(Intent.ACTION_MAIN) + .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES) + .setPackage(pkg); + List<ResolveInfo> infos = pmUser.queryIntentActivities(appSettingsQueryIntent, 0); + if (infos.size() > 0) { + appSettingsButton.setVisibility(View.VISIBLE); + appSettingsButton.setContentDescription( + mContext.getResources().getString( + R.string.status_bar_notification_app_settings_title, + appname + )); + final Intent appSettingsLaunchIntent = new Intent(appSettingsQueryIntent) + .setClassName(pkg, infos.get(0).activityInfo.name); + appSettingsButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + startAppOwnNotificationSettingsActivity(appSettingsLaunchIntent, + sbn.getId(), + sbn.getTag(), + appUidF); + } + }); + } else { + appSettingsButton.setVisibility(View.GONE); + } + } else { + settingsButton.setVisibility(View.GONE); + appSettingsButton.setVisibility(View.GONE); + } + + } + protected SwipeHelper.LongPressListener getNotificationLongClicker() { return new SwipeHelper.LongPressListener() { @Override public boolean onLongPress(View v, int x, int y) { dismissPopups(); + if (!(v instanceof ExpandableNotificationRow)) { + return false; + } if (v.getWindowToken() == null) { Log.e(TAG, "Trying to show notification guts, but not attached to window"); return false; } + inflateGuts((ExpandableNotificationRow) v); + // Assume we are a status_bar_notification_row final NotificationGuts guts = (NotificationGuts) v.findViewById( R.id.notification_guts); @@ -1189,67 +1269,6 @@ public abstract class BaseStatusBar extends SystemUI implements row.setExpansionLogger(this, entry.notification.getKey()); } - // the notification inspector (see SwipeHelper.setLongPressListener) - row.setTag(sbn.getPackageName()); - final View guts = row.findViewById(R.id.notification_guts); - final String pkg = entry.notification.getPackageName(); - String appname = pkg; - Drawable pkgicon = null; - int appUid = -1; - try { - final ApplicationInfo info = pmUser.getApplicationInfo(pkg, - PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS); - if (info != null) { - appname = String.valueOf(pmUser.getApplicationLabel(info)); - pkgicon = pmUser.getApplicationIcon(info); - appUid = info.uid; - } - } catch (NameNotFoundException e) { - // app is gone, just show package name and generic icon - pkgicon = pmUser.getDefaultActivityIcon(); - } - ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(pkgicon); - ((DateTimeView) row.findViewById(R.id.timestamp)).setTime(entry.notification.getPostTime()); - ((TextView) row.findViewById(R.id.pkgname)).setText(appname); - final View settingsButton = guts.findViewById(R.id.notification_inspect_item); - final View appSettingsButton - = guts.findViewById(R.id.notification_inspect_app_provided_settings); - if (appUid >= 0) { - final int appUidF = appUid; - settingsButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - startAppNotificationSettingsActivity(pkg, appUidF); - } - }); - - final Intent appSettingsQueryIntent - = new Intent(Intent.ACTION_MAIN) - .addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES) - .setPackage(pkg); - List<ResolveInfo> infos = pmUser.queryIntentActivities(appSettingsQueryIntent, 0); - if (infos.size() > 0) { - appSettingsButton.setVisibility(View.VISIBLE); - appSettingsButton.setContentDescription( - mContext.getResources().getString( - R.string.status_bar_notification_app_settings_title, - appname - )); - final Intent appSettingsLaunchIntent = new Intent(appSettingsQueryIntent) - .setClassName(pkg, infos.get(0).activityInfo.name); - appSettingsButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - startAppOwnNotificationSettingsActivity(appSettingsLaunchIntent, - sbn.getId(), - sbn.getTag(), - appUidF); - } - }); - } - } else { - settingsButton.setVisibility(View.GONE); - appSettingsButton.setVisibility(View.GONE); - } - workAroundBadLayerDrawableOpacity(row); View vetoButton = updateNotificationVetoButton(row, sbn); vetoButton.setContentDescription(mContext.getString( @@ -1319,15 +1338,23 @@ public abstract class BaseStatusBar extends SystemUI implements } } + // Extract target SDK version. + try { + ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0); + entry.targetSdk = info.targetSdkVersion; + } catch (NameNotFoundException ex) { + Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex); + } + if (publicViewLocal == null) { // Add a basic notification template publicViewLocal = LayoutInflater.from(mContext).inflate( - com.android.internal.R.layout.notification_template_material_base, + R.layout.notification_public_default, expandedPublic, false); publicViewLocal.setIsRootNamespace(true); expandedPublic.setContractedChild(publicViewLocal); - final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title); + final TextView title = (TextView) publicViewLocal.findViewById(R.id.title); try { title.setText(pmUser.getApplicationLabel( pmUser.getApplicationInfo(entry.notification.getPackageName(), 0))); @@ -1335,10 +1362,9 @@ public abstract class BaseStatusBar extends SystemUI implements title.setText(entry.notification.getPackageName()); } - final ImageView icon = (ImageView) publicViewLocal.findViewById( - com.android.internal.R.id.icon); + final ImageView icon = (ImageView) publicViewLocal.findViewById(R.id.icon); final ImageView profileBadge = (ImageView) publicViewLocal.findViewById( - com.android.internal.R.id.profile_badge_line3); + R.id.profile_badge_line3); final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(), entry.notification.getUser(), @@ -1349,12 +1375,17 @@ public abstract class BaseStatusBar extends SystemUI implements Drawable iconDrawable = StatusBarIconView.getIcon(mContext, ic); icon.setImageDrawable(iconDrawable); - if (mNotificationColorUtil.isGrayscaleIcon(iconDrawable)) { + if (entry.targetSdk >= Build.VERSION_CODES.L + || mNotificationColorUtil.isGrayscaleIcon(iconDrawable)) { icon.setBackgroundResource( com.android.internal.R.drawable.notification_icon_legacy_bg); int padding = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.notification_large_icon_circle_padding); icon.setPadding(padding, padding, padding, padding); + if (sbn.getNotification().color != Notification.COLOR_DEFAULT) { + icon.getBackground().setColorFilter( + sbn.getNotification().color, PorterDuff.Mode.SRC_ATOP); + } } if (profileBadge != null) { @@ -1369,16 +1400,13 @@ public abstract class BaseStatusBar extends SystemUI implements } final View privateTime = contentViewLocal.findViewById(com.android.internal.R.id.time); + final DateTimeView time = (DateTimeView) publicViewLocal.findViewById(R.id.time); if (privateTime != null && privateTime.getVisibility() == View.VISIBLE) { - final View timeStub = publicViewLocal.findViewById(com.android.internal.R.id.time); - timeStub.setVisibility(View.VISIBLE); - final DateTimeView dateTimeView = (DateTimeView) - publicViewLocal.findViewById(com.android.internal.R.id.time); - dateTimeView.setTime(entry.notification.getNotification().when); + time.setVisibility(View.VISIBLE); + time.setTime(entry.notification.getNotification().when); } - final TextView text = (TextView) publicViewLocal.findViewById( - com.android.internal.R.id.text); + final TextView text = (TextView) publicViewLocal.findViewById(R.id.text); if (text != null) { text.setText(R.string.notification_hidden_text); text.setTextAppearance(mContext, @@ -1418,7 +1446,7 @@ public abstract class BaseStatusBar extends SystemUI implements row.setUserExpanded(userExpanded); } row.setUserLocked(userLocked); - + row.setStatusBarNotification(entry.notification); return true; } @@ -1440,6 +1468,9 @@ public abstract class BaseStatusBar extends SystemUI implements public void onClick(final View v) { final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); + final boolean afterKeyguardGone = mIntent.isActivity() + && PreviewInflater.wouldLaunchResolverActivity(mContext, mIntent.getIntent(), + mCurrentUserId); dismissKeyguardThenExecute(new OnDismissAction() { public boolean onDismiss() { if (mIsHeadsUp) { @@ -1448,7 +1479,7 @@ public abstract class BaseStatusBar extends SystemUI implements AsyncTask.execute(new Runnable() { @Override public void run() { - if (keyguardShowing) { + if (keyguardShowing && !afterKeyguardGone) { try { ActivityManagerNative.getDefault() .keyguardWaitingForActivityDrawn(); @@ -1472,7 +1503,8 @@ public abstract class BaseStatusBar extends SystemUI implements // TODO: Dismiss Keyguard. } if (mIntent.isActivity()) { - overrideActivityPendingAppTransition(keyguardShowing); + overrideActivityPendingAppTransition(keyguardShowing + && !afterKeyguardGone); } } @@ -1490,7 +1522,7 @@ public abstract class BaseStatusBar extends SystemUI implements return mIntent != null && mIntent.isActivity(); } - }, false /* afterKeyguardGone */); + }, afterKeyguardGone); } } @@ -1625,7 +1657,7 @@ public abstract class BaseStatusBar extends SystemUI implements } } boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification); - if ((isLockscreenPublicMode() && !showOnKeyguard) || + if ((isLockscreenPublicMode() && !mShowLockscreenNotifications) || (onKeyguard && (visibleNotifications >= maxKeyguardNotifications || !showOnKeyguard))) { entry.row.setVisibility(View.GONE); @@ -1776,7 +1808,7 @@ public abstract class BaseStatusBar extends SystemUI implements oldEntry.notification.getNotification().tickerText); final boolean shouldInterrupt = shouldInterrupt(notification); - final boolean alertAgain = alertAgain(oldEntry); + final boolean alertAgain = alertAgain(oldEntry, n); boolean updateSuccessful = false; if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged) { @@ -1911,9 +1943,6 @@ public abstract class BaseStatusBar extends SystemUI implements : null; // Reapply the RemoteViews - if (entry.row != null) { - entry.row.resetHeight(); - } contentView.reapply(mContext, entry.expanded, mOnClickHandler); if (bigContentView != null && entry.getBigContentView() != null) { bigContentView.reapply(mContext, entry.getBigContentView(), @@ -1931,7 +1960,9 @@ public abstract class BaseStatusBar extends SystemUI implements } else { entry.row.setOnClickListener(null); } + entry.row.setStatusBarNotification(notification); entry.row.notifyContentUpdated(); + entry.row.resetHeight(); } protected void notifyHeadsUpScreenOn(boolean screenOn) { @@ -1940,10 +1971,9 @@ public abstract class BaseStatusBar extends SystemUI implements } } - private boolean alertAgain(Entry entry) { - final StatusBarNotification sbn = entry.notification; - return entry == null || !entry.hasInterrupted() - || (sbn.getNotification().flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0; + private boolean alertAgain(Entry oldEntry, Notification newNotification) { + return oldEntry == null || !oldEntry.hasInterrupted() + || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0; } protected boolean shouldInterrupt(StatusBarNotification sbn) { @@ -1965,10 +1995,13 @@ public abstract class BaseStatusBar extends SystemUI implements boolean hasTicker = mHeadsUpTicker && !TextUtils.isEmpty(notification.tickerText); boolean isAllowed = notification.extras.getInt(Notification.EXTRA_AS_HEADS_UP, Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER; + boolean accessibilityForcesLaunch = isFullscreen + && mAccessibilityManager.isTouchExplorationEnabled(); final KeyguardTouchDelegate keyguard = KeyguardTouchDelegate.getInstance(mContext); boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker))) && isAllowed + && !accessibilityForcesLaunch && mPowerManager.isScreenOn() && !keyguard.isShowingAndNotOccluded() && !keyguard.isInputRestricted(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index c13593a..2ad6859 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -20,9 +20,11 @@ import android.content.Context; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; +import android.service.notification.StatusBarNotification; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.view.ViewStub; import android.view.accessibility.AccessibilityEvent; import android.widget.ImageView; @@ -67,6 +69,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { private boolean mWasReset; private NotificationGuts mGuts; + private StatusBarNotification mStatusBarNotification; + public void setIconAnimationRunning(boolean running) { setIconAnimationRunning(running, mPublicLayout); setIconAnimationRunning(running, mPrivateLayout); @@ -112,6 +116,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } } + public void setStatusBarNotification(StatusBarNotification statusBarNotification) { + mStatusBarNotification = statusBarNotification; + } + + public StatusBarNotification getStatusBarNotification() { + return mStatusBarNotification; + } + public interface ExpansionLogger { public void logNotificationExpansion(String key, boolean userAction, boolean expanded); } @@ -155,7 +167,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { super.onFinishInflate(); mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic); mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded); - mGuts = (NotificationGuts) findViewById(R.id.notification_guts); + ViewStub gutsStub = (ViewStub) findViewById(R.id.notification_guts_stub); + gutsStub.setOnInflateListener(new ViewStub.OnInflateListener() { + @Override + public void onInflate(ViewStub stub, View inflated) { + mGuts = (NotificationGuts) inflated; + mGuts.setClipTopAmount(getClipTopAmount()); + mGuts.setActualHeight(getActualHeight()); + } + }); mVetoButton = findViewById(R.id.veto); } @@ -421,7 +441,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setActualHeight(int height, boolean notifyListeners) { mPrivateLayout.setActualHeight(height); mPublicLayout.setActualHeight(height); - mGuts.setActualHeight(height); + if (mGuts != null) { + mGuts.setActualHeight(height); + } invalidate(); super.setActualHeight(height, notifyListeners); } @@ -443,7 +465,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { super.setClipTopAmount(clipTopAmount); mPrivateLayout.setClipTopAmount(clipTopAmount); mPublicLayout.setClipTopAmount(clipTopAmount); - mGuts.setClipTopAmount(clipTopAmount); + if (mGuts != null) { + mGuts.setClipTopAmount(clipTopAmount); + } } public void notifyContentUpdated() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index ca1fbe0..34c458a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -48,6 +48,7 @@ public class NotificationData { private boolean interruption; public boolean autoRedacted; // whether the redacted notification was generated by us public boolean legacy; // whether the notification has a legacy, dark background + public int targetSdk; public Entry(StatusBarNotification n, StatusBarIconView ic) { this.key = n.getKey(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 5883c26..18ef024 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -27,17 +27,21 @@ import android.widget.LinearLayout; import com.android.systemui.R; import com.android.systemui.statusbar.policy.NetworkControllerImpl; +import com.android.systemui.statusbar.policy.SecurityController; // Intimately tied to the design of res/layout/signal_cluster_view.xml public class SignalClusterView extends LinearLayout - implements NetworkControllerImpl.SignalCluster { + implements NetworkControllerImpl.SignalCluster, + SecurityController.SecurityControllerCallback { static final String TAG = "SignalClusterView"; static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); NetworkControllerImpl mNC; + SecurityController mSC; + private boolean mVpnVisible = false; private boolean mWifiVisible = false; private int mWifiStrengthId = 0; private boolean mMobileVisible = false; @@ -46,10 +50,14 @@ public class SignalClusterView private int mAirplaneIconId = 0; private String mWifiDescription, mMobileDescription, mMobileTypeDescription; private boolean mRoaming; + private boolean mIsMobileTypeIconWide; ViewGroup mWifiGroup, mMobileGroup; - ImageView mWifi, mMobile, mMobileType, mAirplane; + ImageView mVpn, mWifi, mMobile, mMobileType, mAirplane; View mWifiAirplaneSpacer; + View mWifiSignalSpacer; + + private int mWideTypeIconStartPadding; public SignalClusterView(Context context) { this(context, null); @@ -68,10 +76,25 @@ public class SignalClusterView mNC = nc; } + public void setSecurityController(SecurityController sc) { + if (DEBUG) Log.d(TAG, "SecurityController=" + sc); + mSC = sc; + mSC.addCallback(this); + mVpnVisible = mSC.isVpnEnabled(); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mWideTypeIconStartPadding = getContext().getResources().getDimensionPixelSize( + R.dimen.wide_type_icon_start_padding); + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); + mVpn = (ImageView) findViewById(R.id.vpn); mWifiGroup = (ViewGroup) findViewById(R.id.wifi_combo); mWifi = (ImageView) findViewById(R.id.wifi_signal); mMobileGroup = (ViewGroup) findViewById(R.id.mobile_combo); @@ -79,12 +102,14 @@ public class SignalClusterView mMobileType = (ImageView) findViewById(R.id.mobile_type); mAirplane = (ImageView) findViewById(R.id.airplane); mWifiAirplaneSpacer = findViewById(R.id.wifi_airplane_spacer); + mWifiSignalSpacer = findViewById(R.id.wifi_signal_spacer); apply(); } @Override protected void onDetachedFromWindow() { + mVpn = null; mWifiGroup = null; mWifi = null; mMobileGroup = null; @@ -95,6 +120,18 @@ public class SignalClusterView super.onDetachedFromWindow(); } + // From SecurityController. + @Override + public void onStateChanged() { + post(new Runnable() { + @Override + public void run() { + mVpnVisible = mSC.isVpnEnabled(); + apply(); + } + }); + } + @Override public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) { mWifiVisible = visible; @@ -106,13 +143,15 @@ public class SignalClusterView @Override public void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon, - String contentDescription, String typeContentDescription, boolean roaming) { + String contentDescription, String typeContentDescription, boolean roaming, + boolean isTypeIconWide) { mMobileVisible = visible; mMobileStrengthId = strengthIcon; mMobileTypeId = typeIcon; mMobileDescription = contentDescription; mMobileTypeDescription = typeContentDescription; mRoaming = roaming; + mIsMobileTypeIconWide = isTypeIconWide; apply(); } @@ -168,6 +207,8 @@ public class SignalClusterView private void apply() { if (mWifiGroup == null) return; + mVpn.setVisibility(mVpnVisible ? View.VISIBLE : View.GONE); + if (DEBUG) Log.d(TAG, String.format("vpn: %s", mVpnVisible ? "VISIBLE" : "GONE")); if (mWifiVisible) { mWifi.setImageResource(mWifiStrengthId); mWifiGroup.setContentDescription(mWifiDescription); @@ -203,6 +244,14 @@ public class SignalClusterView mWifiAirplaneSpacer.setVisibility(View.GONE); } + if (mRoaming && mMobileVisible && mWifiVisible) { + mWifiSignalSpacer.setVisibility(View.VISIBLE); + } else { + mWifiSignalSpacer.setVisibility(View.GONE); + } + + mMobile.setPaddingRelative(mIsMobileTypeIconWide ? mWideTypeIconStartPadding : 0, 0, 0, 0); + if (DEBUG) Log.d(TAG, String.format("mobile: %s sig=%d typ=%d", (mMobileVisible ? "VISIBLE" : "GONE"), diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java index c620046..64d80cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java @@ -90,7 +90,6 @@ public abstract class StackScrollerDecorView extends ExpandableView { .alpha(endValue) .setInterpolator(interpolator) .setDuration(260) - .withLayer() .withEndAction(new Runnable() { @Override public void run() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java index 9dfbb27..23810f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ActivityStarter.java @@ -24,5 +24,5 @@ import android.content.Intent; * Keyguard. */ public interface ActivityStarter { - public void startActivity(Intent intent, boolean dismissShade, boolean afterKeyguardGone); + public void startActivity(Intent intent, boolean dismissShade); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index f9da30f..e84ca52 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -315,15 +315,15 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL public void launchCamera() { mFlashlightController.killFlashlight(); Intent intent = getCameraIntent(); - boolean wouldLaunchResolverActivity = mPreviewInflater.wouldLaunchResolverActivity(intent); + boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity( + mContext, intent, mLockPatternUtils.getCurrentUser()); if (intent == SECURE_CAMERA_INTENT && !wouldLaunchResolverActivity) { mContext.startActivityAsUser(intent, UserHandle.CURRENT); } else { // We need to delay starting the activity because ResolverActivity finishes itself if // launched behind lockscreen. - mActivityStarter.startActivity(intent, false /* dismissShade */, - wouldLaunchResolverActivity /* afterKeyguardGone */); + mActivityStarter.startActivity(intent, false /* dismissShade */); } } @@ -337,8 +337,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } }); } else { - mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */, - mPreviewInflater.wouldLaunchResolverActivity(PHONE_INTENT)); + mActivityStarter.startActivity(PHONE_INTENT, false /* dismissShade */); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java index dc49118..685c184 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java @@ -74,8 +74,10 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener mKeyguardUserSwitcher.show(true /* animate */); } } else { - mQsPanel.showDetailAdapter(true, - mQsPanel.getHost().getUserSwitcherController().userDetailAdapter); + if (mQsPanel != null) { + mQsPanel.showDetailAdapter(true, + mQsPanel.getHost().getUserSwitcherController().userDetailAdapter); + } } } else { Intent intent = ContactsContract.QuickContact.composeQuickContactsIntent( @@ -93,9 +95,12 @@ public class MultiUserSwitch extends FrameLayout implements View.OnClickListener final UserManager um = UserManager.get(getContext()); String text; if (um.isUserSwitcherEnabled()) { - UserSwitcherController controller = mQsPanel.getHost() - .getUserSwitcherController(); - String currentUser = controller.getCurrentUserName(mContext); + String currentUser = null; + if (mQsPanel != null) { + UserSwitcherController controller = mQsPanel.getHost() + .getUserSwitcherController(); + currentUser = controller.getCurrentUserName(mContext); + } if (TextUtils.isEmpty(currentUser)) { text = mContext.getString(R.string.accessibility_multi_user_switch_switcher); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java index b633453..79bb1cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java @@ -31,7 +31,6 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG private final GestureDetector mTaskSwitcherDetector; private final int mScrollTouchSlop; private final int mMinFlingVelocity; - private boolean mInterceptTouches; private int mTouchDownX; private int mTouchDownY; @@ -56,11 +55,11 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG // task switcher detector mTaskSwitcherDetector.onTouchEvent(event); int action = event.getAction(); + boolean interceptTouches = false; switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { mTouchDownX = (int) event.getX(); mTouchDownY = (int) event.getY(); - mInterceptTouches = false; break; } case MotionEvent.ACTION_MOVE: { @@ -72,21 +71,19 @@ public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnG ? xDiff > mScrollTouchSlop && xDiff > yDiff : yDiff > mScrollTouchSlop && yDiff > xDiff; if (exceededTouchSlop) { - mInterceptTouches = true; + interceptTouches = true; return true; } break; } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - mInterceptTouches = false; break; } - return mInterceptTouches; + return interceptTouches; } public boolean onTouchEvent(MotionEvent event) { - if (!mInterceptTouches) return false; return mTaskSwitcherDetector.onTouchEvent(event); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index cf5aebc..9585e17 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -23,6 +23,8 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Configuration; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; import android.util.MathUtils; import android.view.MotionEvent; @@ -60,6 +62,10 @@ public class NotificationPanelView extends PanelView implements private static final float HEADER_RUBBERBAND_FACTOR = 2.05f; private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f; + private static final int DOZE_BACKGROUND_COLOR = 0xff000000; + private static final int TAG_KEY_ANIM = R.id.scrim; + private static final long DOZE_BACKGROUND_ANIM_DURATION = ScrimController.ANIMATION_DURATION; + private KeyguardAffordanceHelper mAfforanceHelper; private StatusBarHeaderView mHeader; private KeyguardUserSwitcher mKeyguardUserSwitcher; @@ -559,7 +565,7 @@ public class NotificationPanelView extends PanelView implements } private boolean isBelowFalsingThreshold() { - return !mQsTouchAboveFalsingThreshold && mStatusBar.isFalsingThresholdNeeded(); + return !mQsTouchAboveFalsingThreshold && mStatusBarState == StatusBarState.KEYGUARD; } private float getQsExpansionFraction() { @@ -1724,13 +1730,58 @@ public class NotificationPanelView extends PanelView implements if (dozing == mDozing) return; mDozing = dozing; if (mDozing) { - setBackgroundColor(0xff000000); + setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0xff, false /*animate*/); } else { - setBackground(null); + setBackgroundColorAlpha(this, DOZE_BACKGROUND_COLOR, 0, true /*animate*/); } updateKeyguardStatusBarVisibility(); } + private static void setBackgroundColorAlpha(final View target, int rgb, int targetAlpha, + boolean animate) { + int currentAlpha = getBackgroundAlpha(target); + if (currentAlpha == targetAlpha) { + return; + } + final int r = Color.red(rgb); + final int g = Color.green(rgb); + final int b = Color.blue(rgb); + Object runningAnim = target.getTag(TAG_KEY_ANIM); + if (runningAnim instanceof ValueAnimator) { + ((ValueAnimator) runningAnim).cancel(); + } + if (!animate) { + target.setBackgroundColor(Color.argb(targetAlpha, r, g, b)); + return; + } + ValueAnimator anim = ValueAnimator.ofInt(currentAlpha, targetAlpha); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int value = (int) animation.getAnimatedValue(); + target.setBackgroundColor(Color.argb(value, r, g, b)); + } + }); + anim.setDuration(DOZE_BACKGROUND_ANIM_DURATION); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + target.setTag(TAG_KEY_ANIM, null); + } + }); + anim.start(); + target.setTag(TAG_KEY_ANIM, anim); + } + + private static int getBackgroundAlpha(View view) { + if (view.getBackground() instanceof ColorDrawable) { + ColorDrawable drawable = (ColorDrawable) view.getBackground(); + return Color.alpha(drawable.getColor()); + } else { + return 0; + } + } + public void setShadeEmpty(boolean shadeEmpty) { mShadeEmpty = shadeEmpty; updateEmptyShadeView(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 861bf4a..5d4c831 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -149,6 +149,7 @@ import com.android.systemui.statusbar.policy.KeyguardUserSwitcher; import com.android.systemui.statusbar.policy.LocationControllerImpl; import com.android.systemui.statusbar.policy.NetworkControllerImpl; import com.android.systemui.statusbar.policy.NextAlarmController; +import com.android.systemui.statusbar.policy.PreviewInflater; import com.android.systemui.statusbar.policy.RotationLockControllerImpl; import com.android.systemui.statusbar.policy.SecurityControllerImpl; import com.android.systemui.statusbar.policy.UserInfoController; @@ -786,8 +787,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mNetworkController.addSignalCluster(signalCluster); mNetworkController.addSignalCluster(signalClusterKeyguard); mNetworkController.addSignalCluster(signalClusterQs); + signalCluster.setSecurityController(mSecurityController); signalCluster.setNetworkController(mNetworkController); + signalClusterKeyguard.setSecurityController(mSecurityController); signalClusterKeyguard.setNetworkController(mNetworkController); + signalClusterQs.setSecurityController(mSecurityController); signalClusterQs.setNetworkController(mNetworkController); final boolean isAPhone = mNetworkController.hasVoiceCallingFeature(); if (isAPhone) { @@ -1078,7 +1082,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, }; private long mLastLockToAppLongPress; - private AccessibilityManager mAccessibilityManager; private View.OnLongClickListener mLongPressBackRecentsListener = new View.OnLongClickListener() { @Override @@ -2067,8 +2070,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override - public void startActivity(Intent intent, boolean dismissShade, boolean afterKeyguardGone) { - startActivityDismissingKeyguard(intent, false, dismissShade, afterKeyguardGone); + public void startActivity(Intent intent, boolean dismissShade) { + startActivityDismissingKeyguard(intent, false, dismissShade); } public ScrimController getScrimController() { @@ -2957,9 +2960,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned, - final boolean dismissShade, final boolean afterKeyguardGone) { + final boolean dismissShade) { if (onlyProvisioned && !isDeviceProvisioned()) return; + final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity( + mContext, intent, mCurrentUserId); final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing(); dismissKeyguardThenExecute(new OnDismissAction() { @Override @@ -3308,8 +3313,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void handleStartSettingsActivity(Intent intent, boolean onlyProvisioned) { - startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */, - false /* afterKeyguardGone */); + startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */); } private static class FastColorDrawable extends Drawable { @@ -3869,10 +3873,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, try { boolean sendBackLongPress = false; IActivityManager activityManager = ActivityManagerNative.getDefault(); - if (mAccessibilityManager == null) { - mAccessibilityManager = (AccessibilityManager) - mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); - } boolean isAccessiblityEnabled = mAccessibilityManager.isEnabled(); if (activityManager.isInLockTaskMode() && !isAccessiblityEnabled) { long time = System.currentTimeMillis(); @@ -3948,6 +3948,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, return !mNotificationData.getActiveNotifications().isEmpty(); } + public void wakeUpIfDozing(long time) { + if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) { + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + pm.wakeUp(time); + } + } + private final class ShadeUpdates { private final ArraySet<String> mVisibleNotifications = new ArraySet<String>(); private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>(); @@ -3992,6 +3999,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, + mCurrentDozeService + "]"; } + public boolean isDozing() { + return mCurrentDozeService != null; + } + public void firePowerSaveChanged(boolean active) { for (Callback callback : mCallbacks) { callback.onPowerSaveChanged(active); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 455c336..be48df7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -38,11 +38,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { private static final String TAG = "ScrimController"; private static final boolean DEBUG = false; + public static final long ANIMATION_DURATION = 220; + private static final float SCRIM_BEHIND_ALPHA = 0.62f; private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.55f; private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f; private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; - private static final long ANIMATION_DURATION = 220; private static final int TAG_KEY_ANIM = R.id.scrim; private static final long PULSE_IN_ANIMATION_DURATION = 1000; @@ -131,6 +132,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { mDozing = dozing; if (!mDozing) { cancelPulsing(); + mAnimateChange = true; } scheduleUpdate(); } @@ -163,7 +165,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { if (mAnimateKeyguardFadingOut) { setScrimInFrontColor(0f); setScrimBehindColor(0f); - }else if (!mKeyguardShowing && !mBouncerShowing) { + } else if (!mKeyguardShowing && !mBouncerShowing) { updateScrimNormal(); setScrimInFrontColor(0); } else { @@ -217,8 +219,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { mScrimInFront.setClickable(false); } else { - // Eat touch events. - mScrimInFront.setClickable(true); + // Eat touch events (unless dozing). + mScrimInFront.setClickable(!mDozing); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index eeb97e3..15a7229 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -497,20 +497,19 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL } else if (v == mAlarmStatus && mNextAlarm != null) { PendingIntent showIntent = mNextAlarm.getShowIntent(); if (showIntent != null && showIntent.isActivity()) { - mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */, - false /* afterKeyguardGone */); + mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */); } } } private void startSettingsActivity() { mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS), - true /* dismissShade */, false /* afterKeyguardGone */); + true /* dismissShade */); } private void startBatteryActivity() { mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY), - true /* dismissShade */, false /* afterKeyguardGone */); + true /* dismissShade */); } public void setQSPanel(QSPanel qsp) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 1811d8d..a5217ab 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -128,6 +128,10 @@ public class StatusBarWindowView extends FrameLayout { && mService.getBarState() == StatusBarState.KEYGUARD && !mService.isBouncerShowing()) { intercept = mDragDownHelper.onInterceptTouchEvent(ev); + // wake up on a touch down event, if dozing + if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { + mService.wakeUpIfDozing(ev.getEventTime()); + } } if (!intercept) { super.onInterceptTouchEvent(ev); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java index b2009c3..7f155a1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java @@ -28,6 +28,7 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; +import android.view.accessibility.AccessibilityEvent; import android.widget.FrameLayout; import com.android.systemui.ExpandHelper; @@ -111,6 +112,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. mContentHolder.setVisibility(View.VISIBLE); mContentHolder.setAlpha(mMaxAlpha); mContentHolder.addView(mHeadsUp.row); + sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); mSwipeHelper.snapChild(mContentHolder, 1f); mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay; @@ -126,6 +128,14 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper. return true; } + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + if (changedView.getVisibility() == VISIBLE) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED); + } + } + public boolean isShowing(String key) { return mHeadsUp != null && mHeadsUp.key.equals(key); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java index d9a3e14..16c0e66 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java @@ -18,10 +18,12 @@ package com.android.systemui.statusbar.policy; import android.animation.Animator; import android.animation.ObjectAnimator; +import android.app.ActivityManager; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.hardware.input.InputManager; +import android.media.AudioManager; import android.os.Bundle; import android.os.SystemClock; import android.util.AttributeSet; @@ -57,6 +59,7 @@ public class KeyButtonView extends ImageView { private boolean mSupportsLongpress = true; private Animator mAnimateToQuiescent = new ObjectAnimator(); private Drawable mBackground; + private AudioManager mAudioManager; private final Runnable mCheckLongPress = new Runnable() { public void run() { @@ -99,6 +102,7 @@ public class KeyButtonView extends ImageView { setClickable(true); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); + mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); } @Override @@ -251,6 +255,10 @@ public class KeyButtonView extends ImageView { return true; } + public void playSoundEffect(int soundConstant) { + mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser()); + }; + public void sendEvent(int action, int flags) { sendEvent(action, flags, SystemClock.uptimeMillis()); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index b64dcbe..2ed9366 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -30,7 +30,8 @@ public interface NetworkController { void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId, String mobileSignalContentDescriptionId, int dataTypeIconId, boolean activityIn, boolean activityOut, - String dataTypeContentDescriptionId, String description, boolean noSim); + String dataTypeContentDescriptionId, String description, boolean noSim, + boolean isDataTypeIconWide); void onAirplaneModeChanged(boolean enabled); void onMobileDataEnabled(boolean enabled); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 4a6f1a8..5088089 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -63,9 +63,6 @@ public class NetworkControllerImpl extends BroadcastReceiver static final boolean DEBUG = false; static final boolean CHATTY = false; // additional diagnostics, but not logspew - private static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode; - private static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam; - // telephony boolean mHspaDataDistinguishable; final TelephonyManager mPhone; @@ -165,7 +162,8 @@ public class NetworkControllerImpl extends BroadcastReceiver public interface SignalCluster { void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription); void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon, - String contentDescription, String typeContentDescription, boolean roaming); + String contentDescription, String typeContentDescription, boolean roaming, + boolean isTypeIconWide); void setIsAirplaneMode(boolean is, int airplaneIcon); } @@ -358,6 +356,16 @@ public class NetworkControllerImpl extends BroadcastReceiver mMobileDataController.setMobileDataEnabled(enabled); } + private boolean isTypeIconWide(int iconId) { + return TelephonyIcons.ICON_LTE == iconId || TelephonyIcons.ICON_1X == iconId + || TelephonyIcons.ICON_3G == iconId || TelephonyIcons.ICON_4G == iconId; + } + + private boolean isQsTypeIconWide(int iconId) { + return TelephonyIcons.QS_ICON_LTE == iconId || TelephonyIcons.QS_ICON_1X == iconId + || TelephonyIcons.QS_ICON_3G == iconId || TelephonyIcons.QS_ICON_4G == iconId; + } + public void refreshSignalCluster(SignalCluster cluster) { if (mDemoMode) return; cluster.setWifiIndicators( @@ -374,7 +382,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mDataTypeIconId, mContentDescriptionWimax, mContentDescriptionDataType, - mDataTypeIconId == ROAMING_ICON); + mDataTypeIconId == TelephonyIcons.ROAMING_ICON, + false /* isTypeIconWide */ ); } else { // normal mobile data cluster.setMobileDataIndicators( @@ -383,7 +392,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mDataTypeIconId, mContentDescriptionPhoneSignal, mContentDescriptionDataType, - mDataTypeIconId == ROAMING_ICON); + mDataTypeIconId == TelephonyIcons.ROAMING_ICON, + isTypeIconWide(mDataTypeIconId)); } cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId); } @@ -409,18 +419,20 @@ public class NetworkControllerImpl extends BroadcastReceiver if (isEmergencyOnly()) { cb.onMobileDataSignalChanged(false, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, null, mNoSim); + mContentDescriptionDataType, null, mNoSim, isQsTypeIconWide(mQSDataTypeIconId)); } else { if (mIsWimaxEnabled && mWimaxConnected) { // Wimax is special cb.onMobileDataSignalChanged(true, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, mNetworkName, mNoSim); + mContentDescriptionDataType, mNetworkName, mNoSim, + isQsTypeIconWide(mQSDataTypeIconId)); } else { // Normal mobile data cb.onMobileDataSignalChanged(mHasMobileDataFeature, mQSPhoneSignalIconId, mContentDescriptionPhoneSignal, mQSDataTypeIconId, mobileIn, mobileOut, - mContentDescriptionDataType, mNetworkName, mNoSim); + mContentDescriptionDataType, mNetworkName, mNoSim, + isQsTypeIconWide(mQSDataTypeIconId)); } } cb.onAirplaneModeChanged(mAirplaneMode); @@ -754,7 +766,7 @@ public class NetworkControllerImpl extends BroadcastReceiver R.string.accessibility_data_connection_4g); } else { mDataIconList = TelephonyIcons.DATA_LTE[mInetCondition]; - mDataTypeIconId = R.drawable.stat_sys_data_fully_connected_lte; + mDataTypeIconId = TelephonyIcons.ICON_LTE; mQSDataTypeIconId = TelephonyIcons.QS_DATA_LTE[mInetCondition]; mContentDescriptionDataType = mContext.getString( R.string.accessibility_data_connection_lte); @@ -780,11 +792,11 @@ public class NetworkControllerImpl extends BroadcastReceiver if (isCdma()) { if (isCdmaEri()) { - mDataTypeIconId = ROAMING_ICON; + mDataTypeIconId = TelephonyIcons.ROAMING_ICON; mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; } } else if (mPhone.isNetworkRoaming()) { - mDataTypeIconId = ROAMING_ICON; + mDataTypeIconId = TelephonyIcons.ROAMING_ICON; mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; } } @@ -928,8 +940,8 @@ public class NetworkControllerImpl extends BroadcastReceiver intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); boolean wasConnected = mWifiConnected; mWifiConnected = networkInfo != null && networkInfo.isConnected(); - // If we just connected, grab the inintial signal strength and ssid - if (mWifiConnected && !wasConnected) { + // If Connected grab the signal strength and ssid + if (mWifiConnected) { // try getting it out of the intent first WifiInfo info = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); if (info == null) { @@ -1164,7 +1176,7 @@ public class NetworkControllerImpl extends BroadcastReceiver // look again; your radios are now airplanes mContentDescriptionPhoneSignal = mContext.getString( R.string.accessibility_airplane_mode); - mAirplaneIconId = FLIGHT_MODE_ICON; + mAirplaneIconId = TelephonyIcons.FLIGHT_MODE_ICON; mPhoneSignalIconId = mDataSignalIconId = mDataTypeIconId = mQSDataTypeIconId = 0; mQSPhoneSignalIconId = 0; @@ -1198,11 +1210,11 @@ public class NetworkControllerImpl extends BroadcastReceiver mQSDataTypeIconId = 0; if (isCdma()) { if (isCdmaEri()) { - mDataTypeIconId = ROAMING_ICON; + mDataTypeIconId = TelephonyIcons.ROAMING_ICON; mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; } } else if (mPhone.isNetworkRoaming()) { - mDataTypeIconId = ROAMING_ICON; + mDataTypeIconId = TelephonyIcons.ROAMING_ICON; mQSDataTypeIconId = TelephonyIcons.QS_DATA_R[mInetCondition]; } } @@ -1509,7 +1521,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (airplane != null) { boolean show = airplane.equals("show"); for (SignalCluster cluster : mSignalClusters) { - cluster.setIsAirplaneMode(show, FLIGHT_MODE_ICON); + cluster.setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON); } } String fully = args.getString("fully"); @@ -1540,23 +1552,23 @@ public class NetworkControllerImpl extends BroadcastReceiver String datatype = args.getString("datatype"); if (datatype != null) { mDemoDataTypeIconId = - datatype.equals("1x") ? R.drawable.stat_sys_data_fully_connected_1x : - datatype.equals("3g") ? R.drawable.stat_sys_data_fully_connected_3g : - datatype.equals("4g") ? R.drawable.stat_sys_data_fully_connected_4g : + datatype.equals("1x") ? TelephonyIcons.ICON_1X : + datatype.equals("3g") ? TelephonyIcons.ICON_3G : + datatype.equals("4g") ? TelephonyIcons.ICON_4G : datatype.equals("e") ? R.drawable.stat_sys_data_fully_connected_e : datatype.equals("g") ? R.drawable.stat_sys_data_fully_connected_g : datatype.equals("h") ? R.drawable.stat_sys_data_fully_connected_h : - datatype.equals("lte") ? R.drawable.stat_sys_data_fully_connected_lte : - datatype.equals("roam") ? ROAMING_ICON : + datatype.equals("lte") ? TelephonyIcons.ICON_LTE : + datatype.equals("roam") ? TelephonyIcons.ROAMING_ICON : 0; mDemoQSDataTypeIconId = - datatype.equals("1x") ? R.drawable.ic_qs_signal_1x : - datatype.equals("3g") ? R.drawable.ic_qs_signal_3g : - datatype.equals("4g") ? R.drawable.ic_qs_signal_4g : + datatype.equals("1x") ? TelephonyIcons.QS_ICON_1X : + datatype.equals("3g") ? TelephonyIcons.QS_ICON_3G : + datatype.equals("4g") ? TelephonyIcons.QS_ICON_4G : datatype.equals("e") ? R.drawable.ic_qs_signal_e : datatype.equals("g") ? R.drawable.ic_qs_signal_g : datatype.equals("h") ? R.drawable.ic_qs_signal_h : - datatype.equals("lte") ? R.drawable.ic_qs_signal_lte : + datatype.equals("lte") ? TelephonyIcons.QS_ICON_LTE : datatype.equals("roam") ? R.drawable.ic_qs_signal_r : 0; } @@ -1575,7 +1587,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mDemoDataTypeIconId, "Demo", "Demo", - mDemoDataTypeIconId == ROAMING_ICON); + mDemoDataTypeIconId == TelephonyIcons.ROAMING_ICON, + isTypeIconWide(mDemoDataTypeIconId)); } refreshViews(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java index cdbe494..030cd6d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java @@ -20,14 +20,12 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.content.pm.UserInfo; import android.os.UserHandle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardActivityLauncher; import com.android.systemui.statusbar.phone.KeyguardPreviewContainer; import java.util.List; @@ -107,20 +105,21 @@ public class PreviewInflater { return info; } - public boolean wouldLaunchResolverActivity(Intent intent) { - PackageManager packageManager = mContext.getPackageManager(); + public static boolean wouldLaunchResolverActivity(Context ctx, Intent intent, + int currentUserId) { + PackageManager packageManager = ctx.getPackageManager(); final List<ResolveInfo> appList = packageManager.queryIntentActivitiesAsUser( - intent, PackageManager.MATCH_DEFAULT_ONLY, mLockPatternUtils.getCurrentUser()); + intent, PackageManager.MATCH_DEFAULT_ONLY, currentUserId); if (appList.size() == 0) { return false; } ResolveInfo resolved = packageManager.resolveActivityAsUser(intent, - PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, - mLockPatternUtils.getCurrentUser()); + PackageManager.MATCH_DEFAULT_ONLY | PackageManager.GET_META_DATA, currentUserId); return wouldLaunchResolverActivity(resolved, appList); } - private boolean wouldLaunchResolverActivity(ResolveInfo resolved, List<ResolveInfo> appList) { + private static boolean wouldLaunchResolverActivity( + ResolveInfo resolved, List<ResolveInfo> appList) { // If the list contains the above resolved activity, then it can't be // ResolverActivity itself. for (int i = 0; i < appList.size(); i++) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index a15ddaf..2fbb812 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -139,14 +139,14 @@ public class SecurityControllerImpl implements SecurityController { } @Override - public void addCallback(SecurityControllerCallback callback) { + public void removeCallback(SecurityControllerCallback callback) { if (callback == null) return; if (DEBUG) Log.d(TAG, "removeCallback " + callback); mCallbacks.remove(callback); } @Override - public void removeCallback(SecurityControllerCallback callback) { + public void addCallback(SecurityControllerCallback callback) { if (callback == null || mCallbacks.contains(callback)) return; if (DEBUG) Log.d(TAG, "addCallback " + callback); mCallbacks.add(callback); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java index 84c53ce..1f2b918 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TelephonyIcons.java @@ -188,5 +188,16 @@ class TelephonyIcons { R.drawable.ic_qs_signal_lte }; + static final int FLIGHT_MODE_ICON = R.drawable.stat_sys_airplane_mode; + static final int ROAMING_ICON = R.drawable.stat_sys_data_fully_connected_roam; + static final int ICON_LTE = R.drawable.stat_sys_data_fully_connected_lte; + static final int ICON_3G = R.drawable.stat_sys_data_fully_connected_3g; + static final int ICON_4G = R.drawable.stat_sys_data_fully_connected_4g; + static final int ICON_1X = R.drawable.stat_sys_data_fully_connected_1x; + + static final int QS_ICON_LTE = R.drawable.ic_qs_signal_lte; + static final int QS_ICON_3G = R.drawable.ic_qs_signal_3g; + static final int QS_ICON_4G = R.drawable.ic_qs_signal_4g; + static final int QS_ICON_1X = R.drawable.ic_qs_signal_1x; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index 52fa621..d02826f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -73,6 +73,7 @@ public class UserSwitcherController { private ArrayList<UserRecord> mUsers = new ArrayList<>(); private Dialog mExitGuestDialog; + private Dialog mAddUserDialog; private int mLastNonGuestUser = UserHandle.USER_OWNER; private boolean mSimpleUserSwitcher; private boolean mAddUsersWhenLocked; @@ -228,8 +229,8 @@ public class UserSwitcherController { // No guest user. Create one. id = mUserManager.createGuest(mContext, mContext.getString(R.string.guest_nickname)).id; } else if (record.isAddUser) { - id = mUserManager.createUser( - mContext.getString(R.string.user_new_user_name), 0 /* flags */).id; + showAddUserDialog(); + return; } else { id = record.info.id; } @@ -260,6 +261,14 @@ public class UserSwitcherController { mExitGuestDialog.show(); } + private void showAddUserDialog() { + if (mAddUserDialog != null && mAddUserDialog.isShowing()) { + mAddUserDialog.cancel(); + } + mAddUserDialog = new AddUserDialog(mContext); + mAddUserDialog.show(); + } + private void exitGuest(int id) { int newId = UserHandle.USER_OWNER; if (mLastNonGuestUser != UserHandle.USER_OWNER) { @@ -534,4 +543,30 @@ public class UserSwitcherController { } } } + + private final class AddUserDialog extends SystemUIDialog implements + DialogInterface.OnClickListener { + + public AddUserDialog(Context context) { + super(context); + setTitle(R.string.user_add_user_title); + setMessage(context.getString(R.string.user_add_user_message_short)); + setButton(DialogInterface.BUTTON_NEGATIVE, + context.getString(android.R.string.cancel), this); + setButton(DialogInterface.BUTTON_POSITIVE, + context.getString(android.R.string.ok), this); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == BUTTON_NEGATIVE) { + cancel(); + } else { + dismiss(); + int id = mUserManager.createUser( + mContext.getString(R.string.user_new_user_name), 0 /* flags */).id; + switchToUserId(id); + } + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 6f477ef..67ba8d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.SpeedBumpView; +import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.policy.ScrollAdapter; import com.android.systemui.statusbar.stack.StackScrollState.ViewState; @@ -645,7 +646,7 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public boolean isAntiFalsingNeeded() { - return mPhoneStatusBar.isFalsingThresholdNeeded(); + return mPhoneStatusBar.getBarState() == StatusBarState.KEYGUARD; } private void setSwipingInProgress(boolean isSwiped) { @@ -1546,7 +1547,7 @@ public class NotificationStackScrollLayout extends ViewGroup mStackScrollAlgorithm.notifyChildrenChanged(this); ((ExpandableView) child).setOnHeightChangedListener(this); generateAddAnimation(child, false /* fromMoreCard */); - updateAnimationState(mAnimationsEnabled && mIsExpanded, child); + updateAnimationState(child); } public void setAnimationsEnabled(boolean animationsEnabled) { @@ -1563,6 +1564,11 @@ public class NotificationStackScrollLayout extends ViewGroup } } + private void updateAnimationState(View child) { + updateAnimationState(mAnimationsEnabled && mIsExpanded, child); + } + + private void updateAnimationState(boolean running, View child) { if (child instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) child; @@ -1960,6 +1966,7 @@ public class NotificationStackScrollLayout extends ViewGroup mRequestViewResizeAnimationOnLayout = true; } mStackScrollAlgorithm.onReset(view); + updateAnimationState(view); } private void updateScrollPositionOnExpandInBottom(ExpandableView view) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 7c4c0e8..e4a1c27 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -40,8 +40,6 @@ public class StackScrollAlgorithm { private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3; private static final int MAX_ITEMS_IN_TOP_STACK = 3; - /** When a child is activated, the other cards' alpha fade to this value. */ - private static final float ACTIVATED_INVERSE_ALPHA = 0.9f; public static final float DIMMED_SCALE = 0.95f; private int mPaddingBetweenElements; @@ -270,12 +268,8 @@ public class StackScrollAlgorithm { childViewState.scale = !mScaleDimmed || !dimmed || isActivatedChild ? 1.0f : DIMMED_SCALE; - if (dimmed && activatedChild != null) { - if (!isActivatedChild) { - childViewState.alpha *= ACTIVATED_INVERSE_ALPHA; - } else { - childViewState.zTranslation += 2.0f * mZDistanceBetweenElements; - } + if (dimmed && isActivatedChild) { + childViewState.zTranslation += 2.0f * mZDistanceBetweenElements; } } } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java index 367c31a..fa43f32 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java @@ -56,6 +56,7 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.ImageView; import android.widget.SeekBar; @@ -1081,6 +1082,7 @@ public class VolumePanel extends Handler { if (mCallback != null) { mCallback.onVisible(true); } + announceDialogShown(); } // Do a little vibrate if applicable (only when going into vibrate mode) @@ -1097,6 +1099,10 @@ public class VolumePanel extends Handler { } } + private void announceDialogShown() { + mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); + } + private boolean isShowing() { return mDialog.isShowing(); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index acb4827..0586a83 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -140,8 +140,7 @@ public class VolumeUI extends SystemUI { @Override public void run() { getComponent(PhoneStatusBar.class).startActivityDismissingKeyguard( - ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */, - false /* afterKeyguardGone */); + ZenModePanel.ZEN_SETTINGS, true /* onlyProvisioned */, true /* dismissShade */); mPanel.postDismiss(mDismissDelay); } }; diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index e4eecd3..f829994 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -60,7 +60,7 @@ public class ZenModePanel extends LinearLayout { private static final int[] MINUTE_BUCKETS = DEBUG ? new int[] { 0, 1, 2, 5, 15, 30, 45, 60, 120, 180, 240, 480 } - : new int[] { 15, 30, 45, 60, 120, 180, 240, 480 }; + : ZenModeConfig.MINUTE_BUCKETS; private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0]; private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1]; private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60); @@ -68,7 +68,6 @@ public class ZenModePanel extends LinearLayout { private static final int TIME_CONDITION_INDEX = 1; private static final int FIRST_CONDITION_INDEX = 2; private static final float SILENT_HINT_PULSE_SCALE = 1.1f; - private static final int ZERO_VALUE_MS = 20 * SECONDS_MS; public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS); @@ -217,7 +216,7 @@ public class ZenModePanel extends LinearLayout { mBucketIndex = -1; } else { mBucketIndex = DEFAULT_BUCKET_INDEX; - mTimeCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); + mTimeCondition = ZenModeConfig.toTimeCondition(MINUTE_BUCKETS[mBucketIndex]); } if (DEBUG) Log.d(mTag, "Initial bucket index: " + mBucketIndex); mConditions = null; // reset conditions @@ -263,7 +262,7 @@ public class ZenModePanel extends LinearLayout { } private void refreshExitConditionText() { - final String forever = mContext.getString(R.string.zen_mode_forever); + final String forever = mContext.getString(com.android.internal.R.string.zen_mode_forever); if (mExitCondition == null) { mExitConditionText = forever; } else if (ZenModeConfig.isValidCountdownConditionId(mExitCondition.id)) { @@ -339,24 +338,7 @@ public class ZenModePanel extends LinearLayout { if (time == 0) return null; final long span = time - System.currentTimeMillis(); if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null; - return timeCondition(time, Math.round(span / (float)MINUTES_MS)); - } - - private Condition newTimeCondition(int minutesFromNow) { - final long now = System.currentTimeMillis(); - final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS; - return timeCondition(now + millis, minutesFromNow); - } - - private Condition timeCondition(long time, int minutes) { - final int num = minutes < 60 ? minutes : Math.round(minutes / 60f); - final int resId = minutes < 60 - ? R.plurals.zen_mode_duration_minutes - : R.plurals.zen_mode_duration_hours; - final String caption = mContext.getResources().getQuantityString(resId, num, num); - final Uri id = ZenModeConfig.toCountdownConditionId(time); - return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE, - Condition.FLAG_RELEVANT_NOW); + return ZenModeConfig.toTimeCondition(time, Math.round(span / (float) MINUTES_MS)); } private void handleUpdateConditions(Condition[] conditions) { @@ -410,7 +392,7 @@ public class ZenModePanel extends LinearLayout { if (favoriteIndex == -1) { getConditionTagAt(FOREVER_CONDITION_INDEX).rb.setChecked(true); } else { - mTimeCondition = newTimeCondition(MINUTE_BUCKETS[favoriteIndex]); + mTimeCondition = ZenModeConfig.toTimeCondition(MINUTE_BUCKETS[favoriteIndex]); mBucketIndex = favoriteIndex; bind(mTimeCondition, mZenConditions.getChildAt(TIME_CONDITION_INDEX)); getConditionTagAt(TIME_CONDITION_INDEX).rb.setChecked(true); @@ -466,7 +448,7 @@ public class ZenModePanel extends LinearLayout { }); final TextView title = (TextView) row.findViewById(android.R.id.title); if (condition == null) { - title.setText(R.string.zen_mode_forever); + title.setText(mContext.getString(com.android.internal.R.string.zen_mode_forever)); } else { title.setText(condition.summary); } @@ -503,7 +485,7 @@ public class ZenModePanel extends LinearLayout { } else { final long span = time - System.currentTimeMillis(); button1.setEnabled(span > MIN_BUCKET_MINUTES * MINUTES_MS); - final Condition maxCondition = newTimeCondition(MAX_BUCKET_MINUTES); + final Condition maxCondition = ZenModeConfig.toTimeCondition(MAX_BUCKET_MINUTES); button2.setEnabled(!Objects.equals(condition.summary, maxCondition.summary)); } @@ -529,18 +511,18 @@ public class ZenModePanel extends LinearLayout { final long bucketTime = now + bucketMinutes * MINUTES_MS; if (up && bucketTime > time || !up && bucketTime < time) { mBucketIndex = j; - newCondition = timeCondition(bucketTime, bucketMinutes); + newCondition = ZenModeConfig.toTimeCondition(bucketTime, bucketMinutes); break; } } if (newCondition == null) { mBucketIndex = DEFAULT_BUCKET_INDEX; - newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); + newCondition = ZenModeConfig.toTimeCondition(MINUTE_BUCKETS[mBucketIndex]); } } else { // on a known index, simply increment or decrement mBucketIndex = Math.max(0, Math.min(N - 1, mBucketIndex + (up ? 1 : -1))); - newCondition = newTimeCondition(MINUTE_BUCKETS[mBucketIndex]); + newCondition = ZenModeConfig.toTimeCondition(MINUTE_BUCKETS[mBucketIndex]); } mTimeCondition = newCondition; bind(mTimeCondition, row); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index f39727a..cce30c7 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -2755,12 +2755,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS, mStatusBarColor, mLastTopInset, Gravity.TOP, STATUS_BAR_BACKGROUND_TRANSITION_NAME, - com.android.internal.R.id.statusBarBackground); + com.android.internal.R.id.statusBarBackground, + (getAttributes().flags & FLAG_FULLSCREEN) != 0); mNavigationColorView = updateColorViewInt(mNavigationColorView, SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION, mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM, NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME, - com.android.internal.R.id.navigationBarBackground); + com.android.internal.R.id.navigationBarBackground, + false /* hiddenByWindowFlag */); } if (insets != null) { insets = insets.consumeStableInsets(); @@ -2769,8 +2771,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag, - int color, int height, int verticalGravity, String transitionName, int id) { + int color, int height, int verticalGravity, String transitionName, int id, + boolean hiddenByWindowFlag) { boolean show = height > 0 && (mLastSystemUiVisibility & systemUiHideFlag) == 0 + && !hiddenByWindowFlag && (getAttributes().flags & translucentFlag) == 0 && (color & Color.BLACK) != 0 && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index cd3eab5..16bb00b 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -3533,13 +3533,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { pf.bottom = df.bottom = of.bottom = cf.bottom = mOverscanScreenTop + mOverscanScreenHeight; } else if (attrs.type == TYPE_WALLPAPER) { - // The wallpaper also has Real Ultimate Power. - pf.left = df.left = of.left = cf.left = mUnrestrictedScreenLeft; - pf.top = df.top = of.top = cf.top = mUnrestrictedScreenTop; - pf.right = df.right = of.right = cf.right - = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; - pf.bottom = df.bottom = of.bottom = cf.bottom - = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; + // The wallpaper also has Real Ultimate Power, but we want to tell + // it about the overscan area. + pf.left = df.left = mOverscanScreenLeft; + pf.top = df.top = mOverscanScreenTop; + pf.right = df.right = mOverscanScreenLeft + mOverscanScreenWidth; + pf.bottom = df.bottom = mOverscanScreenTop + mOverscanScreenHeight; + of.left = cf.left = mUnrestrictedScreenLeft; + of.top = cf.top = mUnrestrictedScreenTop; + of.right = cf.right = mUnrestrictedScreenLeft + mUnrestrictedScreenWidth; + of.bottom = cf.bottom = mUnrestrictedScreenTop + mUnrestrictedScreenHeight; } else if ((fl & FLAG_LAYOUT_IN_OVERSCAN) != 0 && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) { @@ -3653,9 +3656,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it. if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) { - df.left = df.top = of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; - df.right = df.bottom = of.right = of.bottom = cf.right = cf.bottom - = vf.right = vf.bottom = 10000; + df.left = df.top = -10000; + df.right = df.bottom = 10000; + if (attrs.type != TYPE_WALLPAPER) { + of.left = of.top = cf.left = cf.top = vf.left = vf.top = -10000; + of.right = of.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; + } } if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle() @@ -4240,14 +4246,17 @@ public class PhoneWindowManager implements WindowManagerPolicy { int result; boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0 || event.isWakeKey(); - if (interactive - || (isInjected && !isWakeKey) - || (!interactive && shouldDispatchInputWhenNonInteractive())) { - // When the device is interactive, the key is injected, or we're currently dozing in a - // non-interactive state with the screen on and the keyguard showing, pass the key to - // the application. + if (interactive || (isInjected && !isWakeKey)) { + // When the device is interactive or the key is injected pass the key to the + // application. result = ACTION_PASS_TO_USER; isWakeKey = false; + } else if (!interactive && shouldDispatchInputWhenNonInteractive()) { + // If we're currently dozing with the screen on and the keyguard showing, pass the key + // to the application but preserve its wake key status to make sure we still move + // from dozing to fully interactive if we would normally go from off to fully + // interactive. + result = ACTION_PASS_TO_USER; } else { // When the screen is off and the key is not injected, determine whether // to wake the device but don't pass the key to the application. diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index a43a2a6..ebe21ff 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -746,14 +746,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } /** - * Gets the bounds of the accessibility focus in the active window. + * Gets a point within the accessibility focused node where we can send down + * and up events to perform a click. * - * @param outBounds The output to which to write the focus bounds. - * @return Whether accessibility focus was found and the bounds are populated. + * @param outPoint The click point to populate. + * @return Whether accessibility a click point was found and set. */ // TODO: (multi-display) Make sure this works for multiple displays. - boolean getAccessibilityFocusBounds(Rect outBounds) { - return getInteractionBridgeLocked().getAccessibilityFocusBoundsNotLocked(outBounds); + boolean getAccessibilityFocusClickPointInScreen(Point outPoint) { + return getInteractionBridgeLocked() + .getAccessibilityFocusClickPointInScreenNotLocked(outPoint); } /** @@ -2196,8 +2198,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName, - partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid, - interrogatingTid, spec); + partialInteractiveRegion, interactionId, callback, mFetchFlags, + interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2248,8 +2250,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text, - partialInteractiveRegion, interactionId, callback, mFetchFlags, interrogatingPid, - interrogatingTid, spec); + partialInteractiveRegion, interactionId, callback, mFetchFlags, + interrogatingPid, interrogatingTid, spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2352,8 +2354,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { - connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion, interactionId, - callback, mFetchFlags, interrogatingPid, interrogatingTid, spec); + connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion, + interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid, + spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2403,8 +2406,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { final long identityToken = Binder.clearCallingIdentity(); MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); try { - connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion, interactionId, - callback, mFetchFlags, interrogatingPid, interrogatingTid, spec); + connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion, + interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid, + spec); return true; } catch (RemoteException re) { if (DEBUG) { @@ -2460,6 +2464,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return true; } + @Override public boolean performGlobalAction(int action) { synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles @@ -2501,6 +2506,57 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } @Override + public boolean computeClickPointInScreen(int accessibilityWindowId, + long accessibilityNodeId, int interactionId, + IAccessibilityInteractionConnectionCallback callback, long interrogatingTid) + throws RemoteException { + final int resolvedWindowId; + IAccessibilityInteractionConnection connection = null; + Region partialInteractiveRegion = mTempRegion; + synchronized (mLock) { + // We treat calls from a profile as if made by its parent as profiles + // share the accessibility state of the parent. The call below + // performs the current profile parent resolution. + final int resolvedUserId = mSecurityPolicy + .resolveCallingUserIdEnforcingPermissionsLocked( + UserHandle.getCallingUserId()); + if (resolvedUserId != mCurrentUserId) { + return false; + } + resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId); + final boolean permissionGranted = + mSecurityPolicy.canRetrieveWindowContentLocked(this); + if (!permissionGranted) { + return false; + } else { + connection = getConnectionLocked(resolvedWindowId); + if (connection == null) { + return false; + } + } + if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( + resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion = null; + } + } + final int interrogatingPid = Binder.getCallingPid(); + final long identityToken = Binder.clearCallingIdentity(); + MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId); + try { + connection.computeClickPointInScreen(accessibilityNodeId, partialInteractiveRegion, + interactionId, callback, interrogatingPid, interrogatingTid, spec); + return true; + } catch (RemoteException re) { + if (DEBUG) { + Slog.e(LOG_TAG, "Error computeClickPointInScreen()."); + } + } finally { + Binder.restoreCallingIdentity(identityToken); + } + return false; + } + + @Override public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP); synchronized (mLock) { @@ -3119,30 +3175,43 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } - public boolean getAccessibilityFocusBoundsNotLocked(Rect outBounds) { + public boolean getAccessibilityFocusClickPointInScreenNotLocked(Point outPoint) { AccessibilityNodeInfo focus = getAccessibilityFocusNotLocked(); if (focus == null) { return false; } synchronized (mLock) { - focus.getBoundsInScreen(outBounds); + Point point = mClient.computeClickPointInScreen(mConnectionId, + focus.getWindowId(), focus.getSourceNodeId()); + + if (point == null) { + return false; + } MagnificationSpec spec = getCompatibleMagnificationSpecLocked(focus.getWindowId()); if (spec != null && !spec.isNop()) { - outBounds.offset((int) -spec.offsetX, (int) -spec.offsetY); - outBounds.scale(1 / spec.scale); + point.offset((int) -spec.offsetX, (int) -spec.offsetY); + point.x = (int) (point.x * (1 / spec.scale)); + point.y = (int) (point.y * (1 / spec.scale)); } - // Clip to the window rectangle. + // Make sure the point is within the window. Rect windowBounds = mTempRect; getActiveWindowBounds(windowBounds); - outBounds.intersect(windowBounds); + if (!windowBounds.contains(point.x, point.y)) { + return false; + } - // Clip to the screen rectangle. - mDefaultDisplay.getRealSize(mTempPoint); - outBounds.intersect(0, 0, mTempPoint.x, mTempPoint.y); + // Make sure the point is within the screen. + Point screenSize = mTempPoint; + mDefaultDisplay.getRealSize(screenSize); + if (point.x < 0 || point.x > screenSize.x + || point.y < 0 || point.y > screenSize.y) { + return false; + } + outPoint.set(point.x, point.y); return true; } } diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java index ac0ca0a..9e63433 100644 --- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java @@ -24,6 +24,7 @@ import android.gesture.GesturePoint; import android.gesture.GestureStore; import android.gesture.GestureStroke; import android.gesture.Prediction; +import android.graphics.Point; import android.graphics.Rect; import android.os.Handler; import android.os.SystemClock; @@ -171,6 +172,9 @@ class TouchExplorer implements EventStreamTransformation { // Temporary rectangle to avoid instantiation. private final Rect mTempRect = new Rect(); + // Temporary point to avoid instantiation. + private final Point mTempPoint = new Point(); + // Context in which this explorer operates. private final Context mContext; @@ -1157,18 +1161,18 @@ class TouchExplorer implements EventStreamTransformation { mInjectedPointerTracker.getLastInjectedHoverEventForClick(); if (lastExploreEvent == null) { // No last touch explored event but there is accessibility focus in - // the active window. We click in the middle of the focus bounds. - Rect focusBounds = mTempRect; - if (mAms.getAccessibilityFocusBounds(focusBounds)) { - clickLocationX = focusBounds.centerX(); - clickLocationY = focusBounds.centerY(); + // the active window. We click in the focus bounds. + Point point = mTempPoint; + if (mAms.getAccessibilityFocusClickPointInScreen(point)) { + clickLocationX = point.x; + clickLocationY = point.y; } else { // Out of luck - do nothing. return; } } else { // If the click is within the active window but not within the - // accessibility focus bounds we click in the focus center. + // accessibility focus bounds we click in the focus bounds. final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex); clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex); @@ -1176,12 +1180,10 @@ class TouchExplorer implements EventStreamTransformation { if (mLastTouchedWindowId == mAms.getActiveWindowId()) { mAms.getActiveWindowBounds(activeWindowBounds); if (activeWindowBounds.contains(clickLocationX, clickLocationY)) { - Rect focusBounds = mTempRect; - if (mAms.getAccessibilityFocusBounds(focusBounds)) { - if (!focusBounds.contains(clickLocationX, clickLocationY)) { - clickLocationX = focusBounds.centerX(); - clickLocationY = focusBounds.centerY(); - } + Point point = mTempPoint; + if (mAms.getAccessibilityFocusClickPointInScreen(point)) { + clickLocationX = point.x; + clickLocationY = point.y; } } } @@ -1330,18 +1332,18 @@ class TouchExplorer implements EventStreamTransformation { mInjectedPointerTracker.getLastInjectedHoverEventForClick(); if (lastExploreEvent == null) { // No last touch explored event but there is accessibility focus in - // the active window. We click in the middle of the focus bounds. - Rect focusBounds = mTempRect; - if (mAms.getAccessibilityFocusBounds(focusBounds)) { - clickLocationX = focusBounds.centerX(); - clickLocationY = focusBounds.centerY(); + // the active window. We click in the focus bounds. + Point point = mTempPoint; + if (mAms.getAccessibilityFocusClickPointInScreen(point)) { + clickLocationX = point.x; + clickLocationY = point.y; } else { // Out of luck - do nothing. return; } } else { // If the click is within the active window but not within the - // accessibility focus bounds we click in the focus center. + // accessibility focus bounds we click in the focus bounds. final int lastExplorePointerIndex = lastExploreEvent.getActionIndex(); clickLocationX = (int) lastExploreEvent.getX(lastExplorePointerIndex); clickLocationY = (int) lastExploreEvent.getY(lastExplorePointerIndex); @@ -1349,12 +1351,10 @@ class TouchExplorer implements EventStreamTransformation { if (mLastTouchedWindowId == mAms.getActiveWindowId()) { mAms.getActiveWindowBounds(activeWindowBounds); if (activeWindowBounds.contains(clickLocationX, clickLocationY)) { - Rect focusBounds = mTempRect; - if (mAms.getAccessibilityFocusBounds(focusBounds)) { - if (!focusBounds.contains(clickLocationX, clickLocationY)) { - clickLocationX = focusBounds.centerX(); - clickLocationY = focusBounds.centerY(); - } + Point point = mTempPoint; + if (mAms.getAccessibilityFocusClickPointInScreen(point)) { + clickLocationX = point.x; + clickLocationY = point.y; } } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 3bab1bf..3062a92 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -425,8 +425,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { TelephonyManager mTelephonyManager; - // sequence number for Networks - private final static int MIN_NET_ID = 10; // some reserved marks + // sequence number for Networks; keep in sync with system/netd/NetworkController.cpp + private final static int MIN_NET_ID = 100; // some reserved marks private final static int MAX_NET_ID = 65535; private int mNextNetId = MIN_NET_ID; @@ -793,14 +793,28 @@ public class ConnectivityService extends IConnectivityManager.Stub { } /** - * Check if UID should be blocked from using the network represented by the - * given {@link NetworkStateTracker}. + * Check if UID should be blocked from using the network represented by the given networkType. + * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type. */ private boolean isNetworkBlocked(int networkType, int uid) { + return isNetworkWithLinkPropertiesBlocked(getLinkPropertiesForType(networkType), uid); + } + + /** + * Check if UID should be blocked from using the network represented by the given + * NetworkAgentInfo. + */ + private boolean isNetworkBlocked(NetworkAgentInfo nai, int uid) { + return isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid); + } + + /** + * Check if UID should be blocked from using the network with the given LinkProperties. + */ + private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid) { final boolean networkCostly; final int uidRules; - LinkProperties lp = getLinkPropertiesForType(networkType); final String iface = (lp == null ? "" : lp.getInterfaceName()); synchronized (mRulesLock) { networkCostly = mMeteredIfaces.contains(iface); @@ -819,17 +833,36 @@ public class ConnectivityService extends IConnectivityManager.Stub { * Return a filtered {@link NetworkInfo}, potentially marked * {@link DetailedState#BLOCKED} based on * {@link #isNetworkBlocked}. + * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type. */ private NetworkInfo getFilteredNetworkInfo(int networkType, int uid) { NetworkInfo info = getNetworkInfoForType(networkType); return getFilteredNetworkInfo(info, networkType, uid); } + /* + * @deprecated Uses mLegacyTypeTracker; cannot deal with multiple Networks of the same type. + */ private NetworkInfo getFilteredNetworkInfo(NetworkInfo info, int networkType, int uid) { if (isNetworkBlocked(networkType, uid)) { // network is blocked; clone and override state info = new NetworkInfo(info); info.setDetailedState(DetailedState.BLOCKED, null, null); + if (VDBG) log("returning Blocked NetworkInfo"); + } + if (mLockdownTracker != null) { + info = mLockdownTracker.augmentNetworkInfo(info); + if (VDBG) log("returning Locked NetworkInfo"); + } + return info; + } + + private NetworkInfo getFilteredNetworkInfo(NetworkAgentInfo nai, int uid) { + NetworkInfo info = nai.networkInfo; + if (isNetworkBlocked(nai, uid)) { + // network is blocked; clone and override state + info = new NetworkInfo(info); + info.setDetailedState(DetailedState.BLOCKED, null, null); if (DBG) log("returning Blocked NetworkInfo"); } if (mLockdownTracker != null) { @@ -946,7 +979,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { synchronized (nai) { if (nai.networkInfo == null) return null; - return getFilteredNetworkInfo(nai.networkInfo, nai.networkInfo.getType(), uid); + return getFilteredNetworkInfo(nai, uid); } } @@ -1315,6 +1348,12 @@ public class ConnectivityService extends IConnectivityManager.Stub { // } } + private void enforceInternetPermission() { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.INTERNET, + "ConnectivityService"); + } + private void enforceAccessPermission() { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.ACCESS_NETWORK_STATE, @@ -2468,7 +2507,22 @@ public class ConnectivityService extends IConnectivityManager.Stub { } public void reportBadNetwork(Network network) { - //TODO + enforceAccessPermission(); + enforceInternetPermission(); + + if (network == null) return; + + final int uid = Binder.getCallingUid(); + NetworkAgentInfo nai = null; + synchronized (mNetworkForNetId) { + nai = mNetworkForNetId.get(network.netId); + } + if (nai == null) return; + synchronized (nai) { + if (isNetworkBlocked(nai, uid)) return; + + nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid); + } } public ProxyInfo getProxy() { @@ -4436,10 +4490,14 @@ public class ConnectivityService extends IConnectivityManager.Stub { loge("Unknown NetworkAgentInfo in handleLingerComplete"); return; } - if (DBG) log("handleLingerComplete for " + oldNetwork.name()); if (DBG) { - if (oldNetwork.networkRequests.size() != 0) { - loge("Dead network still had " + oldNetwork.networkRequests.size() + " requests"); + log("handleLingerComplete for " + oldNetwork.name()); + for (int i = 0; i < oldNetwork.networkRequests.size(); i++) { + NetworkRequest nr = oldNetwork.networkRequests.valueAt(i); + // Ignore listening requests. + if (mNetworkRequests.get(nr).isRequest == false) continue; + loge("Dead network still had at least " + nr); + break; } } oldNetwork.asyncChannel.disconnect(); @@ -4463,6 +4521,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { loge("Unknown NetworkAgentInfo in handleConnectionValidated"); return; } + if (newNetwork.validated) return; + newNetwork.validated = true; boolean keep = newNetwork.isVPN(); boolean isNewDefault = false; if (DBG) log("handleConnectionValidated for "+newNetwork.name()); @@ -4706,6 +4766,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { // code will fire. for (int i = 0; i < nai.networkRequests.size(); i++) { NetworkRequest nr = nai.networkRequests.valueAt(i); + // Don't send listening requests to factories. b/17393458 + if (mNetworkRequests.get(nr).isRequest == false) continue; sendUpdatedScoreToFactories(nr, score); } } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index c8718e3..060c8e3 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -106,6 +106,7 @@ import android.view.inputmethod.InputMethod; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; +import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder; import android.widget.ArrayAdapter; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -3455,9 +3456,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE); final boolean isAuxiliary = "1".equals(String.valueOf( parser.getAttributeValue(null, ATTR_IS_AUXILIARY))); - final InputMethodSubtype subtype = - new InputMethodSubtype(label, icon, imeSubtypeLocale, - imeSubtypeMode, imeSubtypeExtraValue, isAuxiliary); + final InputMethodSubtype subtype = new InputMethodSubtypeBuilder() + .setSubtypeNameResId(label) + .setSubtypeIconResId(icon) + .setSubtypeLocale(imeSubtypeLocale) + .setSubtypeMode(imeSubtypeMode) + .setSubtypeExtraValue(imeSubtypeExtraValue) + .setIsAuxiliary(isAuxiliary) + .build(); tempSubtypesArray.add(subtype); } } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 7624314..37c23bb 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -196,7 +196,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if (VDBG) log("MSG_USER_SWITCHED userId=" + msg.arg1); int numPhones = TelephonyManager.getDefault().getPhoneCount(); for (int sub = 0; sub < numPhones; sub++) { - TelephonyRegistry.this.notifyCellLocationUsingSubId(sub, + TelephonyRegistry.this.notifyCellLocationForSubscriber(sub, mCellLocation[sub]); } break; @@ -326,7 +326,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void listenUsingSubId(long subId, String pkgForDebug, IPhoneStateListener callback, + public void listenForSubscriber(long subId, String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) { listen(pkgForDebug, callback, events, notifyNow, subId, false); } @@ -542,12 +542,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { broadcastCallStateChanged(state, incomingNumber, mDefaultSubId); } - public void notifyCallStateUsingSubId(long subId, int state, String incomingNumber) { + public void notifyCallStateForSubscriber(long subId, int state, String incomingNumber) { if (!checkNotifyPermission("notifyCallState()")) { return; } if (VDBG) { - log("notifyCallStateUsingSubId: subId=" + subId + log("notifyCallStateForSubscriber: subId=" + subId + " state=" + state + " incomingNumber=" + incomingNumber); } synchronized (mRecords) { @@ -573,38 +573,38 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyServiceState(ServiceState state) { - notifyServiceStateUsingSubId(mDefaultSubId, state); + notifyServiceStateForSubscriber(mDefaultSubId, state); } - public void notifyServiceStateUsingSubId(long subId, ServiceState state) { + public void notifyServiceStateForSubscriber(long subId, ServiceState state) { if (!checkNotifyPermission("notifyServiceState()")){ return; } if (subId == SubscriptionManager.DEFAULT_SUB_ID) { subId = mDefaultSubId; - if (VDBG) log("notifyServiceStateUsingSubId: using mDefaultSubId=" + mDefaultSubId); + if (VDBG) log("notifyServiceStateForSubscriber: using mDefaultSubId=" + mDefaultSubId); } synchronized (mRecords) { int phoneId = SubscriptionManager.getPhoneId(subId); if (VDBG) { - log("notifyServiceStateUsingSubId: subId=" + subId + " phoneId=" + phoneId + log("notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId + " state=" + state); } if (validatePhoneId(phoneId)) { mServiceState[phoneId] = state; - logServiceStateChanged("notifyServiceStateUsingSubId", subId, phoneId, state); - if (VDBG) toStringLogSSC("notifyServiceStateUsingSubId"); + logServiceStateChanged("notifyServiceStateForSubscriber", subId, phoneId, state); + if (VDBG) toStringLogSSC("notifyServiceStateForSubscriber"); for (Record r : mRecords) { if (VDBG) { - log("notifyServiceStateUsingSubId: r=" + r + " subId=" + subId + log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId + " phoneId=" + phoneId + " state=" + state); } if (((r.events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) && (r.phoneId == phoneId)) { try { if (DBG) { - log("notifyServiceStateUsingSubId: callback.onSSC r=" + r + log("notifyServiceStateForSubscriber: callback.onSSC r=" + r + " subId=" + subId + " phoneId=" + phoneId + " state=" + state); } @@ -615,7 +615,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } else { - log("notifyServiceStateUsingSubId: INVALID phoneId=" + phoneId); + log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId); } handleRemoveListLocked(); } @@ -623,33 +623,33 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifySignalStrength(SignalStrength signalStrength) { - notifySignalStrengthUsingSubId(mDefaultSubId, signalStrength); + notifySignalStrengthForSubscriber(mDefaultSubId, signalStrength); } - public void notifySignalStrengthUsingSubId(long subId, SignalStrength signalStrength) { + public void notifySignalStrengthForSubscriber(long subId, SignalStrength signalStrength) { if (!checkNotifyPermission("notifySignalStrength()")) { return; } if (VDBG) { - log("notifySignalStrengthUsingSubId: subId=" + subId + log("notifySignalStrengthForSubscriber: subId=" + subId + " signalStrength=" + signalStrength); - toStringLogSSC("notifySignalStrengthUsingSubId"); + toStringLogSSC("notifySignalStrengthForSubscriber"); } synchronized (mRecords) { int phoneId = SubscriptionManager.getPhoneId(subId); if (validatePhoneId(phoneId)) { - if (VDBG) log("notifySignalStrengthUsingSubId: valid phoneId=" + phoneId); + if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId); mSignalStrength[phoneId] = signalStrength; for (Record r : mRecords) { if (VDBG) { - log("notifySignalStrengthUsingSubId: r=" + r + " subId=" + subId + log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId + " phoneId=" + phoneId + " ss=" + signalStrength); } if (((r.events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) && (r.phoneId == phoneId)) { try { if (DBG) { - log("notifySignalStrengthUsingSubId: callback.onSsS r=" + r + log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r + " subId=" + subId + " phoneId=" + phoneId + " ss=" + signalStrength); } @@ -664,7 +664,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { int gsmSignalStrength = signalStrength.getGsmSignalStrength(); int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); if (DBG) { - log("notifySignalStrengthUsingSubId: callback.onSS r=" + r + log("notifySignalStrengthForSubscriber: callback.onSS r=" + r + " subId=" + subId + " phoneId=" + phoneId + " gsmSS=" + gsmSignalStrength + " ss=" + ss); } @@ -675,7 +675,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } else { - log("notifySignalStrengthUsingSubId: invalid phoneId=" + phoneId); + log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId); } handleRemoveListLocked(); } @@ -683,15 +683,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyCellInfo(List<CellInfo> cellInfo) { - notifyCellInfoUsingSubId(mDefaultSubId, cellInfo); + notifyCellInfoForSubscriber(mDefaultSubId, cellInfo); } - public void notifyCellInfoUsingSubId(long subId, List<CellInfo> cellInfo) { + public void notifyCellInfoForSubscriber(long subId, List<CellInfo> cellInfo) { if (!checkNotifyPermission("notifyCellInfo()")) { return; } if (VDBG) { - log("notifyCellInfoUsingSubId: subId=" + subId + log("notifyCellInfoForSubscriber: subId=" + subId + " cellInfo=" + cellInfo); } @@ -743,15 +743,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyMessageWaitingChanged(boolean mwi) { - notifyMessageWaitingChangedUsingSubId(mDefaultSubId, mwi); + notifyMessageWaitingChangedForSubscriber(mDefaultSubId, mwi); } - public void notifyMessageWaitingChangedUsingSubId(long subId, boolean mwi) { + public void notifyMessageWaitingChangedForSubscriber(long subId, boolean mwi) { if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { return; } if (VDBG) { - log("notifyMessageWaitingChangedUsingSubId: subId=" + subId + log("notifyMessageWaitingChangedForSubscriber: subId=" + subId + " mwi=" + mwi); } synchronized (mRecords) { @@ -774,15 +774,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyCallForwardingChanged(boolean cfi) { - notifyCallForwardingChangedUsingSubId(mDefaultSubId, cfi); + notifyCallForwardingChangedForSubscriber(mDefaultSubId, cfi); } - public void notifyCallForwardingChangedUsingSubId(long subId, boolean cfi) { + public void notifyCallForwardingChangedForSubscriber(long subId, boolean cfi) { if (!checkNotifyPermission("notifyCallForwardingChanged()")) { return; } if (VDBG) { - log("notifyCallForwardingChangedUsingSubId: subId=" + subId + log("notifyCallForwardingChangedForSubscriber: subId=" + subId + " cfi=" + cfi); } synchronized (mRecords) { @@ -805,10 +805,10 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyDataActivity(int state) { - notifyDataActivityUsingSubId(mDefaultSubId, state); + notifyDataActivityForSubscriber(mDefaultSubId, state); } - public void notifyDataActivityUsingSubId(long subId, int state) { + public void notifyDataActivityForSubscriber(long subId, int state) { if (!checkNotifyPermission("notifyDataActivity()" )) { return; } @@ -831,12 +831,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { public void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { - notifyDataConnectionUsingSubId(mDefaultSubId, state, isDataConnectivityPossible, + notifyDataConnectionForSubscriber(mDefaultSubId, state, isDataConnectivityPossible, reason, apn, apnType, linkProperties, networkCapabilities, networkType, roaming); } - public void notifyDataConnectionUsingSubId(long subId, int state, + public void notifyDataConnectionForSubscriber(long subId, int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { @@ -844,7 +844,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { return; } if (VDBG) { - log("notifyDataConnectionUsingSubId: subId=" + subId + log("notifyDataConnectionForSubscriber: subId=" + subId + " state=" + state + " isDataConnectivityPossible=" + isDataConnectivityPossible + " reason='" + reason + "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType @@ -921,16 +921,16 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyDataConnectionFailed(String reason, String apnType) { - notifyDataConnectionFailedUsingSubId(mDefaultSubId, reason, apnType); + notifyDataConnectionFailedForSubscriber(mDefaultSubId, reason, apnType); } - public void notifyDataConnectionFailedUsingSubId(long subId, + public void notifyDataConnectionFailedForSubscriber(long subId, String reason, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; } if (VDBG) { - log("notifyDataConnectionFailedUsingSubId: subId=" + subId + log("notifyDataConnectionFailedForSubscriber: subId=" + subId + " reason=" + reason + " apnType=" + apnType); } synchronized (mRecords) { @@ -954,17 +954,17 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyCellLocation(Bundle cellLocation) { - notifyCellLocationUsingSubId(mDefaultSubId, cellLocation); + notifyCellLocationForSubscriber(mDefaultSubId, cellLocation); } - public void notifyCellLocationUsingSubId(long subId, Bundle cellLocation) { - log("notifyCellLocationUsingSubId: subId=" + subId + public void notifyCellLocationForSubscriber(long subId, Bundle cellLocation) { + log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); if (!checkNotifyPermission("notifyCellLocation()")) { return; } if (VDBG) { - log("notifyCellLocationUsingSubId: subId=" + subId + log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); } synchronized (mRecords) { diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 0bdb964..599c3b9 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -308,7 +308,14 @@ public final class ActiveServices { return new ComponentName("!", res.permission != null ? res.permission : "private to package"); } + ServiceRecord r = res.record; + + if (!mAm.getUserManagerLocked().exists(r.userId)) { + Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId); + return null; + } + NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked( callingUid, r.packageName, service, service.getFlags(), null, r.userId); if (unscheduleServiceRestartLocked(r, callingUid, false)) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 1397ea4..a9a4732 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -196,6 +196,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; +import dalvik.system.VMRuntime; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -3124,6 +3125,11 @@ public final class ActivityManagerService extends ActivityManagerNative requiredAbi = Build.SUPPORTED_ABIS[0]; } + String instructionSet = null; + if (app.info.primaryCpuAbi != null) { + instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); + } + // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); @@ -3131,7 +3137,8 @@ public final class ActivityManagerService extends ActivityManagerNative checkTime(startTime, "startProcess: asking zygote to start proc"); Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, - app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); + app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, + entryPointArgs); checkTime(startTime, "startProcess: returned from zygote!"); if (app.isolated) { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 6168546..bcf3b17 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -425,13 +425,13 @@ final class ActivityStack { } final ActivityRecord topActivity() { - // Iterate to find the first non-empty task stack. Note that this code can - // be simplified once we stop storing tasks with empty mActivities lists. for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; - final int topActivityNdx = activities.size() - 1; - if (topActivityNdx >= 0) { - return activities.get(topActivityNdx); + for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { + final ActivityRecord r = activities.get(activityNdx); + if (!r.finishing) { + return r; + } } } return null; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index f821daf..b8261a4 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1772,7 +1772,7 @@ public final class ActivityStackSupervisor implements DisplayListener { if (intentActivity != null) { if (isLockTaskModeViolation(intentActivity.task)) { showLockTaskToast(); - Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); + Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; } if (r.task == null) { @@ -2783,9 +2783,8 @@ public final class ActivityStackSupervisor implements DisplayListener { } // A non-top activity is reporting a visibility change. - if ((visible && (top.fullscreen || top.state != ActivityState.RESUMED)) || - top.app == null || top.app.thread == null) { - // Can't carry out this request. + if (visible && top.fullscreen) { + // Let the caller know that it can't be seen. if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG, "requestVisibleBehind: returning top.fullscreen=" + top.fullscreen + " top.state=" + top.state + " top.app=" + top.app + " top.app.thread=" + top.app.thread); @@ -2807,9 +2806,12 @@ public final class ActivityStackSupervisor implements DisplayListener { mService.convertFromTranslucent(next.appToken); } } - try { - top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); - } catch (RemoteException e) { + if (top.app != null && top.app.thread != null) { + // Notify the top app of the change. + try { + top.app.thread.scheduleBackgroundVisibleBehindChanged(top.appToken, visible); + } catch (RemoteException e) { + } } return true; } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 5a97aee..bba786d 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -47,6 +47,7 @@ public class NetworkAgentInfo { public final NetworkMonitor networkMonitor; public final NetworkMisc networkMisc; public boolean created; + public boolean validated; // The list of NetworkRequests being satisfied by this Network. public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>(); @@ -68,6 +69,7 @@ public class NetworkAgentInfo { networkMonitor = new NetworkMonitor(context, handler, this); networkMisc = misc; created = false; + validated = false; } public void addRequest(NetworkRequest networkRequest) { diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index ff319d3..96872a7 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -27,6 +27,7 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; +import android.net.TrafficStats; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Handler; @@ -140,34 +141,28 @@ public class NetworkMonitor extends StateMachine { private static final int CMD_REEVALUATE = BASE + 6; /** - * Message to self indicating network evaluation is complete. - * arg1 = Token to ignore old messages. - * arg2 = HTTP response code of network evaluation. - */ - private static final int EVENT_REEVALUATION_COMPLETE = BASE + 7; - - /** * Inform NetworkMonitor that the network has disconnected. */ - public static final int CMD_NETWORK_DISCONNECTED = BASE + 8; + public static final int CMD_NETWORK_DISCONNECTED = BASE + 7; /** * Force evaluation even if it has succeeded in the past. + * arg1 = UID responsible for requesting this reeval. Will be billed for data. */ - public static final int CMD_FORCE_REEVALUATION = BASE + 9; + public static final int CMD_FORCE_REEVALUATION = BASE + 8; /** * Message to self indicating captive portal login is complete. * arg1 = Token to ignore old messages. * arg2 = 1 if we should use this network, 0 otherwise. */ - private static final int CMD_CAPTIVE_PORTAL_LOGGED_IN = BASE + 10; + private static final int CMD_CAPTIVE_PORTAL_LOGGED_IN = BASE + 9; /** * Message to self indicating user desires to log into captive portal. * arg1 = Token to ignore old messages. */ - private static final int CMD_USER_WANTS_SIGN_IN = BASE + 11; + private static final int CMD_USER_WANTS_SIGN_IN = BASE + 10; /** * Request ConnectivityService display provisioning notification. @@ -175,22 +170,22 @@ public class NetworkMonitor extends StateMachine { * arg2 = NetID. * obj = Intent to be launched when notification selected by user, null if !arg1. */ - public static final int EVENT_PROVISIONING_NOTIFICATION = BASE + 12; + public static final int EVENT_PROVISIONING_NOTIFICATION = BASE + 11; /** * Message to self indicating sign-in app bypassed captive portal. */ - private static final int EVENT_APP_BYPASSED_CAPTIVE_PORTAL = BASE + 13; + private static final int EVENT_APP_BYPASSED_CAPTIVE_PORTAL = BASE + 12; /** * Message to self indicating no sign-in app responded. */ - private static final int EVENT_NO_APP_RESPONSE = BASE + 14; + private static final int EVENT_NO_APP_RESPONSE = BASE + 13; /** * Message to self indicating sign-in app indicates sign-in is not possible. */ - private static final int EVENT_APP_INDICATES_SIGN_IN_IMPOSSIBLE = BASE + 15; + private static final int EVENT_APP_INDICATES_SIGN_IN_IMPOSSIBLE = BASE + 14; private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; // Default to 30s linger time-out. @@ -205,6 +200,8 @@ public class NetworkMonitor extends StateMachine { private static final int MAX_RETRIES = 10; private final int mReevaluateDelayMs; private int mReevaluateToken = 0; + private static final int INVALID_UID = -1; + private int mUidResponsibleForReeval = INVALID_UID; private int mCaptivePortalLoggedInToken = 0; private int mUserPromptedToken = 0; @@ -282,6 +279,7 @@ public class NetworkMonitor extends StateMachine { return HANDLED; case CMD_FORCE_REEVALUATION: if (DBG) log("Forcing reevaluation"); + mUidResponsibleForReeval = message.arg1; transitionTo(mEvaluatingState); return HANDLED; default: @@ -322,20 +320,14 @@ public class NetworkMonitor extends StateMachine { private class EvaluatingState extends State { private int mRetries; - private class EvaluateInternetConnectivity extends Thread { - private int mToken; - EvaluateInternetConnectivity(int token) { - mToken = token; - } - public void run() { - sendMessage(EVENT_REEVALUATION_COMPLETE, mToken, isCaptivePortal()); - } - } - @Override public void enter() { mRetries = 0; sendMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); + if (mUidResponsibleForReeval != INVALID_UID) { + TrafficStats.setThreadStatsUid(mUidResponsibleForReeval); + mUidResponsibleForReeval = INVALID_UID; + } } @Override @@ -356,14 +348,7 @@ public class NetworkMonitor extends StateMachine { transitionTo(mValidatedState); return HANDLED; } - // Kick off a thread to perform internet connectivity evaluation. - Thread thread = new EvaluateInternetConnectivity(mReevaluateToken); - thread.run(); - return HANDLED; - case EVENT_REEVALUATION_COMPLETE: - if (message.arg1 != mReevaluateToken) - return HANDLED; - int httpResponseCode = message.arg2; + int httpResponseCode = isCaptivePortal(); if (httpResponseCode == 204) { transitionTo(mValidatedState); } else if (httpResponseCode >= 200 && httpResponseCode <= 399) { @@ -375,10 +360,18 @@ public class NetworkMonitor extends StateMachine { sendMessageDelayed(msg, mReevaluateDelayMs); } return HANDLED; + case CMD_FORCE_REEVALUATION: + // Ignore duplicate requests. + return HANDLED; default: return NOT_HANDLED; } } + + @Override + public void exit() { + TrafficStats.clearThreadStatsUid(); + } } private class UserPromptedState extends State { diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 38c6fb3..5cd7c01 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -256,7 +256,7 @@ public final class HdmiControlService extends SystemService { private List<HdmiDeviceInfo> mMhlDevices; @Nullable - private HdmiMhlController mMhlController; + private HdmiMhlControllerStub mMhlController; // Last input port before switching to the MHL port. Should switch back to this port // when the mobile device sends the request one touch play with off. @@ -305,7 +305,7 @@ public final class HdmiControlService extends SystemService { Slog.i(TAG, "Device does not support HDMI-CEC."); } - mMhlController = HdmiMhlController.create(this); + mMhlController = HdmiMhlControllerStub.create(this); if (!mMhlController.isReady()) { Slog.i(TAG, "Device does not support MHL-control."); } diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java new file mode 100644 index 0000000..c27cf18 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.hdmi; + +import android.hardware.hdmi.HdmiPortInfo; +import android.util.SparseArray; + +import com.android.server.hdmi.HdmiControlService.SendMessageCallback; + +/** + * A handler class for MHL control command. It converts user's command into MHL command and pass it + * to MHL HAL layer. + * <p> + * It can be created only by {@link HdmiMhlControllerStub#create}. + */ +final class HdmiMhlControllerStub { + + private static final SparseArray<HdmiMhlLocalDevice> mLocalDevices = new SparseArray<>(); + private static final HdmiPortInfo[] EMPTY_PORT_INFO = new HdmiPortInfo[0]; + private static final int INVALID_MHL_VERSION = 0; + private static final int NO_SUPPORTED_FEATURES = 0; + private static final int INVALID_DEVICE_ROLES = 0; + + // Private constructor. Use HdmiMhlControllerStub.create(). + private HdmiMhlControllerStub(HdmiControlService service) { + } + + // Returns true if MHL controller is initialized and ready to use. + boolean isReady() { + return false; + } + + static HdmiMhlControllerStub create(HdmiControlService service) { + return new HdmiMhlControllerStub(service); + } + + HdmiPortInfo[] getPortInfos() { + return EMPTY_PORT_INFO; + } + + /** + * Return {@link HdmiMhlLocalDevice} matched with the given port id. + * + * @return null if has no matched port id + */ + HdmiMhlLocalDevice getLocalDevice(int portId) { + return null; + } + + /** + * Return {@link HdmiMhlLocalDevice} matched with the given device id. + * + * @return null if has no matched id + */ + HdmiMhlLocalDevice getLocalDeviceById(int deviceId) { + return null; + } + + SparseArray<HdmiMhlLocalDevice> getAllLocalDevices() { + return mLocalDevices; + } + + /** + * Remove a {@link HdmiMhlLocalDevice} matched with the given port id. + * + * @return removed {@link HdmiMhlLocalDevice}. Return null if no matched port id. + */ + HdmiMhlLocalDevice removeLocalDevice(int portId) { + return null; + } + + /** + * Add a new {@link HdmiMhlLocalDevice}. + * + * @return old {@link HdmiMhlLocalDevice} having same port id + */ + HdmiMhlLocalDevice addLocalDevice(HdmiMhlLocalDevice device) { + return null; + } + + void clearAllLocalDevices() { + } + + /** + * Send MHL MSC-Subcommand to the device connected to the given port. + */ + void sendSubcommand(int portId, HdmiMhlSubcommand command) { + } + + void sendSubcommand(final int portId, final HdmiMhlSubcommand command, + SendMessageCallback callback) { + } + + + void sendScratchpadCommand(int portId, int offset, int length, byte[] data) { + } + + void setOption(int flag, int value) { + } + + /** + * Get the MHL version supported by underlying hardware port of the given {@code portId}. + * MHL specification version 2.0 returns 0x20, 3.0 will return 0x30 respectively. + * The return value is stored in 'version'. Return INVALID_VERSION if MHL hardware layer + * is not ready. + */ + int getMhlVersion(int portId) { + return INVALID_MHL_VERSION; + } + + /** + * Get MHL version of a device which is connected to a port of the given {@code portId}. + * MHL specification version 2.0 returns 0x20, 3.0 will return 0x30 respectively. + * The return value is stored in 'version'. + */ + int getPeerMhlVersion(int portId) { + return INVALID_MHL_VERSION; + } + + /** + * Get the bit flags describing the features supported by the system. Refer to feature support + * flag register info in MHL specification. + */ + int getSupportedFeatures(int portId) { + return NO_SUPPORTED_FEATURES; + } + + /** + * Get the bit flags describing the roles which ECBUS device can play. Refer to the + * ECBUS_DEV_ROLES Register info MHL3.0 specification + */ + int getEcbusDeviceRoles(int portId) { + return INVALID_DEVICE_ROLES; + } +} diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index bbb8371..9c567ac 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -697,7 +697,9 @@ public class InputManagerService extends IInputManager.Stub synchronized (mDataStore) { for (int i = 0; i < numFullKeyboards; i++) { final InputDevice inputDevice = mTempFullKeyboards.get(i); - if (mDataStore.getCurrentKeyboardLayout(inputDevice.getDescriptor()) == null) { + final String layout = + getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier()); + if (layout == null) { missingLayoutForExternalKeyboard = true; if (i < numFullKeyboardsAdded) { missingLayoutForExternalKeyboardAdded = true; diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 0cb8eb8..11818d8 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java @@ -331,6 +331,7 @@ public class GpsLocationProvider implements LocationProviderInterface { private int mSuplServerPort; private String mC2KServerHost; private int mC2KServerPort; + private boolean mSuplEsEnabled = false; private final Context mContext; private final NtpTrustedTime mNtpTime; @@ -493,6 +494,7 @@ public class GpsLocationProvider implements LocationProviderInterface { Log.d(TAG, "SIM STATE is ready, SIM MCC/MNC is " + mccMnc); synchronized (mLock) { reloadGpsProperties(context, mProperties); + mNIHandler.setSuplEsEnablement(mSuplEsEnabled); } } } @@ -570,6 +572,16 @@ public class GpsLocationProvider implements LocationProviderInterface { } catch (IOException ex) { Log.w(TAG, "failed to dump properties contents"); } + + // SUPL_ES configuration. + String suplESProperty = mProperties.getProperty("SUPL_ES"); + if (suplESProperty != null) { + try { + mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1); + } catch (NumberFormatException e) { + Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty); + } + } } private void loadPropertiesFromResource(Context context, @@ -611,7 +623,6 @@ public class GpsLocationProvider implements LocationProviderInterface { mContext = context; mNtpTime = NtpTrustedTime.getInstance(context); mILocationManager = ilocationManager; - mNIHandler = new GpsNetInitiatedHandler(context); mLocation.setExtras(mLocationExtras); @@ -638,6 +649,11 @@ public class GpsLocationProvider implements LocationProviderInterface { mProperties = new Properties(); reloadGpsProperties(mContext, mProperties); + // Create a GPS net-initiated handler. + mNIHandler = new GpsNetInitiatedHandler(context, + mNetInitiatedListener, + mSuplEsEnabled); + // construct handler, listen for events mHandler = new ProviderHandler(looper); listenForBroadcasts(); diff --git a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java index 317ebef..b71bad8 100644 --- a/services/core/java/com/android/server/notification/DowntimeConditionProvider.java +++ b/services/core/java/com/android/server/notification/DowntimeConditionProvider.java @@ -43,6 +43,7 @@ import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.Objects; +import java.util.TimeZone; /** Built-in zen condition provider for managing downtime */ public class DowntimeConditionProvider extends ConditionProviderService { @@ -275,6 +276,9 @@ public class DowntimeConditionProvider extends ConditionProviderService { final long schTime = intent.getLongExtra(EXTRA_TIME, 0); if (DEBUG) Slog.d(TAG, String.format("%s scheduled for %s, fired at %s, delta=%s", action, ts(schTime), ts(now), now - schTime)); + } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) { + if (DEBUG) Slog.d(TAG, "timezone changed to " + TimeZone.getDefault()); + mCalendar.setTimeZone(TimeZone.getDefault()); } else { if (DEBUG) Slog.d(TAG, action + " fired at " + now); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 54f043d..c09eff8 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -49,6 +49,7 @@ import android.content.res.Resources; import android.database.ContentObserver; import android.media.AudioAttributes; import android.media.AudioManager; +import android.media.AudioSystem; import android.media.IRingtonePlayer; import android.net.Uri; import android.os.Binder; @@ -1945,14 +1946,19 @@ public class NotificationManagerService extends SystemService { } private static AudioAttributes audioAttributesForNotification(Notification n) { - if (n.audioAttributes != null - && !Notification.AUDIO_ATTRIBUTES_DEFAULT.equals(n.audioAttributes)) { + if (n.audioAttributes != null) { return n.audioAttributes; + } else if (n.audioStreamType >= 0 && n.audioStreamType < AudioSystem.getNumStreamTypes()) { + // the stream type is valid, use it + return new AudioAttributes.Builder() + .setInternalLegacyStreamType(n.audioStreamType) + .build(); + } else if (n.audioStreamType == AudioSystem.STREAM_DEFAULT) { + return Notification.AUDIO_ATTRIBUTES_DEFAULT; + } else { + Log.w(TAG, String.format("Invalid stream type: %d", n.audioStreamType)); + return Notification.AUDIO_ATTRIBUTES_DEFAULT; } - return new AudioAttributes.Builder() - .setLegacyStreamType(n.audioStreamType) - .setUsage(AudioAttributes.usageForLegacyStreamType(n.audioStreamType)) - .build(); } void showNextToastLocked() { @@ -2648,6 +2654,11 @@ public class NotificationManagerService extends SystemService { if (speedBumpIndex == -1 && // Intrusiveness trumps priority, hence ignore intrusives. !record.isRecentlyIntrusive() && + // Currently, package priority is either PRIORITY_DEFAULT or PRIORITY_MAX, so + // scanning for PRIORITY_MIN within the package bucket PRIORITY_DEFAULT + // (or lower as a safeguard) is sufficient to find the speedbump index. + // We'll have to revisit this when more package priority buckets are introduced. + record.getPackagePriority() <= Notification.PRIORITY_DEFAULT && record.sbn.getNotification().priority == Notification.PRIORITY_MIN) { speedBumpIndex = keys.size() - 1; } @@ -2960,15 +2971,18 @@ public class NotificationManagerService extends SystemService { */ private static final class StatusBarNotificationHolder extends IStatusBarNotificationHolder.Stub { - private final StatusBarNotification mValue; + private StatusBarNotification mValue; public StatusBarNotificationHolder(StatusBarNotification value) { mValue = value; } + /** Get the held value and clear it. This function should only be called once per holder */ @Override public StatusBarNotification get() { - return mValue; + StatusBarNotification value = mValue; + mValue = null; + return value; } } } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 168328f..41d7fa8 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -18,7 +18,6 @@ package com.android.server.notification; import static android.media.AudioAttributes.USAGE_ALARM; import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE; -import static android.media.AudioAttributes.USAGE_UNKNOWN; import android.app.AppOpsManager; import android.app.Notification; @@ -225,11 +224,6 @@ public class ZenModeHelper { muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, exceptionPackages); - // restrict vibrations with no hints - mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_UNKNOWN, - zen ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED, - exceptionPackages); - // alarm restrictions final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS; mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM, @@ -307,8 +301,8 @@ public class ZenModeHelper { final int ringerMode = mAudioManager.getRingerMode(); int newZen = -1; if (ringerMode == AudioManager.RINGER_MODE_SILENT) { - if (mZenMode != Global.ZEN_MODE_NO_INTERRUPTIONS) { - newZen = Global.ZEN_MODE_NO_INTERRUPTIONS; + if (mZenMode == Global.ZEN_MODE_OFF) { + newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; } } else if ((ringerMode == AudioManager.RINGER_MODE_NORMAL || ringerMode == AudioManager.RINGER_MODE_VIBRATE) diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index b7b1c23..dcc4f8d 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -199,8 +199,7 @@ public class LauncherAppsService extends SystemService { mainIntent.setPackage(packageName); long ident = Binder.clearCallingIdentity(); try { - List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent, - PackageManager.NO_CROSS_PROFILE, // We only want the apps for this user + List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(mainIntent, 0 /* flags */, user.getIdentifier()); return apps; } finally { @@ -288,8 +287,7 @@ public class LauncherAppsService extends SystemService { // as calling startActivityAsUser ignores the category and just // resolves based on the component if present. List<ResolveInfo> apps = mPm.queryIntentActivitiesAsUser(launchIntent, - PackageManager.NO_CROSS_PROFILE, // We only want the apps for this user - user.getIdentifier()); + 0 /* flags */, user.getIdentifier()); final int size = apps.size(); for (int i = 0; i < size; ++i) { ActivityInfo activityInfo = apps.get(i).activityInfo; diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 89ea905..496c136 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -42,7 +42,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; -import android.content.pm.ApplicationInfo; import android.content.pm.IPackageInstaller; import android.content.pm.IPackageInstallerCallback; import android.content.pm.IPackageInstallerSession; @@ -50,15 +49,11 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; -import android.content.pm.PackageParser; -import android.content.pm.PackageParser.PackageLite; -import android.content.pm.PackageParser.PackageParserException; import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Environment; -import android.os.Environment.UserEnvironment; import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; @@ -70,7 +65,6 @@ import android.os.RemoteException; import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; -import android.os.storage.StorageManager; import android.system.ErrnoException; import android.system.Os; import android.text.TextUtils; @@ -126,6 +120,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private static final String ATTR_CREATED_MILLIS = "createdMillis"; private static final String ATTR_SESSION_STAGE_DIR = "sessionStageDir"; private static final String ATTR_SESSION_STAGE_CID = "sessionStageCid"; + private static final String ATTR_PREPARED = "prepared"; private static final String ATTR_SEALED = "sealed"; private static final String ATTR_MODE = "mode"; private static final String ATTR_INSTALL_FLAGS = "installFlags"; @@ -148,7 +143,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private final Context mContext; private final PackageManagerService mPm; private final AppOpsManager mAppOps; - private final StorageManager mStorage; private final File mStagingDir; private final HandlerThread mInstallThread; @@ -190,7 +184,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub { mContext = context; mPm = pm; mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); - mStorage = StorageManager.from(mContext); mStagingDir = stagingDir; @@ -266,7 +259,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub { try { final int sessionId = allocateSessionIdLocked(); mLegacySessions.put(sessionId, true); - return prepareInternalStageDir(sessionId); + final File stageDir = buildInternalStageDir(sessionId); + prepareInternalStageDir(stageDir); + return stageDir; } catch (IllegalStateException e) { throw new IOException(e); } @@ -345,6 +340,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { final String stageDirRaw = readStringAttribute(in, ATTR_SESSION_STAGE_DIR); final File stageDir = (stageDirRaw != null) ? new File(stageDirRaw) : null; final String stageCid = readStringAttribute(in, ATTR_SESSION_STAGE_CID); + final boolean prepared = readBooleanAttribute(in, ATTR_PREPARED, true); final boolean sealed = readBooleanAttribute(in, ATTR_SEALED); final SessionParams params = new SessionParams( @@ -362,7 +358,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { return new PackageInstallerSession(mInternalCallback, mContext, mPm, mInstallThread.getLooper(), sessionId, userId, installerPackageName, params, - createdMillis, stageDir, stageCid, sealed); + createdMillis, stageDir, stageCid, prepared, sealed); } private void writeSessionsLocked() { @@ -410,6 +406,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub { if (session.stageCid != null) { writeStringAttribute(out, ATTR_SESSION_STAGE_CID, session.stageCid); } + writeBooleanAttribute(out, ATTR_PREPARED, session.isPrepared()); writeBooleanAttribute(out, ATTR_SEALED, session.isSealed()); writeIntAttribute(out, ATTR_MODE, params.mode); @@ -483,14 +480,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } } - // TODO: treat INHERIT_EXISTING as install for user - - // Figure out where we're going to be staging session data - final boolean stageInternal; - - if (params.mode == SessionParams.MODE_FULL_INSTALL) { - // Brand new install, use best resolved location. This also verifies - // that target has enough free space for the install. + if (params.mode == SessionParams.MODE_FULL_INSTALL + || params.mode == SessionParams.MODE_INHERIT_EXISTING) { + // Resolve best location for install, based on combination of + // requested install flags, delta size, and manifest settings. final long ident = Binder.clearCallingIdentity(); try { final int resolved = PackageHelper.resolveInstallLocation(mContext, @@ -498,46 +491,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub { params.installFlags); if (resolved == PackageHelper.RECOMMEND_INSTALL_INTERNAL) { - stageInternal = true; + params.setInstallFlagsInternal(); } else if (resolved == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { - stageInternal = false; + params.setInstallFlagsExternal(); } else { throw new IOException("No storage with enough free space; res=" + resolved); } } finally { Binder.restoreCallingIdentity(ident); } - } else if (params.mode == SessionParams.MODE_INHERIT_EXISTING) { - // Inheriting existing install, so stay on the same storage medium. - final ApplicationInfo existingApp = mPm.getApplicationInfo(params.appPackageName, 0, - userId); - if (existingApp == null) { - throw new IllegalStateException( - "Missing existing app " + params.appPackageName); - } - - final long existingSize; - try { - final PackageLite existingPkg = PackageParser.parsePackageLite( - new File(existingApp.getCodePath()), 0); - existingSize = PackageHelper.calculateInstalledSize(existingPkg, false, - params.abiOverride); - } catch (PackageParserException e) { - throw new IllegalStateException( - "Failed to calculate size of " + params.appPackageName); - } - - if ((existingApp.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0) { - // Internal we can link existing install into place, so we only - // need enough space for the new data. - checkInternalStorage(params.sizeBytes); - stageInternal = true; - } else { - // External we're going to copy existing install into our - // container, so we need footprint of both. - checkExternalStorage(params.sizeBytes + existingSize); - stageInternal = false; - } } else { throw new IllegalArgumentException("Invalid install mode: " + params.mode); } @@ -563,15 +525,15 @@ public class PackageInstallerService extends IPackageInstaller.Stub { // We're staging to exactly one location File stageDir = null; String stageCid = null; - if (stageInternal) { - stageDir = prepareInternalStageDir(sessionId); + if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) { + stageDir = buildInternalStageDir(sessionId); } else { - stageCid = prepareExternalStageCid(sessionId, params.sizeBytes); + stageCid = buildExternalStageCid(sessionId); } session = new PackageInstallerSession(mInternalCallback, mContext, mPm, mInstallThread.getLooper(), sessionId, userId, installerPackageName, params, - createdMillis, stageDir, stageCid, false); + createdMillis, stageDir, stageCid, false, false); mSessions.put(sessionId, session); } @@ -615,32 +577,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } } - private void checkInternalStorage(long sizeBytes) throws IOException { - if (sizeBytes <= 0) return; - - final File target = Environment.getDataDirectory(); - final long targetBytes = sizeBytes + mStorage.getStorageLowBytes(target); - - mPm.freeStorage(targetBytes); - if (target.getUsableSpace() < targetBytes) { - throw new IOException("Not enough internal space to write " + sizeBytes + " bytes"); - } - } - - private void checkExternalStorage(long sizeBytes) throws IOException { - if (sizeBytes <= 0) return; - - final File target = new UserEnvironment(UserHandle.USER_OWNER) - .getExternalStorageDirectory(); - final long targetBytes = sizeBytes + mStorage.getStorageLowBytes(target); - - if (target.getUsableSpace() < targetBytes) { - throw new IOException("Not enough external space to write " + sizeBytes + " bytes"); + @Override + public IPackageInstallerSession openSession(int sessionId) { + try { + return openSessionInternal(sessionId); + } catch (IOException e) { + throw ExceptionUtils.wrap(e); } } - @Override - public IPackageInstallerSession openSession(int sessionId) { + private IPackageInstallerSession openSessionInternal(int sessionId) throws IOException { synchronized (mSessions) { final PackageInstallerSession session = mSessions.get(sessionId); if (session == null || !isCallingUidOwner(session)) { @@ -665,40 +611,37 @@ public class PackageInstallerService extends IPackageInstaller.Stub { throw new IllegalStateException("Failed to allocate session ID"); } - private File prepareInternalStageDir(int sessionId) throws IOException { - final File file = new File(mStagingDir, "vmdl" + sessionId + ".tmp"); + private File buildInternalStageDir(int sessionId) { + return new File(mStagingDir, "vmdl" + sessionId + ".tmp"); + } - if (file.exists()) { - throw new IOException("Session dir already exists: " + file); + static void prepareInternalStageDir(File stageDir) throws IOException { + if (stageDir.exists()) { + throw new IOException("Session dir already exists: " + stageDir); } try { - Os.mkdir(file.getAbsolutePath(), 0755); - Os.chmod(file.getAbsolutePath(), 0755); + Os.mkdir(stageDir.getAbsolutePath(), 0755); + Os.chmod(stageDir.getAbsolutePath(), 0755); } catch (ErrnoException e) { // This purposefully throws if directory already exists - throw new IOException("Failed to prepare session dir", e); + throw new IOException("Failed to prepare session dir: " + stageDir, e); } - if (!SELinux.restorecon(file)) { - throw new IOException("Failed to restorecon session dir"); + if (!SELinux.restorecon(stageDir)) { + throw new IOException("Failed to restorecon session dir: " + stageDir); } - - return file; } - private String prepareExternalStageCid(int sessionId, long sizeBytes) throws IOException { - if (sizeBytes <= 0) { - throw new IOException("Session must provide valid size for ASEC"); - } + private String buildExternalStageCid(int sessionId) { + return "smdl" + sessionId + ".tmp"; + } - final String cid = "smdl" + sessionId + ".tmp"; - if (PackageHelper.createSdDir(sizeBytes, cid, PackageManagerService.getEncryptKey(), + static void prepareExternalStageCid(String stageCid, long sizeBytes) throws IOException { + if (PackageHelper.createSdDir(sizeBytes, stageCid, PackageManagerService.getEncryptKey(), Process.SYSTEM_UID, true) == null) { - throw new IOException("Failed to create ASEC"); + throw new IOException("Failed to create session cid: " + stageCid); } - - return cid; } @Override @@ -1031,6 +974,12 @@ public class PackageInstallerService extends IPackageInstaller.Stub { writeSessionsAsync(); } + public void onSessionPrepared(PackageInstallerSession session) { + // We prepared the destination to write into; we want to persist + // this, but it's not critical enough to block for. + writeSessionsAsync(); + } + public void onSessionSealed(PackageInstallerSession session) { // It's very important that we block until we've recorded the // session as being sealed, since we never want to allow mutation diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index f8273c0..06f550d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -17,15 +17,15 @@ package com.android.server.pm; import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED; -import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; -import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; import static android.system.OsConstants.O_CREAT; import static android.system.OsConstants.O_RDONLY; import static android.system.OsConstants.O_WRONLY; +import static com.android.server.pm.PackageInstallerService.prepareExternalStageCid; +import static com.android.server.pm.PackageInstallerService.prepareInternalStageDir; import android.content.Context; import android.content.Intent; @@ -88,8 +88,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // TODO: enforce INSTALL_ALLOW_TEST // TODO: enforce INSTALL_ALLOW_DOWNGRADE - // TODO: treat INHERIT_EXISTING as installExistingPackage() - private final PackageInstallerService.InternalCallback mCallback; private final Context mContext; private final PackageManagerService mPm; @@ -108,18 +106,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { /** Note that UID is not persisted; it's always derived at runtime. */ final int installerUid; - private final AtomicInteger mOpenCount = new AtomicInteger(); + private final AtomicInteger mActiveCount = new AtomicInteger(); private final Object mLock = new Object(); @GuardedBy("mLock") private float mClientProgress = 0; @GuardedBy("mLock") + private float mInternalProgress = 0; + + @GuardedBy("mLock") private float mProgress = 0; @GuardedBy("mLock") private float mReportedProgress = -1; @GuardedBy("mLock") + private boolean mPrepared = false; + @GuardedBy("mLock") private boolean mSealed = false; @GuardedBy("mLock") private boolean mPermissionsAccepted = false; @@ -184,7 +187,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public PackageInstallerSession(PackageInstallerService.InternalCallback callback, Context context, PackageManagerService pm, Looper looper, int sessionId, int userId, String installerPackageName, SessionParams params, long createdMillis, - File stageDir, String stageCid, boolean sealed) { + File stageDir, String stageCid, boolean prepared, boolean sealed) { mCallback = callback; mContext = context; mPm = pm; @@ -203,6 +206,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { "Exactly one of stageDir or stageCid stage must be set"); } + mPrepared = prepared; mSealed = sealed; // Always derived at runtime @@ -214,8 +218,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } else { mPermissionsAccepted = false; } - - computeProgressLocked(); } public SessionInfo generateInfo() { @@ -227,7 +229,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mResolvedBaseFile.getAbsolutePath() : null; info.progress = mProgress; info.sealed = mSealed; - info.active = mOpenCount.get() > 0; + info.active = mActiveCount.get() > 0; info.mode = params.mode; info.sizeBytes = params.sizeBytes; @@ -238,14 +240,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return info; } + public boolean isPrepared() { + synchronized (mLock) { + return mPrepared; + } + } + public boolean isSealed() { synchronized (mLock) { return mSealed; } } - private void assertNotSealed(String cookie) { + private void assertPreparedAndNotSealed(String cookie) { synchronized (mLock) { + if (!mPrepared) { + throw new IllegalStateException(cookie + " before prepared"); + } if (mSealed) { throw new SecurityException(cookie + " not allowed after commit"); } @@ -278,30 +289,26 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void setClientProgress(float progress) { synchronized (mLock) { + // Always publish first staging movement + final boolean forcePublish = (mClientProgress == 0); mClientProgress = progress; - computeProgressLocked(); + computeProgressLocked(forcePublish); } - maybePublishProgress(); } @Override public void addClientProgress(float progress) { synchronized (mLock) { - mClientProgress += progress; - computeProgressLocked(); + setClientProgress(mClientProgress + progress); } - maybePublishProgress(); } - private void computeProgressLocked() { - if (mProgress <= 0.8f) { - mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f); - } - } + private void computeProgressLocked(boolean forcePublish) { + mProgress = MathUtils.constrain(mClientProgress * 0.8f, 0f, 0.8f) + + MathUtils.constrain(mInternalProgress * 0.2f, 0f, 0.2f); - private void maybePublishProgress() { // Only publish when meaningful change - if (Math.abs(mProgress - mReportedProgress) > 0.01) { + if (forcePublish || Math.abs(mProgress - mReportedProgress) >= 0.01) { mReportedProgress = mProgress; mCallback.onSessionProgressChanged(this, mProgress); } @@ -309,7 +316,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public String[] getNames() { - assertNotSealed("getNames"); + assertPreparedAndNotSealed("getNames"); try { return resolveStageDir().list(); } catch (IOException e) { @@ -333,7 +340,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // will block any attempted install transitions. final FileBridge bridge; synchronized (mLock) { - assertNotSealed("openWrite"); + assertPreparedAndNotSealed("openWrite"); bridge = new FileBridge(); mBridges.add(bridge); @@ -387,7 +394,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } private ParcelFileDescriptor openReadInternal(String name) throws IOException { - assertNotSealed("openRead"); + assertPreparedAndNotSealed("openRead"); try { if (!FileUtils.isValidExtFilename(name)) { @@ -407,6 +414,30 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public void commit(IntentSender statusReceiver) { Preconditions.checkNotNull(statusReceiver); + synchronized (mLock) { + if (!mSealed) { + // Verify that all writers are hands-off + for (FileBridge bridge : mBridges) { + if (!bridge.isClosed()) { + throw new SecurityException("Files still open"); + } + } + + // Persist the fact that we've sealed ourselves to prevent + // mutations of any hard links we create. + mSealed = true; + mCallback.onSessionSealed(this); + } + } + + // Client staging is fully done at this point + mClientProgress = 1f; + computeProgressLocked(true); + + // This ongoing commit should keep session active, even though client + // will probably close their end. + mActiveCount.incrementAndGet(); + final PackageInstallObserverAdapter adapter = new PackageInstallObserverAdapter(mContext, statusReceiver, sessionId); mHandler.obtainMessage(MSG_COMMIT, adapter.getBinder()).sendToTarget(); @@ -414,22 +445,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private void commitLocked() throws PackageManagerException { if (mDestroyed) { - throw new PackageManagerException(INSTALL_FAILED_ALREADY_EXISTS, "Invalid session"); + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed"); } - - // Verify that all writers are hands-off if (!mSealed) { - for (FileBridge bridge : mBridges) { - if (!bridge.isClosed()) { - throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED, - "Files still open"); - } - } - mSealed = true; - - // Persist the fact that we've sealed ourselves to prevent mutations - // of any hard links we create below. - mCallback.onSessionSealed(this); + throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed"); } try { @@ -458,6 +477,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mRemoteObserver.onUserActionRequired(intent); } catch (RemoteException ignored) { } + + // Commit was keeping session marked as active until now; release + // that extra refcount so session appears idle. + close(); return; } @@ -487,8 +510,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } // TODO: surface more granular state from dexopt - mProgress = 0.9f; - maybePublishProgress(); + mInternalProgress = 0.5f; + computeProgressLocked(true); // Unpack native libraries extractNativeLibraries(mResolvedStageDir, params.abiOverride); @@ -556,8 +579,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { try { apk = PackageParser.parseApkLite(file, PackageParser.PARSE_COLLECT_CERTIFICATES); } catch (PackageParserException e) { - throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Failed to parse " + file + ": " + e); + throw PackageManagerException.from(e); } if (!stagedSplits.add(apk.splitName)) { @@ -623,8 +645,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { existingBase = PackageParser.parseApkLite(new File(app.getBaseCodePath()), PackageParser.PARSE_COLLECT_CERTIFICATES); } catch (PackageParserException e) { - throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Failed to parse existing package " + app.getCodePath() + ": " + e); + throw PackageManagerException.from(e); } assertApkConsistent("Existing base", existingBase); @@ -676,8 +697,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { try { baseApk = PackageParser.parseApkLite(mResolvedBaseFile, 0); } catch (PackageParserException e) { - throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, - "Failed to parse base package " + mResolvedBaseFile + ": " + e); + throw PackageManagerException.from(e); } final List<String> splitPaths = new ArrayList<>(); @@ -831,15 +851,35 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } - public void open() { - if (mOpenCount.getAndIncrement() == 0) { + public void open() throws IOException { + if (mActiveCount.getAndIncrement() == 0) { mCallback.onSessionActiveChanged(this, true); } + + synchronized (mLock) { + if (!mPrepared) { + if (stageDir != null) { + prepareInternalStageDir(stageDir); + } else if (stageCid != null) { + prepareExternalStageCid(stageCid, params.sizeBytes); + + // TODO: deliver more granular progress for ASEC allocation + mInternalProgress = 0.25f; + computeProgressLocked(true); + } else { + throw new IllegalArgumentException( + "Exactly one of stageDir or stageCid stage must be set"); + } + + mPrepared = true; + mCallback.onSessionPrepared(this); + } + } } @Override public void close() { - if (mOpenCount.decrementAndGet() == 0) { + if (mActiveCount.decrementAndGet() == 0) { mCallback.onSessionActiveChanged(this, false); } } @@ -869,6 +909,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { synchronized (mLock) { mSealed = true; mDestroyed = true; + + // Force shut down all bridges + for (FileBridge bridge : mBridges) { + bridge.forceClose(); + } } if (stageDir != null) { FileUtils.deleteContents(stageDir); diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java index 0cbdcdc..a41636e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerException.java +++ b/services/core/java/com/android/server/pm/PackageManagerException.java @@ -16,6 +16,8 @@ package com.android.server.pm; +import android.content.pm.PackageParser.PackageParserException; + /** {@hide} */ public class PackageManagerException extends Exception { public final int error; @@ -29,4 +31,9 @@ public class PackageManagerException extends Exception { super(detailMessage, throwable); this.error = error; } + + public static PackageManagerException from(PackageParserException e) + throws PackageManagerException { + throw new PackageManagerException(e.error, e.getMessage(), e.getCause()); + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7b4270b..d821fc1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3240,32 +3240,31 @@ public class PackageManagerService extends IPackageManager.Stub { // reader synchronized (mPackages) { final String pkgName = intent.getPackage(); - boolean queryCrossProfile = (flags & PackageManager.NO_CROSS_PROFILE) == 0; if (pkgName == null) { ResolveInfo resolveInfo = null; - if (queryCrossProfile) { - // Check if the intent needs to be forwarded to another user for this package - ArrayList<ResolveInfo> crossProfileResult = - queryIntentActivitiesCrossProfilePackage( - intent, resolvedType, flags, userId); - if (!crossProfileResult.isEmpty()) { - // Skip the current profile - return crossProfileResult; - } - List<CrossProfileIntentFilter> matchingFilters = - getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); - // Check for results that need to skip the current profile. - resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, - resolvedType, flags, userId); - if (resolveInfo != null) { - List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); - result.add(resolveInfo); - return result; - } - // Check for cross profile results. - resolveInfo = queryCrossProfileIntents( - matchingFilters, intent, resolvedType, flags, userId); + + // Check if the intent needs to be forwarded to another user for this package + ArrayList<ResolveInfo> crossProfileResult = + queryIntentActivitiesCrossProfilePackage( + intent, resolvedType, flags, userId); + if (!crossProfileResult.isEmpty()) { + // Skip the current profile + return crossProfileResult; + } + List<CrossProfileIntentFilter> matchingFilters = + getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); + // Check for results that need to skip the current profile. + resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent, + resolvedType, flags, userId); + if (resolveInfo != null) { + List<ResolveInfo> result = new ArrayList<ResolveInfo>(1); + result.add(resolveInfo); + return result; } + // Check for cross profile results. + resolveInfo = queryCrossProfileIntents( + matchingFilters, intent, resolvedType, flags, userId); + // Check for results in the current profile. List<ResolveInfo> result = mActivities.queryIntent( intent, resolvedType, flags, userId); @@ -3277,14 +3276,12 @@ public class PackageManagerService extends IPackageManager.Stub { } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { - if (queryCrossProfile) { - ArrayList<ResolveInfo> crossProfileResult = - queryIntentActivitiesCrossProfilePackage( - intent, resolvedType, flags, userId, pkg, pkgName); - if (!crossProfileResult.isEmpty()) { - // Skip the current profile - return crossProfileResult; - } + ArrayList<ResolveInfo> crossProfileResult = + queryIntentActivitiesCrossProfilePackage( + intent, resolvedType, flags, userId, pkg, pkgName); + if (!crossProfileResult.isEmpty()) { + // Skip the current profile + return crossProfileResult; } return mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId); @@ -4165,8 +4162,7 @@ public class PackageManagerService extends IPackageManager.Stub { pp.collectCertificates(pkg, parseFlags); pp.collectManifestDigest(pkg); } catch (PackageParserException e) { - throw new PackageManagerException(e.error, "Failed to collect certificates for " - + pkg.packageName + ": " + e.getMessage()); + throw PackageManagerException.from(e); } } @@ -4191,8 +4187,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { pkg = pp.parsePackage(scanFile, parseFlags); } catch (PackageParserException e) { - throw new PackageManagerException(e.error, - "Failed to scan " + scanFile + ": " + e.getMessage()); + throw PackageManagerException.from(e); } PackageSetting ps = null; diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 4a2cece..d032d29 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -21,7 +21,6 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerNative; -import android.app.ActivityThread; import android.app.IStopUserCallback; import android.content.BroadcastReceiver; import android.content.Context; @@ -92,6 +91,7 @@ public class UserManagerService extends IUserManager.Stub { private static final String ATTR_SERIAL_NO = "serialNumber"; private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber"; private static final String ATTR_PARTIAL = "partial"; + private static final String ATTR_GUEST_TO_REMOVE = "guestToRemove"; private static final String ATTR_USER_VERSION = "version"; private static final String ATTR_PROFILE_GROUP_ID = "profileGroupId"; private static final String TAG_GUEST_RESTRICTIONS = "guestRestrictions"; @@ -228,7 +228,7 @@ public class UserManagerService extends IUserManager.Stub { ArrayList<UserInfo> partials = new ArrayList<UserInfo>(); for (int i = 0; i < mUsers.size(); i++) { UserInfo ui = mUsers.valueAt(i); - if (ui.partial && i != 0) { + if ((ui.partial || ui.guestToRemove) && i != 0) { partials.add(ui); } } @@ -759,6 +759,9 @@ public class UserManagerService extends IUserManager.Stub { if (userInfo.partial) { serializer.attribute(null, ATTR_PARTIAL, "true"); } + if (userInfo.guestToRemove) { + serializer.attribute(null, ATTR_GUEST_TO_REMOVE, "true"); + } if (userInfo.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { serializer.attribute(null, ATTR_PROFILE_GROUP_ID, Integer.toString(userInfo.profileGroupId)); @@ -806,7 +809,7 @@ public class UserManagerService extends IUserManager.Stub { serializer.attribute(null, ATTR_NEXT_SERIAL_NO, Integer.toString(mNextSerialNumber)); serializer.attribute(null, ATTR_USER_VERSION, Integer.toString(mUserVersion)); - serializer.startTag(null, TAG_GUEST_RESTRICTIONS); + serializer.startTag(null, TAG_GUEST_RESTRICTIONS); writeRestrictionsLocked(serializer, mGuestRestrictions); serializer.endTag(null, TAG_GUEST_RESTRICTIONS); for (int i = 0; i < mUsers.size(); i++) { @@ -855,6 +858,8 @@ public class UserManagerService extends IUserManager.Stub { writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_CALLS); writeBoolean(serializer, restrictions, UserManager.DISALLOW_SMS); writeBoolean(serializer, restrictions, UserManager.DISALLOW_CREATE_WINDOWS); + writeBoolean(serializer, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); + writeBoolean(serializer, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); serializer.endTag(null, TAG_RESTRICTIONS); } @@ -871,6 +876,7 @@ public class UserManagerService extends IUserManager.Stub { int profileGroupId = UserInfo.NO_PROFILE_GROUP_ID; long lastAttemptTime = 0L; boolean partial = false; + boolean guestToRemove = false; Bundle restrictions = new Bundle(); FileInputStream fis = null; @@ -918,6 +924,10 @@ public class UserManagerService extends IUserManager.Stub { if ("true".equals(valueString)) { partial = true; } + valueString = parser.getAttributeValue(null, ATTR_GUEST_TO_REMOVE); + if ("true".equals(valueString)) { + guestToRemove = true; + } int outerDepth = parser.getDepth(); while ((type = parser.next()) != XmlPullParser.END_DOCUMENT @@ -942,6 +952,7 @@ public class UserManagerService extends IUserManager.Stub { userInfo.creationTime = creationTime; userInfo.lastLoggedInTime = lastLoggedInTime; userInfo.partial = partial; + userInfo.guestToRemove = guestToRemove; userInfo.profileGroupId = profileGroupId; mUserRestrictions.append(id, restrictions); if (salt != 0L) { @@ -999,6 +1010,8 @@ public class UserManagerService extends IUserManager.Stub { readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_CALLS); readBoolean(parser, restrictions, UserManager.DISALLOW_SMS); readBoolean(parser, restrictions, UserManager.DISALLOW_CREATE_WINDOWS); + readBoolean(parser, restrictions, UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); + readBoolean(parser, restrictions, UserManager.DISALLOW_OUTGOING_BEAM); } private void readBoolean(XmlPullParser parser, Bundle restrictions, @@ -1119,7 +1132,7 @@ public class UserManagerService extends IUserManager.Stub { return null; } // If we're adding a guest and there already exists one, bail. - if (isGuest && numberOfUsersOfTypeLocked(UserInfo.FLAG_GUEST, true) > 0) { + if (isGuest && findCurrentGuestUserLocked() != null) { return null; } // Limit number of managed profiles that can be created @@ -1180,6 +1193,23 @@ public class UserManagerService extends IUserManager.Stub { } /** + * Find the current guest user. If the Guest user is partial, + * then do not include it in the results as it is about to die. + * This is different than {@link #numberOfUsersOfTypeLocked(int, boolean)} due to + * the special handling of Guests being removed. + */ + private UserInfo findCurrentGuestUserLocked() { + final int size = mUsers.size(); + for (int i = 0; i < size; i++) { + final UserInfo user = mUsers.valueAt(i); + if (user.isGuest() && !user.guestToRemove && !mRemovingUserIds.get(user.id)) { + return user; + } + } + return null; + } + + /** * Mark this guest user for deletion to allow us to create another guest * and switch to that user before actually removing this guest. * @param userHandle the userid of the current guest @@ -1204,14 +1234,15 @@ public class UserManagerService extends IUserManager.Stub { if (!user.isGuest()) { return false; } - // Set this to a partially created user, so that the user will be purged - // on next startup, in case the runtime stops now before stopping and - // removing the user completely. - user.partial = true; + // We set this to a guest user that is to be removed. This is a temporary state + // where we are allowed to add new Guest users, even if this one is still not + // removed. This user will still show up in getUserInfo() calls. + // If we don't get around to removing this Guest user, it will be purged on next + // startup. + user.guestToRemove = true; // Mark it as disabled, so that it isn't returned any more when // profiles are queried. user.flags |= UserInfo.FLAG_DISABLED; - user.flags &= ~UserInfo.FLAG_GUEST; writeUserLocked(user); } } finally { diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index c8b5b3e..fefbe0a 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -33,6 +33,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; @@ -48,6 +49,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.provider.Settings; import android.service.trust.TrustAgentService; import android.util.ArraySet; import android.util.AttributeSet; @@ -97,6 +99,7 @@ public class TrustManagerService extends SystemService { private final SparseBooleanArray mUserHasAuthenticatedSinceBoot = new SparseBooleanArray(); /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; + private final LockPatternUtils mLockPatternUtils; private UserManager mUserManager; @@ -104,6 +107,7 @@ public class TrustManagerService extends SystemService { super(context); mContext = context; mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); + mLockPatternUtils = new LockPatternUtils(context); } @Override @@ -116,6 +120,7 @@ public class TrustManagerService extends SystemService { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) { mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); mReceiver.register(mContext); + maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER); refreshAgentList(UserHandle.USER_ALL); } } @@ -159,6 +164,11 @@ public class TrustManagerService extends SystemService { void refreshAgentList(int userId) { if (DEBUG) Slog.d(TAG, "refreshAgentList()"); + if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_OWNER) { + Log.e(TAG, "refreshAgentList(userId=" + userId + "): Invalid user handle," + + " must be USER_ALL or a specific user.", new Throwable("here")); + userId = UserHandle.USER_ALL; + } PackageManager pm = mContext.getPackageManager(); List<UserInfo> userInfos; @@ -168,12 +178,13 @@ public class TrustManagerService extends SystemService { userInfos = new ArrayList<>(); userInfos.add(mUserManager.getUserInfo(userId)); } - LockPatternUtils lockPatternUtils = new LockPatternUtils(mContext); + LockPatternUtils lockPatternUtils = mLockPatternUtils; ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>(); obsoleteAgents.addAll(mActiveAgents); for (UserInfo userInfo : userInfos) { + if (!userInfo.supportsSwitchTo()) continue; if (lockPatternUtils.getKeyguardStoredPasswordQuality(userInfo.id) == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) continue; if (!mUserHasAuthenticatedSinceBoot.get(userInfo.id)) continue; @@ -186,22 +197,11 @@ public class TrustManagerService extends SystemService { if (enabledAgents == null) { continue; } - List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT, - PackageManager.GET_META_DATA, userInfo.id); + List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id); for (ResolveInfo resolveInfo : resolveInfos) { - if (resolveInfo.serviceInfo == null) continue; - - String packageName = resolveInfo.serviceInfo.packageName; - if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName) - != PackageManager.PERMISSION_GRANTED) { - Log.w(TAG, "Skipping agent because package " + packageName - + " does not have permission " + PERMISSION_PROVIDE_AGENT + "."); - continue; - } - ComponentName name = getComponentName(resolveInfo); - if (!enabledAgents.contains(name)) continue; + if (!enabledAgents.contains(name)) continue; if (disableTrustAgents) { List<String> features = dpm.getTrustAgentFeaturesEnabled(null /* admin */, name); @@ -228,11 +228,13 @@ public class TrustManagerService extends SystemService { boolean trustMayHaveChanged = false; for (int i = 0; i < obsoleteAgents.size(); i++) { AgentInfo info = obsoleteAgents.valueAt(i); - if (info.agent.isManagingTrust()) { - trustMayHaveChanged = true; + if (userId == UserHandle.USER_ALL || userId == info.userId) { + if (info.agent.isManagingTrust()) { + trustMayHaveChanged = true; + } + info.agent.unbind(); + mActiveAgents.remove(info); } - info.agent.unbind(); - mActiveAgents.remove(info); } if (trustMayHaveChanged) { @@ -342,6 +344,54 @@ public class TrustManagerService extends SystemService { return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name); } + private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) { + if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) { + return; + } + PackageManager pm = mContext.getPackageManager(); + List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId); + ArraySet<ComponentName> discoveredAgents = new ArraySet<>(); + for (ResolveInfo resolveInfo : resolveInfos) { + ComponentName componentName = getComponentName(resolveInfo); + int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags; + if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { + Log.i(TAG, "Leaving agent " + componentName + " disabled because package " + + "is not a system package."); + continue; + } + discoveredAgents.add(componentName); + } + + List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId); + if (previouslyEnabledAgents != null) { + discoveredAgents.addAll(previouslyEnabledAgents); + } + utils.setEnabledTrustAgents(discoveredAgents, userId); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId); + } + + private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) { + List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT, + 0 /* flags */, userId); + ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size()); + for (ResolveInfo resolveInfo : resolveInfos) { + if (resolveInfo.serviceInfo == null) continue; + if (resolveInfo.serviceInfo.applicationInfo == null) continue; + String packageName = resolveInfo.serviceInfo.packageName; + if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName) + != PackageManager.PERMISSION_GRANTED) { + ComponentName name = getComponentName(resolveInfo); + Log.w(TAG, "Skipping agent " + name + " because package does not have" + + " permission " + PERMISSION_PROVIDE_AGENT + "."); + continue; + } + allowedAgents.add(resolveInfo); + } + return allowedAgents; + } + // Agent dispatch and aggregation private boolean aggregateIsTrusted(int userId) { @@ -414,6 +464,7 @@ public class TrustManagerService extends SystemService { } } mTrustListeners.add(listener); + updateTrustAll(); } private void removeListener(ITrustListener listener) { @@ -616,12 +667,19 @@ public class TrustManagerService extends SystemService { @Override public void onReceive(Context context, Intent intent) { - if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals( - intent.getAction())) { + String action = intent.getAction(); + if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) { refreshAgentList(getSendingUserId()); updateDevicePolicyFeatures(); - } else if (Intent.ACTION_USER_PRESENT.equals(intent.getAction())) { + } else if (Intent.ACTION_USER_PRESENT.equals(action)) { updateUserHasAuthenticated(getSendingUserId()); + } else if (Intent.ACTION_USER_ADDED.equals(action)) { + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100); + if (userId > 0) { + maybeEnableFactoryTrustAgents(mLockPatternUtils, userId); + } else { + Log.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId); + } } } @@ -629,6 +687,7 @@ public class TrustManagerService extends SystemService { IntentFilter filter = new IntentFilter(); filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); filter.addAction(Intent.ACTION_USER_PRESENT); + filter.addAction(Intent.ACTION_USER_ADDED); context.registerReceiverAsUser(this, UserHandle.ALL, filter, diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 802df95..e1ade63 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -42,6 +42,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Point; +import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.Environment; @@ -206,6 +207,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { int width = -1; int height = -1; + final Rect padding = new Rect(0, 0, 0, 0); + WallpaperData(int userId) { this.userId = userId; wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER); @@ -222,6 +225,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { IRemoteCallback mReply; boolean mDimensionsChanged = false; + boolean mPaddingChanged = false; public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) { mInfo = info; @@ -283,6 +287,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } mDimensionsChanged = false; } + if (mPaddingChanged) { + try { + mEngine.setDisplayPadding(mWallpaper.padding); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to set wallpaper padding", e); + } + mPaddingChanged = false; + } } } @@ -719,6 +731,40 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } } + public void setDisplayPadding(Rect padding) { + checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS); + synchronized (mLock) { + int userId = UserHandle.getCallingUserId(); + WallpaperData wallpaper = mWallpaperMap.get(userId); + if (wallpaper == null) { + throw new IllegalStateException("Wallpaper not yet initialized for user " + userId); + } + if (padding.left < 0 || padding.top < 0 || padding.right < 0 || padding.bottom < 0) { + throw new IllegalArgumentException("padding must be positive: " + padding); + } + + if (!padding.equals(wallpaper.padding)) { + wallpaper.padding.set(padding); + saveSettingsLocked(wallpaper); + if (mCurrentUserId != userId) return; // Don't change the properties now + if (wallpaper.connection != null) { + if (wallpaper.connection.mEngine != null) { + try { + wallpaper.connection.mEngine.setDisplayPadding(padding); + } catch (RemoteException e) { + } + notifyCallbacksLocked(wallpaper); + } else if (wallpaper.connection.mService != null) { + // We've attached to the service but the engine hasn't attached back to us + // yet. This means it will be created with the previous dimensions, so we + // need to update it to the new dimensions once it attaches. + wallpaper.connection.mPaddingChanged = true; + } + } + } + } + } + public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, Bundle outParams) { synchronized (mLock) { @@ -1006,7 +1052,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { try { conn.mService.attach(conn, conn.mToken, WindowManager.LayoutParams.TYPE_WALLPAPER, false, - wallpaper.width, wallpaper.height); + wallpaper.width, wallpaper.height, wallpaper.padding); } catch (RemoteException e) { Slog.w(TAG, "Failed attaching wallpaper; clearing", e); if (!wallpaper.wallpaperUpdating) { @@ -1055,6 +1101,18 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { out.startTag(null, "wp"); out.attribute(null, "width", Integer.toString(wallpaper.width)); out.attribute(null, "height", Integer.toString(wallpaper.height)); + if (wallpaper.padding.left != 0) { + out.attribute(null, "paddingLeft", Integer.toString(wallpaper.padding.left)); + } + if (wallpaper.padding.top != 0) { + out.attribute(null, "paddingTop", Integer.toString(wallpaper.padding.top)); + } + if (wallpaper.padding.right != 0) { + out.attribute(null, "paddingRight", Integer.toString(wallpaper.padding.right)); + } + if (wallpaper.padding.bottom != 0) { + out.attribute(null, "paddingBottom", Integer.toString(wallpaper.padding.bottom)); + } out.attribute(null, "name", wallpaper.name); if (wallpaper.wallpaperComponent != null && !wallpaper.wallpaperComponent.equals(mImageWallpaper)) { @@ -1091,6 +1149,14 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } } + private int getAttributeInt(XmlPullParser parser, String name, int defValue) { + String value = parser.getAttributeValue(null, name); + if (value == null) { + return defValue; + } + return Integer.parseInt(value); + } + private void loadSettingsLocked(int userId) { if (DEBUG) Slog.v(TAG, "loadSettingsLocked"); @@ -1121,6 +1187,10 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width")); wallpaper.height = Integer.parseInt(parser .getAttributeValue(null, "height")); + wallpaper.padding.left = getAttributeInt(parser, "paddingLeft", 0); + wallpaper.padding.top = getAttributeInt(parser, "paddingTop", 0); + wallpaper.padding.right = getAttributeInt(parser, "paddingRight", 0); + wallpaper.padding.bottom = getAttributeInt(parser, "paddingBottom", 0); wallpaper.name = parser.getAttributeValue(null, "name"); String comp = parser.getAttributeValue(null, "component"); wallpaper.nextWallpaperComponent = comp != null @@ -1167,6 +1237,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { if (!success) { wallpaper.width = -1; wallpaper.height = -1; + wallpaper.padding.set(0, 0, 0, 0); wallpaper.name = ""; } @@ -1330,13 +1401,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { WallpaperData wallpaper = mWallpaperMap.valueAt(i); pw.println(" User " + wallpaper.userId + ":"); pw.print(" mWidth="); - pw.print(wallpaper.width); - pw.print(" mHeight="); - pw.println(wallpaper.height); - pw.print(" mName="); - pw.println(wallpaper.name); - pw.print(" mWallpaperComponent="); - pw.println(wallpaper.wallpaperComponent); + pw.print(wallpaper.width); + pw.print(" mHeight="); + pw.println(wallpaper.height); + pw.print(" mPadding="); pw.println(wallpaper.padding); + pw.print(" mName="); pw.println(wallpaper.name); + pw.print(" mWallpaperComponent="); pw.println(wallpaper.wallpaperComponent); if (wallpaper.connection != null) { WallpaperConnection conn = wallpaper.connection; pw.print(" Wallpaper connection "); diff --git a/services/core/java/com/android/server/wm/CircularDisplayMask.java b/services/core/java/com/android/server/wm/CircularDisplayMask.java index 64b852b..a7d41fa 100644 --- a/services/core/java/com/android/server/wm/CircularDisplayMask.java +++ b/services/core/java/com/android/server/wm/CircularDisplayMask.java @@ -63,8 +63,14 @@ class CircularDisplayMask { SurfaceControl ctrl = null; try { - ctrl = new SurfaceControl(session, "CircularDisplayMask", - mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + if (WindowManagerService.DEBUG_SURFACE_TRACE) { + ctrl = new WindowStateAnimator.SurfaceTrace(session, "CircularDisplayMask", + mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, + SurfaceControl.HIDDEN); + } else { + ctrl = new SurfaceControl(session, "CircularDisplayMask", mScreenSize.x, + mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + } ctrl.setLayerStack(display.getLayerStack()); ctrl.setLayer(zOrder); ctrl.setPosition(0, 0); diff --git a/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java new file mode 100644 index 0000000..62f2b48 --- /dev/null +++ b/services/core/java/com/android/server/wm/EmulatorDisplayOverlay.java @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wm; + + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PixelFormat; +import android.graphics.Point; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.Slog; +import android.view.Display; +import android.view.Surface; +import android.view.Surface.OutOfResourcesException; +import android.view.SurfaceControl; +import android.view.SurfaceSession; + +class EmulatorDisplayOverlay { + private static final String TAG = "EmulatorDisplayOverlay"; + + // Display dimensions + private Point mScreenSize; + + private final SurfaceControl mSurfaceControl; + private final Surface mSurface = new Surface(); + private int mLastDW; + private int mLastDH; + private boolean mDrawNeeded; + private Drawable mOverlay; + private int mRotation; + private boolean mVisible; + + public EmulatorDisplayOverlay(Context context, Display display, SurfaceSession session, + int zOrder) { + mScreenSize = new Point(); + display.getSize(mScreenSize); + + SurfaceControl ctrl = null; + try { + if (WindowManagerService.DEBUG_SURFACE_TRACE) { + ctrl = new WindowStateAnimator.SurfaceTrace(session, "EmulatorDisplayOverlay", + mScreenSize.x, mScreenSize.y, PixelFormat.TRANSLUCENT, + SurfaceControl.HIDDEN); + } else { + ctrl = new SurfaceControl(session, "EmulatorDisplayOverlay", mScreenSize.x, + mScreenSize.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + } + ctrl.setLayerStack(display.getLayerStack()); + ctrl.setLayer(zOrder); + ctrl.setPosition(0, 0); + ctrl.show(); + mSurface.copyFrom(ctrl); + } catch (OutOfResourcesException e) { + } + mSurfaceControl = ctrl; + mDrawNeeded = true; + mOverlay = context.getDrawable( + com.android.internal.R.drawable.emulator_circular_window_overlay); + } + + private void drawIfNeeded() { + if (!mDrawNeeded || !mVisible) { + return; + } + mDrawNeeded = false; + + Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y); + Canvas c = null; + try { + c = mSurface.lockCanvas(dirty); + } catch (IllegalArgumentException e) { + } catch (OutOfResourcesException e) { + } + if (c == null) { + return; + } + c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC); + mSurfaceControl.setPosition(0, 0); + mOverlay.setBounds(0, 0, mScreenSize.x, mScreenSize.y); + mOverlay.draw(c); + mSurface.unlockCanvasAndPost(c); + } + + // Note: caller responsible for being inside + // Surface.openTransaction() / closeTransaction() + public void setVisibility(boolean on) { + if (mSurfaceControl == null) { + return; + } + mVisible = on; + drawIfNeeded(); + if (on) { + mSurfaceControl.show(); + } else { + mSurfaceControl.hide(); + } + } + + void positionSurface(int dw, int dh, int rotation) { + if (mLastDW == dw && mLastDH == dh && mRotation == rotation) { + return; + } + mLastDW = dw; + mLastDH = dh; + mDrawNeeded = true; + mRotation = rotation; + drawIfNeeded(); + } + +} diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index f2703ad..d737e7f 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -415,6 +415,18 @@ final class Session extends IWindowSession.Stub mService.wallpaperOffsetsComplete(window); } + public void setWallpaperDisplayOffset(IBinder window, int x, int y) { + synchronized(mService.mWindowMap) { + long ident = Binder.clearCallingIdentity(); + try { + mService.setWindowWallpaperDisplayOffsetLocked( + mService.windowForClientLocked(this, window, true), x, y); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, int z, Bundle extras, boolean sync) { synchronized(mService.mWindowMap) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 55c6d81..10ab6b5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams.*; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import android.app.AppOpsManager; +import android.os.Build; import android.util.ArraySet; import android.util.TimeUtils; import android.view.IWindowId; @@ -295,6 +296,8 @@ public class WindowManagerService extends IWindowManager.Stub private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular"; + final private KeyguardDisableHandler mKeyguardDisableHandler; final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @@ -441,6 +444,7 @@ public class WindowManagerService extends IWindowManager.Stub Watermark mWatermark; StrictModeFlash mStrictModeFlash; CircularDisplayMask mCircularDisplayMask; + EmulatorDisplayOverlay mEmulatorDisplayOverlay; FocusedStackFrame mFocusedStackFrame; int mFocusedStackLayer; @@ -572,6 +576,8 @@ public class WindowManagerService extends IWindowManager.Stub float mLastWallpaperY = -1; float mLastWallpaperXStep = -1; float mLastWallpaperYStep = -1; + int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE; + int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE; // This is set when we are waiting for a wallpaper to tell us it is done // changing its scroll position. WindowState mWaitingOnWallpaper; @@ -879,6 +885,7 @@ public class WindowManagerService extends IWindowManager.Stub } showCircularDisplayMaskIfNeeded(); + showEmulatorDisplayOverlayIfNeeded(); } public InputMonitor getInputMonitor() { @@ -1892,6 +1899,12 @@ public class WindowManagerService extends IWindowManager.Stub mLastWallpaperY = mWallpaperTarget.mWallpaperY; mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep; } + if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX; + } + if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY; + } } // Start stepping backwards from here, ensuring that our wallpaper windows @@ -2030,6 +2043,9 @@ public class WindowManagerService extends IWindowManager.Stub float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f; int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw; int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0; + if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) { + offset += mLastWallpaperDisplayOffsetX; + } changed = wallpaperWin.mXOffset != offset; if (changed) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " @@ -2046,6 +2062,9 @@ public class WindowManagerService extends IWindowManager.Stub float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f; int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh; offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0; + if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + offset += mLastWallpaperDisplayOffsetY; + } if (wallpaperWin.mYOffset != offset) { if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset); @@ -2130,6 +2149,16 @@ public class WindowManagerService extends IWindowManager.Stub } else if (changingTarget.mWallpaperY >= 0) { mLastWallpaperY = changingTarget.mWallpaperY; } + if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX; + } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX; + } + if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY; + } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY; + } } int curTokenIndex = mWallpaperTokens.size(); @@ -2826,6 +2855,14 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void setWindowWallpaperDisplayOffsetLocked(WindowState window, int x, int y) { + if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) { + window.mWallpaperDisplayOffsetX = x; + window.mWallpaperDisplayOffsetY = y; + updateWallpaperOffsetLocked(window, true); + } + } + public Bundle sendWindowWallpaperCommandLocked(WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) { if (window == mWallpaperTarget || window == mLowerWallpaperTarget @@ -5735,7 +5772,16 @@ public class WindowManagerService extends IWindowManager.Stub com.android.internal.R.bool.config_windowIsRound) && mContext.getResources().getBoolean( com.android.internal.R.bool.config_windowShowCircularMask)) { - mH.sendMessage(mH.obtainMessage(H.SHOW_DISPLAY_MASK)); + mH.sendMessage(mH.obtainMessage(H.SHOW_CIRCULAR_DISPLAY_MASK)); + } + } + + public void showEmulatorDisplayOverlayIfNeeded() { + if (mContext.getResources().getBoolean( + com.android.internal.R.bool.config_windowEnableCircularEmulatorDisplayOverlay) + && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false) + && Build.HARDWARE.contains("goldfish")) { + mH.sendMessage(mH.obtainMessage(H.SHOW_EMULATOR_DISPLAY_OVERLAY)); } } @@ -5743,12 +5789,12 @@ public class WindowManagerService extends IWindowManager.Stub synchronized(mWindowMap) { if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, - ">>> OPEN TRANSACTION showDisplayMask"); + ">>> OPEN TRANSACTION showCircularMask"); SurfaceControl.openTransaction(); try { // TODO(multi-display): support multiple displays if (mCircularDisplayMask == null) { - int screenOffset = (int) mContext.getResources().getDimensionPixelSize( + int screenOffset = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.circular_display_mask_offset); mCircularDisplayMask = new CircularDisplayMask( @@ -5762,7 +5808,32 @@ public class WindowManagerService extends IWindowManager.Stub } finally { SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, - "<<< CLOSE TRANSACTION showDisplayMask"); + "<<< CLOSE TRANSACTION showCircularMask"); + } + } + } + + public void showEmulatorDisplayOverlay() { + synchronized(mWindowMap) { + + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + ">>> OPEN TRANSACTION showEmulatorDisplayOverlay"); + SurfaceControl.openTransaction(); + try { + if (mEmulatorDisplayOverlay == null) { + mEmulatorDisplayOverlay = new EmulatorDisplayOverlay( + mContext, + getDefaultDisplayContentLocked().getDisplay(), + mFxSession, + mPolicy.windowTypeToLayerLw( + WindowManager.LayoutParams.TYPE_POINTER) + * TYPE_LAYER_MULTIPLIER + 10); + } + mEmulatorDisplayOverlay.setVisibility(true); + } finally { + SurfaceControl.closeTransaction(); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + "<<< CLOSE TRANSACTION showEmulatorDisplayOverlay"); } } } @@ -5860,7 +5931,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height, boolean force565) { - if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, + if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER, "screenshotApplications()")) { throw new SecurityException("Requires READ_FRAME_BUFFER permission"); } @@ -5880,7 +5951,7 @@ public class WindowManagerService extends IWindowManager.Stub return null; } - Bitmap rawss = null; + Bitmap bm = null; int maxLayer = 0; final Rect frame = new Rect(); @@ -6021,10 +6092,8 @@ public class WindowManagerService extends IWindowManager.Stub // The screenshot API does not apply the current screen rotation. rot = getDefaultDisplayContentLocked().getDisplay().getRotation(); + if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { - final int tmp = width; - width = height; - height = tmp; rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90; } @@ -6050,9 +6119,9 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG, "Taking screenshot while rotating"); - rawss = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer, - inRotation); - if (rawss == null) { + bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer, + inRotation, rot); + if (bm == null) { Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh + ") to layer " + maxLayer); return null; @@ -6062,17 +6131,6 @@ public class WindowManagerService extends IWindowManager.Stub break; } - Bitmap bm = Bitmap.createBitmap(width, height, force565 ? - Config.RGB_565 : rawss.getConfig()); - if (DEBUG_SCREENSHOT) { - bm.eraseColor(0xFF000000); - } - Matrix matrix = new Matrix(); - ScreenRotationAnimation.createRotationMatrix(rot, width, height, matrix); - Canvas canvas = new Canvas(bm); - canvas.drawBitmap(rawss, matrix, null); - canvas.setBitmap(null); - if (DEBUG_SCREENSHOT) { // TEST IF IT's ALL BLACK int[] buffer = new int[bm.getWidth() * bm.getHeight()]; @@ -6093,9 +6151,12 @@ public class WindowManagerService extends IWindowManager.Stub } } - rawss.recycle(); - - return bm; + // Copy the screenshot bitmap to another buffer so that the gralloc backed + // bitmap will not have a long lifetime. Gralloc memory can be pinned or + // duplicated and might have a higher cost than a skia backed buffer. + Bitmap ret = bm.copy(bm.getConfig(),true); + bm.recycle(); + return ret; } /** @@ -7393,7 +7454,8 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NEW_ANIMATOR_SCALE = 34; - public static final int SHOW_DISPLAY_MASK = 35; + public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35; + public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36; @Override public void handleMessage(Message msg) { @@ -7789,11 +7851,16 @@ public class WindowManagerService extends IWindowManager.Stub break; } - case SHOW_DISPLAY_MASK: { + case SHOW_CIRCULAR_DISPLAY_MASK: { showCircularMask(); break; } + case SHOW_EMULATOR_DISPLAY_OVERLAY: { + showEmulatorDisplayOverlay(); + break; + } + case DO_ANIMATION_CALLBACK: { try { ((IRemoteCallback)msg.obj).sendResult(null); @@ -9363,6 +9430,9 @@ public class WindowManagerService extends IWindowManager.Stub if (mCircularDisplayMask != null) { mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mRotation); } + if (mEmulatorDisplayOverlay != null) { + mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh, mRotation); + } boolean focusDisplayed = false; @@ -10889,6 +10959,12 @@ public class WindowManagerService extends IWindowManager.Stub } pw.print(" mLastWallpaperX="); pw.print(mLastWallpaperX); pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY); + if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE + || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + pw.print(" mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX); + pw.print(" mLastWallpaperDisplayOffsetY="); + pw.println(mLastWallpaperDisplayOffsetY); + } if (mInputMethodAnimLayerAdjustment != 0 || mWallpaperAnimLayerAdjustment != 0) { pw.print(" mInputMethodAnimLayerAdjustment="); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e74de38..0baa2be 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -247,6 +247,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { float mWallpaperXStep = -1; float mWallpaperYStep = -1; + // If a window showing a wallpaper: a raw pixel offset to forcibly apply + // to its window; if a wallpaper window: not used. + int mWallpaperDisplayOffsetX = Integer.MIN_VALUE; + int mWallpaperDisplayOffsetY = Integer.MIN_VALUE; + // Wallpaper windows: pixels offset based on above variables. int mXOffset; int mYOffset; @@ -1584,6 +1589,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep); pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep); } + if (mWallpaperDisplayOffsetX != Integer.MIN_VALUE + || mWallpaperDisplayOffsetY != Integer.MIN_VALUE) { + pw.print(prefix); pw.print("mWallpaperDisplayOffsetX="); + pw.print(mWallpaperDisplayOffsetX); + pw.print(" mWallpaperDisplayOffsetY="); + pw.println(mWallpaperDisplayOffsetY); + } } String makeInputChannelName() { diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index a871522..dd611ce 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1526,8 +1526,9 @@ class WindowStateAnimator { } void setWallpaperOffset(RectF shownFrame) { - final int left = (int) shownFrame.left; - final int top = (int) shownFrame.top; + final LayoutParams attrs = mWin.getAttrs(); + final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left; + final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top; if (mSurfaceX != left || mSurfaceY != top) { mSurfaceX = left; mSurfaceY = top; diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index 1f377c7..d81cdd9 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -11,7 +11,6 @@ LOCAL_SRC_FILES += \ $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \ $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \ $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \ - $(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiMhlController.cpp \ $(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \ $(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \ $(LOCAL_REL_DIR)/com_android_server_input_InputWindowHandle.cpp \ diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp index bc866d3..65a28c0 100644 --- a/services/core/jni/com_android_server_UsbHostManager.cpp +++ b/services/core/jni/com_android_server_UsbHostManager.cpp @@ -21,7 +21,6 @@ #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include "android_runtime/Log.h" -#include "utils/Vector.h" #include <usbhost/usbhost.h> @@ -68,8 +67,6 @@ static int usb_device_added(const char *devname, void* client_data) { JNIEnv* env = AndroidRuntime::getJNIEnv(); jobject thiz = (jobject)client_data; - Vector<int> interfaceValues; - Vector<int> endpointValues; const usb_device_descriptor* deviceDesc = usb_device_get_device_descriptor(device); char *manufacturer = usb_device_get_manufacturer_name(device); diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index 39b70a8..7b2e408 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -38,7 +38,6 @@ int register_android_server_location_GpsLocationProvider(JNIEnv* env); int register_android_server_location_FlpHardwareProvider(JNIEnv* env); int register_android_server_connectivity_Vpn(JNIEnv* env); int register_android_server_hdmi_HdmiCecController(JNIEnv* env); -int register_android_server_hdmi_HdmiMhlController(JNIEnv* env); int register_android_server_tv_TvInputHal(JNIEnv* env); int register_android_server_PersistentDataBlockService(JNIEnv* env); int register_android_server_fingerprint_FingerprintService(JNIEnv* env); @@ -76,7 +75,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) register_android_server_ConsumerIrService(env); register_android_server_BatteryStatsService(env); register_android_server_hdmi_HdmiCecController(env); - register_android_server_hdmi_HdmiMhlController(env); register_android_server_tv_TvInputHal(env); register_android_server_PersistentDataBlockService(env); register_android_server_fingerprint_FingerprintService(env); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java index 376230b..ad38b22 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoundTriggerHelper.java @@ -67,7 +67,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { final ModuleProperties moduleProperties; /** The properties for the DSP module */ - private final SoundTriggerModule mModule; + private SoundTriggerModule mModule; private final Object mLock = new Object(); private final Context mContext; private final TelephonyManager mTelephonyManager; @@ -105,7 +105,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { } else { // TODO: Figure out how to determine which module corresponds to the DSP hardware. moduleProperties = modules.get(0); - mModule = SoundTrigger.attachModule(moduleProperties.id, this, null); } } @@ -155,10 +154,17 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { mIsPowerSaveMode = mPowerManager.isPowerSaveMode(); } - if (moduleProperties == null || mModule == null) { + if (moduleProperties == null) { Slog.w(TAG, "Attempting startRecognition without the capability"); return STATUS_ERROR; } + if (mModule == null) { + mModule = SoundTrigger.attachModule(moduleProperties.id, this, null); + if (mModule == null) { + Slog.w(TAG, "startRecognition cannot attach to sound trigger module"); + return STATUS_ERROR; + } + } if (mCurrentSoundModelHandle != INVALID_VALUE && !soundModel.uuid.equals(mCurrentSoundModelUuid)) { @@ -446,6 +452,10 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener { Slog.w(TAG, "RemoteException in onError", e); } finally { internalClearStateLocked(); + if (mModule != null) { + mModule.detach(); + mModule = null; + } } } diff --git a/telecomm/java/android/telecomm/AudioState.java b/telecomm/java/android/telecomm/AudioState.java index a5fda79..314704b 100644 --- a/telecomm/java/android/telecomm/AudioState.java +++ b/telecomm/java/android/telecomm/AudioState.java @@ -34,7 +34,7 @@ public final class AudioState implements Parcelable { /** Direct the audio stream through a wired headset. */ public static final int ROUTE_WIRED_HEADSET = 0x00000004; - /** Direct the audio stream through the device's spakerphone. */ + /** Direct the audio stream through the device's speakerphone. */ public static final int ROUTE_SPEAKER = 0x00000008; /** @@ -43,7 +43,10 @@ public final class AudioState implements Parcelable { */ public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET; - /** Bit mask of all possible audio routes. */ + /** Bit mask of all possible audio routes. + * + * @hide + */ public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET | ROUTE_SPEAKER; diff --git a/telecomm/java/android/telecomm/Conference.java b/telecomm/java/android/telecomm/Conference.java index c838b48..f9c3ac3 100644 --- a/telecomm/java/android/telecomm/Conference.java +++ b/telecomm/java/android/telecomm/Conference.java @@ -54,7 +54,7 @@ public abstract class Conference { mPhoneAccount = phoneAccount; } - public final PhoneAccountHandle getPhoneAccount() { + public final PhoneAccountHandle getPhoneAccountHandle() { return mPhoneAccount; } @@ -183,7 +183,7 @@ public abstract class Conference { } /** - * Tears down the conference object and any of it's current connections. + * Tears down the conference object and any of its current connections. */ public final void destroy() { Log.d(this, "destroying conference : %s", this); diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java index 6df117e..03db1c3 100644 --- a/telecomm/java/android/telecomm/Connection.java +++ b/telecomm/java/android/telecomm/Connection.java @@ -139,7 +139,7 @@ public abstract class Connection { */ public static final int SESSION_MODIFY_REQUEST_INVALID = 3; - private static final int MSG_SET_VIDEO_LISTENER = 1; + private static final int MSG_SET_VIDEO_CALLBACK = 1; private static final int MSG_SET_CAMERA = 2; private static final int MSG_SET_PREVIEW_SURFACE = 3; private static final int MSG_SET_DISPLAY_SURFACE = 4; @@ -154,7 +154,7 @@ public abstract class Connection { private final VideoProvider.VideoProviderHandler mMessageHandler = new VideoProvider.VideoProviderHandler(); private final VideoProvider.VideoProviderBinder mBinder; - private IVideoCallback mVideoListener; + private IVideoCallback mVideoCallback; /** * Default handler used to consolidate binder method calls onto a single thread. @@ -163,8 +163,8 @@ public abstract class Connection { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_SET_VIDEO_LISTENER: - mVideoListener = IVideoCallback.Stub.asInterface((IBinder) msg.obj); + case MSG_SET_VIDEO_CALLBACK: + mVideoCallback = IVideoCallback.Stub.asInterface((IBinder) msg.obj); break; case MSG_SET_CAMERA: onSetCamera((String) msg.obj); @@ -206,9 +206,9 @@ public abstract class Connection { * IVideoProvider stub implementation. */ private final class VideoProviderBinder extends IVideoProvider.Stub { - public void setVideoListener(IBinder videoListenerBinder) { + public void setVideoCallback(IBinder videoCallbackBinder) { mMessageHandler.obtainMessage( - MSG_SET_VIDEO_LISTENER, videoListenerBinder).sendToTarget(); + MSG_SET_VIDEO_CALLBACK, videoCallbackBinder).sendToTarget(); } public void setCamera(String cameraId) { @@ -350,9 +350,9 @@ public abstract class Connection { * @param videoProfile The requested video call profile. */ public void receiveSessionModifyRequest(VideoProfile videoProfile) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.receiveSessionModifyRequest(videoProfile); + mVideoCallback.receiveSessionModifyRequest(videoProfile); } catch (RemoteException ignored) { } } @@ -370,9 +370,9 @@ public abstract class Connection { */ public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile, VideoProfile responseProfile) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.receiveSessionModifyResponse( + mVideoCallback.receiveSessionModifyResponse( status, requestedProfile, responseProfile); } catch (RemoteException ignored) { } @@ -390,9 +390,9 @@ public abstract class Connection { * @param event The event. */ public void handleCallSessionEvent(int event) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.handleCallSessionEvent(event); + mVideoCallback.handleCallSessionEvent(event); } catch (RemoteException ignored) { } } @@ -405,9 +405,9 @@ public abstract class Connection { * @param height The updated peer video height. */ public void changePeerDimensions(int width, int height) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.changePeerDimensions(width, height); + mVideoCallback.changePeerDimensions(width, height); } catch (RemoteException ignored) { } } @@ -419,9 +419,9 @@ public abstract class Connection { * @param dataUsage The updated data usage. */ public void changeCallDataUsage(int dataUsage) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.changeCallDataUsage(dataUsage); + mVideoCallback.changeCallDataUsage(dataUsage); } catch (RemoteException ignored) { } } @@ -433,9 +433,9 @@ public abstract class Connection { * @param cameraCapabilities The changed camera capabilities. */ public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { - if (mVideoListener != null) { + if (mVideoCallback != null) { try { - mVideoListener.changeCameraCapabilities(cameraCapabilities); + mVideoCallback.changeCameraCapabilities(cameraCapabilities); } catch (RemoteException ignored) { } } diff --git a/telecomm/java/android/telecomm/ConnectionRequest.java b/telecomm/java/android/telecomm/ConnectionRequest.java index 39ae59a..d5a6aa5 100644 --- a/telecomm/java/android/telecomm/ConnectionRequest.java +++ b/telecomm/java/android/telecomm/ConnectionRequest.java @@ -29,31 +29,25 @@ public final class ConnectionRequest implements Parcelable { // TODO: Token to limit recursive invocations private final PhoneAccountHandle mAccountHandle; - private final Uri mHandle; - private final int mHandlePresentation; + private final Uri mAddress; private final Bundle mExtras; private final int mVideoState; /** * @param accountHandle The accountHandle which should be used to place the call. * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. - * @param handlePresentation The {@link PropertyPresentation} which controls how the handle - * is shown. * @param extras Application-specific extra data. */ public ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, - int handlePresentation, Bundle extras) { - this(accountHandle, handle, handlePresentation, extras, VideoProfile.VideoState.AUDIO_ONLY); + this(accountHandle, handle, extras, VideoProfile.VideoState.AUDIO_ONLY); } /** * @param accountHandle The accountHandle which should be used to place the call. * @param handle The handle (e.g., phone number) to which the {@link Connection} is to connect. - * @param handlePresentation The {@link PropertyPresentation} which controls how the handle - * is shown. * @param extras Application-specific extra data. * @param videoState Determines the video state for the connection. * @hide @@ -61,20 +55,17 @@ public final class ConnectionRequest implements Parcelable { public ConnectionRequest( PhoneAccountHandle accountHandle, Uri handle, - int handlePresentation, Bundle extras, int videoState) { mAccountHandle = accountHandle; - mHandle = handle; - mHandlePresentation = handlePresentation; + mAddress = handle; mExtras = extras; mVideoState = videoState; } private ConnectionRequest(Parcel in) { mAccountHandle = in.readParcelable(getClass().getClassLoader()); - mHandle = in.readParcelable(getClass().getClassLoader()); - mHandlePresentation = in.readInt(); + mAddress = in.readParcelable(getClass().getClassLoader()); mExtras = in.readParcelable(getClass().getClassLoader()); mVideoState = in.readInt(); } @@ -87,12 +78,7 @@ public final class ConnectionRequest implements Parcelable { /** * The handle (e.g., phone number) to which the {@link Connection} is to connect. */ - public Uri getHandle() { return mHandle; } - - /** - * The {@link PropertyPresentation} which controls how the handle is shown. - */ - public int getHandlePresentation() { return mHandlePresentation; } + public Uri getAddress() { return mAddress; } /** * Application-specific extra data. Used for passing back information from an incoming @@ -118,9 +104,9 @@ public final class ConnectionRequest implements Parcelable { @Override public String toString() { return String.format("ConnectionRequest %s %s", - mHandle == null + mAddress == null ? Uri.EMPTY - : Connection.toLogSafePhoneNumber(mHandle.toString()), + : Connection.toLogSafePhoneNumber(mAddress.toString()), mExtras == null ? "" : mExtras); } @@ -147,8 +133,7 @@ public final class ConnectionRequest implements Parcelable { @Override public void writeToParcel(Parcel destination, int flags) { destination.writeParcelable(mAccountHandle, 0); - destination.writeParcelable(mHandle, 0); - destination.writeInt(mHandlePresentation); + destination.writeParcelable(mAddress, 0); destination.writeParcelable(mExtras, 0); destination.writeInt(mVideoState); } diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java index 833aa26..39365b6 100644 --- a/telecomm/java/android/telecomm/ConnectionService.java +++ b/telecomm/java/android/telecomm/ConnectionService.java @@ -781,7 +781,7 @@ public abstract class ConnectionService extends Service { } } ParcelableConference parcelableConference = new ParcelableConference( - conference.getPhoneAccount(), + conference.getPhoneAccountHandle(), conference.getState(), conference.getCapabilities(), connectionIds); diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java index 1d61a6e..f709a86 100644 --- a/telecomm/java/android/telecomm/PhoneAccount.java +++ b/telecomm/java/android/telecomm/PhoneAccount.java @@ -98,8 +98,8 @@ public class PhoneAccount implements Parcelable { public static final String SCHEME_SIP = "sip"; private final PhoneAccountHandle mAccountHandle; - private final Uri mHandle; - private final String mSubscriptionNumber; + private final Uri mAddress; + private final Uri mSubscriptionAddress; private final int mCapabilities; private final int mIconResId; private final CharSequence mLabel; @@ -108,47 +108,40 @@ public class PhoneAccount implements Parcelable { public static class Builder { private PhoneAccountHandle mAccountHandle; - private Uri mHandle; - private String mSubscriptionNumber; + private Uri mAddress; + private Uri mSubscriptionAddress; private int mCapabilities; private int mIconResId; private CharSequence mLabel; private CharSequence mShortDescription; private List<String> mSupportedUriSchemes = new ArrayList<String>(); - public Builder() {} - - public Builder withAccountHandle(PhoneAccountHandle value) { - this.mAccountHandle = value; - return this; + public Builder(PhoneAccountHandle accountHandle, CharSequence label) { + this.mAccountHandle = accountHandle; + this.mLabel = label; } - public Builder withHandle(Uri value) { - this.mHandle = value; + public Builder setAddress(Uri value) { + this.mAddress = value; return this; } - public Builder withSubscriptionNumber(String value) { - this.mSubscriptionNumber = value; + public Builder setSubscriptionAddress(Uri value) { + this.mSubscriptionAddress = value; return this; } - public Builder withCapabilities(int value) { + public Builder setCapabilities(int value) { this.mCapabilities = value; return this; } - public Builder withIconResId(int value) { + public Builder setIconResId(int value) { this.mIconResId = value; return this; } - public Builder withLabel(CharSequence value) { - this.mLabel = value; - return this; - } - - public Builder withShortDescription(CharSequence value) { + public Builder setShortDescription(CharSequence value) { this.mShortDescription = value; return this; } @@ -158,8 +151,9 @@ public class PhoneAccount implements Parcelable { * * @param uriScheme The URI scheme. * @return The Builder. + * @hide */ - public Builder withSupportedUriScheme(String uriScheme) { + public Builder addSupportedUriScheme(String uriScheme) { if (!TextUtils.isEmpty(uriScheme) && !mSupportedUriSchemes.contains(uriScheme)) { this.mSupportedUriSchemes.add(uriScheme); } @@ -167,15 +161,17 @@ public class PhoneAccount implements Parcelable { } /** - * Specifies additional URI schemes supported by the {@link PhoneAccount}. + * Specifies the URI schemes supported by the {@link PhoneAccount}. * * @param uriSchemes The URI schemes. * @return The Builder. */ - public Builder withSupportedUriSchemes(List<String> uriSchemes) { + public Builder setSupportedUriSchemes(List<String> uriSchemes) { + mSupportedUriSchemes.clear(); + if (uriSchemes != null && !uriSchemes.isEmpty()) { for (String uriScheme : uriSchemes) { - withSupportedUriScheme(uriScheme); + addSupportedUriScheme(uriScheme); } } return this; @@ -184,13 +180,13 @@ public class PhoneAccount implements Parcelable { public PhoneAccount build() { // If no supported URI schemes were defined, assume "tel" is supported. if (mSupportedUriSchemes.isEmpty()) { - withSupportedUriScheme(SCHEME_TEL); + addSupportedUriScheme(SCHEME_TEL); } return new PhoneAccount( mAccountHandle, - mHandle, - mSubscriptionNumber, + mAddress, + mSubscriptionAddress, mCapabilities, mIconResId, mLabel, @@ -201,16 +197,16 @@ public class PhoneAccount implements Parcelable { private PhoneAccount( PhoneAccountHandle account, - Uri handle, - String subscriptionNumber, + Uri address, + Uri subscriptionAddress, int capabilities, int iconResId, CharSequence label, CharSequence shortDescription, List<String> supportedUriSchemes) { mAccountHandle = account; - mHandle = handle; - mSubscriptionNumber = subscriptionNumber; + mAddress = address; + mSubscriptionAddress = subscriptionAddress; mCapabilities = capabilities; mIconResId = iconResId; mLabel = label; @@ -218,7 +214,11 @@ public class PhoneAccount implements Parcelable { mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); } - public static Builder builder() { return new Builder(); } + public static Builder builder( + PhoneAccountHandle accountHandle, + CharSequence label) { + return new Builder(accountHandle, label); + } /** * The unique identifier of this {@code PhoneAccount}. @@ -230,32 +230,29 @@ public class PhoneAccount implements Parcelable { } /** - * The handle (e.g., a phone number) associated with this {@code PhoneAccount}. This + * The address (e.g., a phone number) associated with this {@code PhoneAccount}. This * represents the destination from which outgoing calls using this {@code PhoneAccount} * will appear to come, if applicable, and the destination to which incoming calls using this * {@code PhoneAccount} may be addressed. * - * @return A handle expressed as a {@code Uri}, for example, a phone number. + * @return A address expressed as a {@code Uri}, for example, a phone number. */ - public Uri getHandle() { - return mHandle; + public Uri getAddress() { + return mAddress; } /** * The raw callback number used for this {@code PhoneAccount}, as distinct from - * {@link #getHandle()}. For the majority of {@code PhoneAccount}s this should be registered + * {@link #getAddress()}. For the majority of {@code PhoneAccount}s this should be registered * as {@code null}. It is used by the system for SIM-based {@code PhoneAccount} registration * where {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(String, String)} - * or {@link android.telephony.TelephonyManager#setLine1NumberForDisplay(long, String, String)} * has been used to alter the callback number. * <p> - * TODO: Should this also be a URI, for consistency? Should it be called the - * "subscription handle"? * * @return The subscription number, suitable for display to the user. */ - public String getSubscriptionNumber() { - return mSubscriptionNumber; + public Uri getSubscriptionAddress() { + return mSubscriptionAddress; } /** @@ -295,11 +292,11 @@ public class PhoneAccount implements Parcelable { } /** - * Determines if the {@link PhoneAccount} supports calls to/from handles with a specified URI + * Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI * scheme. * * @param uriScheme The URI scheme to check. - * @return {@code True} if the {@code PhoneAccount} supports calls to/from handles with the + * @return {@code True} if the {@code PhoneAccount} supports calls to/from addresses with the * specified URI scheme. */ public boolean supportsUriScheme(String uriScheme) { @@ -363,8 +360,8 @@ public class PhoneAccount implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { out.writeParcelable(mAccountHandle, 0); - out.writeParcelable(mHandle, 0); - out.writeString(mSubscriptionNumber); + out.writeParcelable(mAddress, 0); + out.writeParcelable(mSubscriptionAddress, 0); out.writeInt(mCapabilities); out.writeInt(mIconResId); out.writeCharSequence(mLabel); @@ -389,8 +386,8 @@ public class PhoneAccount implements Parcelable { ClassLoader classLoader = PhoneAccount.class.getClassLoader(); mAccountHandle = in.readParcelable(getClass().getClassLoader()); - mHandle = in.readParcelable(getClass().getClassLoader()); - mSubscriptionNumber = in.readString(); + mAddress = in.readParcelable(getClass().getClassLoader()); + mSubscriptionAddress = in.readParcelable(getClass().getClassLoader()); mCapabilities = in.readInt(); mIconResId = in.readInt(); mLabel = in.readCharSequence(); diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java index 31afb4b..8ad8d19 100644 --- a/telecomm/java/android/telecomm/RemoteConnection.java +++ b/telecomm/java/android/telecomm/RemoteConnection.java @@ -17,15 +17,18 @@ package android.telecomm; import com.android.internal.telecomm.IConnectionService; +import com.android.internal.telecomm.IVideoCallback; +import com.android.internal.telecomm.IVideoProvider; import android.app.PendingIntent; import android.net.Uri; +import android.os.IBinder; import android.os.RemoteException; import android.telephony.DisconnectCause; +import android.view.Surface; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -183,6 +186,18 @@ public final class RemoteConnection { List<RemoteConnection> conferenceableConnections) {} /** + * Indicates that the {@code VideoProvider} associated with this {@code RemoteConnection} + * has changed. + * + * @param connection The {@code RemoteConnection} invoking this method. + * @param videoProvider The new {@code VideoProvider} associated with this + * {@code RemoteConnection}. + * @hide + */ + public void onVideoProviderChanged( + RemoteConnection connection, VideoProvider videoProvider) {} + + /** * Indicates that the {@code RemoteConference} that this {@code RemoteConnection} is a part * of has changed. * @@ -195,6 +210,185 @@ public final class RemoteConnection { RemoteConference conference) {} } + /** {@hide} */ + public static class VideoProvider { + + public abstract static class Listener { + public void onReceiveSessionModifyRequest( + VideoProvider videoProvider, + VideoProfile videoProfile) {} + + public void onReceiveSessionModifyResponse( + VideoProvider videoProvider, + int status, + VideoProfile requestedProfile, + VideoProfile responseProfile) {} + + public void onHandleCallSessionEvent(VideoProvider videoProvider, int event) {} + + public void onPeerDimensionsChanged(VideoProvider videoProvider, int width, int height) {} + + public void onCallDataUsageChanged(VideoProvider videoProvider, int dataUsage) {} + + public void onCameraCapabilitiesChanged( + VideoProvider videoProvider, + CameraCapabilities cameraCapabilities) {} + } + + private final IVideoCallback mVideoCallbackDelegate = new IVideoCallback() { + @Override + public void receiveSessionModifyRequest(VideoProfile videoProfile) { + for (Listener l : mListeners) { + l.onReceiveSessionModifyRequest(VideoProvider.this, videoProfile); + } + } + + @Override + public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile, + VideoProfile responseProfile) { + for (Listener l : mListeners) { + l.onReceiveSessionModifyResponse( + VideoProvider.this, + status, + requestedProfile, + responseProfile); + } + } + + @Override + public void handleCallSessionEvent(int event) { + for (Listener l : mListeners) { + l.onHandleCallSessionEvent(VideoProvider.this, event); + } + } + + @Override + public void changePeerDimensions(int width, int height) { + for (Listener l : mListeners) { + l.onPeerDimensionsChanged(VideoProvider.this, width, height); + } + } + + @Override + public void changeCallDataUsage(int dataUsage) { + for (Listener l : mListeners) { + l.onCallDataUsageChanged(VideoProvider.this, dataUsage); + } + } + + @Override + public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) { + for (Listener l : mListeners) { + l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities); + } + } + + @Override + public IBinder asBinder() { + return null; + } + }; + + private final VideoCallbackServant mVideoCallbackServant = + new VideoCallbackServant(mVideoCallbackDelegate); + + private final IVideoProvider mVideoProviderBinder; + + /** + * ConcurrentHashMap constructor params: 8 is initial table size, 0.9f is + * load factor before resizing, 1 means we only expect a single thread to + * access the map so make only a single shard + */ + private final Set<Listener> mListeners = Collections.newSetFromMap( + new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1)); + + public VideoProvider(IVideoProvider videoProviderBinder) { + mVideoProviderBinder = videoProviderBinder; + try { + mVideoProviderBinder.setVideoCallback(mVideoCallbackServant.getStub().asBinder()); + } catch (RemoteException e) { + } + } + + public void addListener(Listener l) { + mListeners.add(l); + } + + public void removeListener(Listener l) { + mListeners.remove(l); + } + + public void setCamera(String cameraId) { + try { + mVideoProviderBinder.setCamera(cameraId); + } catch (RemoteException e) { + } + } + + public void setPreviewSurface(Surface surface) { + try { + mVideoProviderBinder.setPreviewSurface(surface); + } catch (RemoteException e) { + } + } + + public void setDisplaySurface(Surface surface) { + try { + mVideoProviderBinder.setDisplaySurface(surface); + } catch (RemoteException e) { + } + } + + public void setDeviceOrientation(int rotation) { + try { + mVideoProviderBinder.setDeviceOrientation(rotation); + } catch (RemoteException e) { + } + } + + public void setZoom(float value) { + try { + mVideoProviderBinder.setZoom(value); + } catch (RemoteException e) { + } + } + + public void sendSessionModifyRequest(VideoProfile reqProfile) { + try { + mVideoProviderBinder.sendSessionModifyRequest(reqProfile); + } catch (RemoteException e) { + } + } + + public void sendSessionModifyResponse(VideoProfile responseProfile) { + try { + mVideoProviderBinder.sendSessionModifyResponse(responseProfile); + } catch (RemoteException e) { + } + } + + public void requestCameraCapabilities() { + try { + mVideoProviderBinder.requestCameraCapabilities(); + } catch (RemoteException e) { + } + } + + public void requestCallDataUsage() { + try { + mVideoProviderBinder.requestCallDataUsage(); + } catch (RemoteException e) { + } + } + + public void setPauseImage(String uri) { + try { + mVideoProviderBinder.setPauseImage(uri); + } catch (RemoteException e) { + } + } + } + private IConnectionService mConnectionService; private final String mConnectionId; /** @@ -215,6 +409,7 @@ public final class RemoteConnection { private boolean mConnected; private int mCallCapabilities; private int mVideoState; + private VideoProvider mVideoProvider; private boolean mAudioModeIsVoip; private StatusHints mStatusHints; private Uri mHandle; @@ -380,6 +575,14 @@ public final class RemoteConnection { } /** + * @return The video provider associated with this {@code RemoteConnection}. + * @hide + */ + public final VideoProvider getVideoProvider() { + return mVideoProvider; + } + + /** * @return The failure code ({@see DisconnectCause}) associated with this failed * {@code RemoteConnection}. */ @@ -684,6 +887,16 @@ public final class RemoteConnection { } } + /** + * @hide + */ + void setVideoProvider(VideoProvider videoProvider) { + mVideoProvider = videoProvider; + for (Listener l : mListeners) { + l.onVideoProviderChanged(this, videoProvider); + } + } + /** @hide */ void setAudioModeIsVoip(boolean isVoip) { mAudioModeIsVoip = isVoip; diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java index 79193c2..348c36c 100644 --- a/telecomm/java/android/telecomm/RemoteConnectionService.java +++ b/telecomm/java/android/telecomm/RemoteConnectionService.java @@ -74,7 +74,7 @@ final class RemoteConnectionService { } } connection.setConferenceableConnections(conferenceable); - // TODO: Do we need to support video providers for remote connections? + connection.setVideoState(parcel.getVideoState()); if (connection.getState() == Connection.STATE_DISCONNECTED) { // ... then, if it was created in a disconnected state, that indicates // failure on the providing end, so immediately mark it destroyed @@ -226,7 +226,8 @@ final class RemoteConnectionService { @Override public void setVideoProvider(String callId, IVideoProvider videoProvider) { - // not supported for remote connections. + findConnectionForAction(callId, "setVideoProvider") + .setVideoProvider(new RemoteConnection.VideoProvider(videoProvider)); } @Override @@ -325,8 +326,7 @@ final class RemoteConnectionService { final String id = UUID.randomUUID().toString(); final ConnectionRequest newRequest = new ConnectionRequest( request.getAccountHandle(), - request.getHandle(), - request.getHandlePresentation(), + request.getAddress(), request.getExtras(), request.getVideoState()); try { diff --git a/telecomm/java/android/telecomm/StatusHints.java b/telecomm/java/android/telecomm/StatusHints.java index f7c4f2f..ff96a5b 100644 --- a/telecomm/java/android/telecomm/StatusHints.java +++ b/telecomm/java/android/telecomm/StatusHints.java @@ -32,23 +32,24 @@ import java.util.Objects; */ public final class StatusHints implements Parcelable { - private final ComponentName mComponentName; + private final ComponentName mPackageName; private final CharSequence mLabel; private final int mIconResId; private final Bundle mExtras; - public StatusHints(ComponentName componentName, CharSequence label, int iconResId, Bundle extras) { - mComponentName = componentName; + public StatusHints(ComponentName packageName, CharSequence label, int iconResId, + Bundle extras) { + mPackageName = packageName; mLabel = label; mIconResId = iconResId; mExtras = extras; } /** - * @return A component used to load the icon. + * @return A package used to load the icon. */ - public ComponentName getComponentName() { - return mComponentName; + public ComponentName getPackageName() { + return mPackageName; } /** @@ -88,7 +89,7 @@ public final class StatusHints implements Parcelable { @Override public void writeToParcel(Parcel out, int flags) { - out.writeParcelable(mComponentName, flags); + out.writeParcelable(mPackageName, flags); out.writeCharSequence(mLabel); out.writeInt(mIconResId); out.writeParcelable(mExtras, 0); @@ -106,7 +107,7 @@ public final class StatusHints implements Parcelable { }; private StatusHints(Parcel in) { - mComponentName = in.readParcelable(getClass().getClassLoader()); + mPackageName = in.readParcelable(getClass().getClassLoader()); mLabel = in.readCharSequence(); mIconResId = in.readInt(); mExtras = in.readParcelable(getClass().getClassLoader()); @@ -115,16 +116,16 @@ public final class StatusHints implements Parcelable { private Drawable getIcon(Context context, int resId) { Context packageContext; try { - packageContext = context.createPackageContext(mComponentName.getPackageName(), 0); + packageContext = context.createPackageContext(mPackageName.getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { - Log.e(this, e, "Cannot find package %s", mComponentName.getPackageName()); + Log.e(this, e, "Cannot find package %s", mPackageName.getPackageName()); return null; } try { return packageContext.getDrawable(resId); } catch (MissingResourceException e) { Log.e(this, e, "Cannot find icon %d in package %s", - resId, mComponentName.getPackageName()); + resId, mPackageName.getPackageName()); return null; } } @@ -133,7 +134,7 @@ public final class StatusHints implements Parcelable { public boolean equals(Object other) { if (other != null && other instanceof StatusHints) { StatusHints otherHints = (StatusHints) other; - return Objects.equals(otherHints.getComponentName(), getComponentName()) && + return Objects.equals(otherHints.getPackageName(), getPackageName()) && Objects.equals(otherHints.getLabel(), getLabel()) && otherHints.getIconResId() == getIconResId() && Objects.equals(otherHints.getExtras(), getExtras()); @@ -143,7 +144,7 @@ public final class StatusHints implements Parcelable { @Override public int hashCode() { - return Objects.hashCode(mComponentName) + Objects.hashCode(mLabel) + mIconResId + + return Objects.hashCode(mPackageName) + Objects.hashCode(mLabel) + mIconResId + Objects.hashCode(mExtras); } } diff --git a/telecomm/java/android/telecomm/VideoCallImpl.java b/telecomm/java/android/telecomm/VideoCallImpl.java index c10865f..d33a351 100644 --- a/telecomm/java/android/telecomm/VideoCallImpl.java +++ b/telecomm/java/android/telecomm/VideoCallImpl.java @@ -157,7 +157,7 @@ public class VideoCallImpl extends VideoCall { mVideoProvider.asBinder().linkToDeath(mDeathRecipient, 0); mBinder = new VideoCallListenerBinder(); - mVideoProvider.setVideoListener(mBinder); + mVideoProvider.setVideoCallback(mBinder); } /** {@inheritDoc} */ diff --git a/telecomm/java/android/telecomm/VideoCallbackServant.java b/telecomm/java/android/telecomm/VideoCallbackServant.java new file mode 100644 index 0000000..060b8a9 --- /dev/null +++ b/telecomm/java/android/telecomm/VideoCallbackServant.java @@ -0,0 +1,160 @@ +/* + * 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 + R* limitations under the License. + */ + +package android.telecomm; + +import com.android.internal.os.SomeArgs; +import com.android.internal.telecomm.IVideoCallback; + +import android.os.Handler; +import android.os.Message; +import android.os.RemoteException; + +/** + * A component that provides an RPC servant implementation of {@link IVideoCallback}, + * posting incoming messages on the main thread on a client-supplied delegate object. + * + * TODO: Generate this and similar classes using a compiler starting from AIDL interfaces. + * + * @hide + */ +final class VideoCallbackServant { + private static final int MSG_RECEIVE_SESSION_MODIFY_REQUEST = 0; + private static final int MSG_RECEIVE_SESSION_MODIFY_RESPONSE = 1; + private static final int MSG_HANDLE_CALL_SESSION_EVENT = 2; + private static final int MSG_CHANGE_PEER_DIMENSIONS = 3; + private static final int MSG_CHANGE_CALL_DATA_USAGE = 4; + private static final int MSG_CHANGE_CAMERA_CAPABILITIES = 5; + + private final IVideoCallback mDelegate; + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + try { + internalHandleMessage(msg); + } catch (RemoteException e) { + } + } + + // Internal method defined to centralize handling of RemoteException + private void internalHandleMessage(Message msg) throws RemoteException { + switch (msg.what) { + case MSG_RECEIVE_SESSION_MODIFY_REQUEST: { + mDelegate.receiveSessionModifyRequest((VideoProfile) msg.obj); + break; + } + case MSG_RECEIVE_SESSION_MODIFY_RESPONSE: { + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.receiveSessionModifyResponse( + args.argi1, + (VideoProfile) args.arg1, + (VideoProfile) args.arg2); + } finally { + args.recycle(); + } + break; + } + case MSG_HANDLE_CALL_SESSION_EVENT: { + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.handleCallSessionEvent(args.argi1); + } finally { + args.recycle(); + } + break; + } + case MSG_CHANGE_PEER_DIMENSIONS: { + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.changePeerDimensions(args.argi1, args.argi2); + } finally { + args.recycle(); + } + break; + } + case MSG_CHANGE_CALL_DATA_USAGE: { + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.changeCallDataUsage(args.argi1); + } finally { + args.recycle(); + } + break; + } + case MSG_CHANGE_CAMERA_CAPABILITIES: { + mDelegate.changeCameraCapabilities((CameraCapabilities) msg.obj); + break; + } + } + } + }; + + private final IVideoCallback mStub = new IVideoCallback.Stub() { + @Override + public void receiveSessionModifyRequest(VideoProfile videoProfile) throws RemoteException { + mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST, videoProfile).sendToTarget(); + } + + @Override + public void receiveSessionModifyResponse(int status, VideoProfile requestedProfile, + VideoProfile responseProfile) throws RemoteException { + SomeArgs args = SomeArgs.obtain(); + args.argi1 = status; + args.arg1 = requestedProfile; + args.arg2 = responseProfile; + mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_RESPONSE, args).sendToTarget(); + } + + @Override + public void handleCallSessionEvent(int event) throws RemoteException { + SomeArgs args = SomeArgs.obtain(); + args.argi1 = event; + mHandler.obtainMessage(MSG_HANDLE_CALL_SESSION_EVENT, args).sendToTarget(); + } + + @Override + public void changePeerDimensions(int width, int height) throws RemoteException { + SomeArgs args = SomeArgs.obtain(); + args.argi1 = width; + args.argi2 = height; + mHandler.obtainMessage(MSG_CHANGE_PEER_DIMENSIONS, args).sendToTarget(); + } + + @Override + public void changeCallDataUsage(int dataUsage) throws RemoteException { + SomeArgs args = SomeArgs.obtain(); + args.argi1 = dataUsage; + mHandler.obtainMessage(MSG_CHANGE_CALL_DATA_USAGE, args).sendToTarget(); + } + + @Override + public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) + throws RemoteException { + mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities) + .sendToTarget(); + } + }; + + public VideoCallbackServant(IVideoCallback delegate) { + mDelegate = delegate; + } + + public IVideoCallback getStub() { + return mStub; + } +} diff --git a/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl index 9d3ad7f..b0aa988 100644 --- a/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl +++ b/telecomm/java/com/android/internal/telecomm/IVideoProvider.aidl @@ -25,7 +25,7 @@ import android.telecomm.VideoProfile; * @hide */ oneway interface IVideoProvider { - void setVideoListener(IBinder videoListenerBinder); + void setVideoCallback(IBinder videoCallbackBinder); void setCamera(String cameraId); diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 1d9e6a9..30799f8 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -2316,8 +2316,9 @@ public class PhoneNumberUtils /** * This function checks if the passed in string conforms to the NANP format * i.e. NXX-NXX-XXXX, N is any digit 2-9 and X is any digit 0-9 + * @hide */ - private static boolean isNanp (String dialStr) { + public static boolean isNanp (String dialStr) { boolean retVal = false; if (dialStr != null) { if (dialStr.length() == NANP_LENGTH) { diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 58d30f1..d0f355e 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -265,9 +265,9 @@ public class SubscriptionManager implements BaseColumns { * @return SubInfoRecord, maybe null * @hide - to be unhidden */ - public static SubInfoRecord getSubInfoUsingSubId(long subId) { + public static SubInfoRecord getSubInfoForSubscriber(long subId) { if (!isValidSubId(subId)) { - logd("[getSubInfoUsingSubIdx]- invalid subId"); + logd("[getSubInfoForSubscriberx]- invalid subId"); return null; } @@ -276,7 +276,7 @@ public class SubscriptionManager implements BaseColumns { try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - subInfo = iSub.getSubInfoUsingSubId(subId); + subInfo = iSub.getSubInfoForSubscriber(subId); } } catch (RemoteException ex) { // ignore it @@ -783,7 +783,7 @@ public class SubscriptionManager implements BaseColumns { /** @hide */ public static SubInfoRecord getDefaultVoiceSubInfo() { - return getSubInfoUsingSubId(getDefaultVoiceSubId()); + return getSubInfoForSubscriber(getDefaultVoiceSubId()); } /** @hide */ @@ -826,7 +826,7 @@ public class SubscriptionManager implements BaseColumns { /** @hide */ public static SubInfoRecord getDefaultSmsSubInfo() { - return getSubInfoUsingSubId(getDefaultSmsSubId()); + return getSubInfoForSubscriber(getDefaultSmsSubId()); } /** @hide */ @@ -866,7 +866,7 @@ public class SubscriptionManager implements BaseColumns { /** @hide */ public static SubInfoRecord getDefaultDataSubInfo() { - return getSubInfoUsingSubId(getDefaultDataSubId()); + return getSubInfoForSubscriber(getDefaultDataSubId()); } /** @hide */ diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 93c49ba..d53be4f 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -608,7 +608,7 @@ public class TelephonyManager { public String getDeviceId(int slotId) { long[] subId = SubscriptionManager.getSubId(slotId); try { - return getSubscriberInfo().getDeviceIdUsingSubId(subId[0]); + return getSubscriberInfo().getDeviceIdForSubscriber(subId[0]); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -639,7 +639,7 @@ public class TelephonyManager { public String getImei(int slotId) { long[] subId = SubscriptionManager.getSubId(slotId); try { - return getSubscriberInfo().getImeiUsingSubId(subId[0]); + return getSubscriberInfo().getImeiForSubscriber(subId[0]); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -703,7 +703,7 @@ public class TelephonyManager { /** @hide */ public void enableLocationUpdates(long subId) { try { - getITelephony().enableLocationUpdatesUsingSubId(subId); + getITelephony().enableLocationUpdatesForSubscriber(subId); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -725,7 +725,7 @@ public class TelephonyManager { /** @hide */ public void disableLocationUpdates(long subId) { try { - getITelephony().disableLocationUpdatesUsingSubId(subId); + getITelephony().disableLocationUpdatesForSubscriber(subId); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -772,6 +772,7 @@ public class TelephonyManager { * * {@hide} */ + @SystemApi public int getCurrentPhoneType() { return getCurrentPhoneType(getDefaultSubscription()); } @@ -786,12 +787,13 @@ public class TelephonyManager { * @param subId for which phone type is returned */ /** {@hide} */ + @SystemApi public int getCurrentPhoneType(long subId) { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getActivePhoneTypeUsingSubId(subId); + return telephony.getActivePhoneTypeForSubscriber(subId); } else { // This can happen when the ITelephony interface is not up yet. return getPhoneTypeFromProperty(subId); @@ -1157,7 +1159,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getNetworkTypeUsingSubId(subId); + return telephony.getNetworkTypeForSubscriber(subId); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -1211,7 +1213,7 @@ public class TelephonyManager { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getDataNetworkTypeUsingSubId(subId); + return telephony.getDataNetworkTypeForSubscriber(subId); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -1243,7 +1245,7 @@ public class TelephonyManager { try{ ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getVoiceNetworkTypeUsingSubId(subId); + return telephony.getVoiceNetworkTypeForSubscriber(subId); } else { // This can happen when the ITelephony interface is not up yet. return NETWORK_TYPE_UNKNOWN; @@ -1570,7 +1572,7 @@ public class TelephonyManager { /** {@hide} */ public String getSimSerialNumber(long subId) { try { - return getSubscriberInfo().getIccSerialNumberUsingSubId(subId); + return getSubscriberInfo().getIccSerialNumberForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1606,7 +1608,7 @@ public class TelephonyManager { /** {@hide} */ public int getLteOnCdmaMode(long subId) { try { - return getITelephony().getLteOnCdmaModeUsingSubId(subId); + return getITelephony().getLteOnCdmaModeForSubscriber(subId); } catch (RemoteException ex) { // Assume no ICC card if remote exception which shouldn't happen return PhoneConstants.LTE_ON_CDMA_UNKNOWN; @@ -1646,7 +1648,7 @@ public class TelephonyManager { /** {@hide} */ public String getSubscriberId(long subId) { try { - return getSubscriberInfo().getSubscriberIdUsingSubId(subId); + return getSubscriberInfo().getSubscriberIdForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1685,7 +1687,7 @@ public class TelephonyManager { /** {@hide} */ public String getGroupIdLevel1(long subId) { try { - return getSubscriberInfo().getGroupIdLevel1UsingSubId(subId); + return getSubscriberInfo().getGroupIdLevel1ForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1702,7 +1704,7 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ public String getLine1Number() { - return getLine1Number(getDefaultSubscription()); + return getLine1NumberForSubscriber(getDefaultSubscription()); } /** @@ -1715,7 +1717,7 @@ public class TelephonyManager { * @param subId whose phone number for line 1 is returned */ /** {@hide} */ - public String getLine1Number(long subId) { + public String getLine1NumberForSubscriber(long subId) { String number = null; try { number = getITelephony().getLine1NumberForDisplay(subId); @@ -1726,7 +1728,7 @@ public class TelephonyManager { return number; } try { - return getSubscriberInfo().getLine1NumberUsingSubId(subId); + return getSubscriberInfo().getLine1NumberForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1749,7 +1751,7 @@ public class TelephonyManager { * @param number The dialing number */ public void setLine1NumberForDisplay(String alphaTag, String number) { - setLine1NumberForDisplay(getDefaultSubscription(), alphaTag, number); + setLine1NumberForDisplayForSubscriber(getDefaultSubscription(), alphaTag, number); } /** @@ -1765,10 +1767,11 @@ public class TelephonyManager { * @param subId the subscriber that the alphatag and dialing number belongs to. * @param alphaTag alpha-tagging of the dailing nubmer * @param number The dialing number + * @hide */ - public void setLine1NumberForDisplay(long subId, String alphaTag, String number) { + public void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number) { try { - getITelephony().setLine1NumberForDisplay(subId, alphaTag, number); + getITelephony().setLine1NumberForDisplayForSubscriber(subId, alphaTag, number); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -1784,7 +1787,7 @@ public class TelephonyManager { * nobody seems to call this. */ public String getLine1AlphaTag() { - return getLine1AlphaTag(getDefaultSubscription()); + return getLine1AlphaTagForSubscriber(getDefaultSubscription()); } /** @@ -1798,7 +1801,7 @@ public class TelephonyManager { * nobody seems to call this. */ /** {@hide} */ - public String getLine1AlphaTag(long subId) { + public String getLine1AlphaTagForSubscriber(long subId) { String alphaTag = null; try { alphaTag = getITelephony().getLine1AlphaTagForDisplay(subId); @@ -1809,7 +1812,7 @@ public class TelephonyManager { return alphaTag; } try { - return getSubscriberInfo().getLine1AlphaTagUsingSubId(subId); + return getSubscriberInfo().getLine1AlphaTagForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1843,7 +1846,7 @@ public class TelephonyManager { /** {@hide} */ public String getMsisdn(long subId) { try { - return getSubscriberInfo().getMsisdnUsingSubId(subId); + return getSubscriberInfo().getMsisdnForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1873,7 +1876,7 @@ public class TelephonyManager { /** {@hide} */ public String getVoiceMailNumber(long subId) { try { - return getSubscriberInfo().getVoiceMailNumberUsingSubId(subId); + return getSubscriberInfo().getVoiceMailNumberForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1905,7 +1908,7 @@ public class TelephonyManager { /** {@hide} */ public String getCompleteVoiceMailNumber(long subId) { try { - return getSubscriberInfo().getCompleteVoiceMailNumberUsingSubId(subId); + return getSubscriberInfo().getCompleteVoiceMailNumberForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -1935,7 +1938,7 @@ public class TelephonyManager { /** {@hide} */ public int getVoiceMessageCount(long subId) { try { - return getITelephony().getVoiceMessageCountUsingSubId(subId); + return getITelephony().getVoiceMessageCountForSubscriber(subId); } catch (RemoteException ex) { return 0; } catch (NullPointerException ex) { @@ -1967,7 +1970,7 @@ public class TelephonyManager { /** {@hide} */ public String getVoiceMailAlphaTag(long subId) { try { - return getSubscriberInfo().getVoiceMailAlphaTagUsingSubId(subId); + return getSubscriberInfo().getVoiceMailAlphaTagForSubscriber(subId); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -2057,7 +2060,7 @@ public class TelephonyManager { /** {@hide} */ public int getCallState(long subId) { try { - return getITelephony().getCallStateUsingSubId(subId); + return getITelephony().getCallStateForSubscriber(subId); } catch (RemoteException ex) { // the phone process is restarting. return CALL_STATE_IDLE; @@ -2179,7 +2182,7 @@ public class TelephonyManager { String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>"; try { Boolean notifyNow = (getITelephony() != null); - sRegistry.listenUsingSubId(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow); + sRegistry.listenForSubscriber(listener.mSubId, pkgForDebug, listener.callback, events, notifyNow); } catch (RemoteException ex) { // system process dead } catch (NullPointerException ex) { @@ -2202,7 +2205,7 @@ public class TelephonyManager { /** {@hide} */ public int getCdmaEriIconIndex(long subId) { try { - return getITelephony().getCdmaEriIconIndexUsingSubId(subId); + return getITelephony().getCdmaEriIconIndexForSubscriber(subId); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -2230,7 +2233,7 @@ public class TelephonyManager { /** {@hide} */ public int getCdmaEriIconMode(long subId) { try { - return getITelephony().getCdmaEriIconModeUsingSubId(subId); + return getITelephony().getCdmaEriIconModeForSubscriber(subId); } catch (RemoteException ex) { // the phone process is restarting. return -1; @@ -2255,7 +2258,7 @@ public class TelephonyManager { /** {@hide} */ public String getCdmaEriText(long subId) { try { - return getITelephony().getCdmaEriTextUsingSubId(subId); + return getITelephony().getCdmaEriTextForSubscriber(subId); } catch (RemoteException ex) { // the phone process is restarting. return null; @@ -3367,7 +3370,7 @@ public class TelephonyManager { * @hide */ public void enableSimplifiedNetworkSettings(boolean enable) { - enableSimplifiedNetworkSettings(getDefaultSubscription(), enable); + enableSimplifiedNetworkSettingsForSubscriber(getDefaultSubscription(), enable); } /** @@ -3382,9 +3385,9 @@ public class TelephonyManager { * @param enable true means enabling the simplified UI. * @hide */ - public void enableSimplifiedNetworkSettings(long subId, boolean enable) { + public void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable) { try { - getITelephony().enableSimplifiedNetworkSettings(subId, enable); + getITelephony().enableSimplifiedNetworkSettingsForSubscriber(subId, enable); } catch (RemoteException ex) { } catch (NullPointerException ex) { } @@ -3400,7 +3403,7 @@ public class TelephonyManager { * @hide */ public boolean getSimplifiedNetworkSettingsEnabled() { - return getSimplifiedNetworkSettingsEnabled(getDefaultSubscription()); + return getSimplifiedNetworkSettingsEnabledForSubscriber(getDefaultSubscription()); } /** @@ -3413,9 +3416,9 @@ public class TelephonyManager { * @return true if the simplified UI is enabled. * @hide */ - public boolean getSimplifiedNetworkSettingsEnabled(long subId) { + public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId) { try { - return getITelephony().getSimplifiedNetworkSettingsEnabled(subId); + return getITelephony().getSimplifiedNetworkSettingsEnabledForSubscriber(subId); } catch (RemoteException ex) { } catch (NullPointerException ex) { } diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 552abaf..c203442 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -31,12 +31,12 @@ interface IPhoneSubInfo { * Retrieves the unique device ID of a subId for the device, e.g., IMEI * for GSM phones. */ - String getDeviceIdUsingSubId(long subId); + String getDeviceIdForSubscriber(long subId); /** * Retrieves the IMEI. */ - String getImeiUsingSubId(long subId); + String getImeiForSubscriber(long subId); /** * Retrieves the software version number for the device, e.g., IMEI/SV @@ -52,7 +52,7 @@ interface IPhoneSubInfo { /** * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones. */ - String getSubscriberIdUsingSubId(long subId); + String getSubscriberIdForSubscriber(long subId); /** * Retrieves the Group Identifier Level1 for GSM phones. @@ -62,7 +62,7 @@ interface IPhoneSubInfo { /** * Retrieves the Group Identifier Level1 for GSM phones of a subId. */ - String getGroupIdLevel1UsingSubId(long subId); + String getGroupIdLevel1ForSubscriber(long subId); /** * Retrieves the serial number of the ICC, if applicable. @@ -72,7 +72,7 @@ interface IPhoneSubInfo { /** * Retrieves the serial number of a given subId. */ - String getIccSerialNumberUsingSubId(long subId); + String getIccSerialNumberForSubscriber(long subId); /** * Retrieves the phone number string for line 1. @@ -82,7 +82,7 @@ interface IPhoneSubInfo { /** * Retrieves the phone number string for line 1 of a subcription. */ - String getLine1NumberUsingSubId(long subId); + String getLine1NumberForSubscriber(long subId); /** @@ -93,7 +93,7 @@ interface IPhoneSubInfo { /** * Retrieves the alpha identifier for line 1 of a subId. */ - String getLine1AlphaTagUsingSubId(long subId); + String getLine1AlphaTagForSubscriber(long subId); /** @@ -104,7 +104,7 @@ interface IPhoneSubInfo { /** * Retrieves the Msisdn of a subId. */ - String getMsisdnUsingSubId(long subId); + String getMsisdnForSubscriber(long subId); /** * Retrieves the voice mail number. @@ -114,7 +114,7 @@ interface IPhoneSubInfo { /** * Retrieves the voice mail number of a given subId. */ - String getVoiceMailNumberUsingSubId(long subId); + String getVoiceMailNumberForSubscriber(long subId); /** * Retrieves the complete voice mail number. @@ -124,7 +124,7 @@ interface IPhoneSubInfo { /** * Retrieves the complete voice mail number for particular subId */ - String getCompleteVoiceMailNumberUsingSubId(long subId); + String getCompleteVoiceMailNumberForSubscriber(long subId); /** * Retrieves the alpha identifier associated with the voice mail number. @@ -135,7 +135,7 @@ interface IPhoneSubInfo { * Retrieves the alpha identifier associated with the voice mail number * of a subId. */ - String getVoiceMailAlphaTagUsingSubId(long subId); + String getVoiceMailAlphaTagForSubscriber(long subId); /** * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index abbdc4a..32bb8b4 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -47,7 +47,7 @@ interface ISms { * @param subId the subId id. * @return list of SmsRawData of all sms on ICC */ - List<SmsRawData> getAllMessagesFromIccEfUsingSubId(in long subId, String callingPkg); + List<SmsRawData> getAllMessagesFromIccEfForSubscriber(in long subId, String callingPkg); /** * Update the specified message on the ICC. @@ -75,7 +75,7 @@ interface ISms { * @return success or not * */ - boolean updateMessageOnIccEfUsingSubId(in long subId, String callingPkg, + boolean updateMessageOnIccEfForSubscriber(in long subId, String callingPkg, int messageIndex, int newStatus, in byte[] pdu); /** @@ -99,7 +99,7 @@ interface ISms { * @return success or not * */ - boolean copyMessageToIccEfUsingSubId(in long subId, String callingPkg, int status, + boolean copyMessageToIccEfForSubscriber(in long subId, String callingPkg, int status, in byte[] pdu, in byte[] smsc); /** @@ -152,7 +152,7 @@ interface ISms { * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId id. */ - void sendDataUsingSubId(long subId, String callingPkg, in String destAddr, + void sendDataForSubscriber(long subId, String callingPkg, in String destAddr, in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent); @@ -206,7 +206,7 @@ interface ISms { * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. */ - void sendTextUsingSubId(in long subId, String callingPkg, in String destAddr, + void sendTextForSubscriber(in long subId, String callingPkg, in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent, in PendingIntent deliveryIntent); @@ -283,7 +283,7 @@ interface ISms { * extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. */ - void sendMultipartTextUsingSubId(in long subId, String callingPkg, + void sendMultipartTextForSubscriber(in long subId, String callingPkg, in String destinationAddress, in String scAddress, in List<String> parts, in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents); @@ -315,7 +315,7 @@ interface ISms { * * @see #disableCellBroadcast(int) */ - boolean enableCellBroadcastUsingSubId(in long subId, int messageIdentifier); + boolean enableCellBroadcastForSubscriber(in long subId, int messageIdentifier); /** * Disable reception of cell broadcast (SMS-CB) messages with the given @@ -344,7 +344,7 @@ interface ISms { * * @see #enableCellBroadcast(int) */ - boolean disableCellBroadcastUsingSubId(in long subId, int messageIdentifier); + boolean disableCellBroadcastForSubscriber(in long subId, int messageIdentifier); /* * Enable reception of cell broadcast (SMS-CB) messages with the given @@ -377,7 +377,7 @@ interface ISms { * * @see #disableCellBroadcastRange(int, int) */ - boolean enableCellBroadcastRangeUsingSubId(long subId, int startMessageId, int endMessageId); + boolean enableCellBroadcastRangeForSubscriber(long subId, int startMessageId, int endMessageId); /** * Disable reception of cell broadcast (SMS-CB) messages with the given @@ -410,7 +410,7 @@ interface ISms { * * @see #enableCellBroadcastRange(int, int, int) */ - boolean disableCellBroadcastRangeUsingSubId(long subId, int startMessageId, + boolean disableCellBroadcastRangeForSubscriber(long subId, int startMessageId, int endMessageId); /** @@ -423,7 +423,7 @@ interface ISms { * Returns the premium SMS send permission for the specified package. * Requires system permission. */ - int getPremiumSmsPermissionUsingSubId(long subId, String packageName); + int getPremiumSmsPermissionForSubscriber(long subId, String packageName); /** * Set the SMS send permission for the specified package. @@ -439,7 +439,7 @@ interface ISms { * Set the SMS send permission for the specified package. * Requires system permission. */ - void setPremiumSmsPermissionUsingSubId(long subId, String packageName, int permission); + void setPremiumSmsPermissionForSubscriber(long subId, String packageName, int permission); /** * SMS over IMS is supported if IMS is registered and SMS is supported @@ -459,7 +459,7 @@ interface ISms { * * @see #getImsSmsFormat() */ - boolean isImsSmsSupportedUsingSubId(long subId); + boolean isImsSmsSupportedForSubscriber(long subId); /* * get user prefered SMS subId @@ -489,7 +489,7 @@ interface ISms { * * @see #isImsSmsSupported() */ - String getImsSmsFormatUsingSubId(long subId); + String getImsSmsFormatForSubscriber(long subId); /* * Get SMS prompt property, enabled or not diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index 46d0660..b87365e 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -25,7 +25,7 @@ interface ISub { * @param subId The unique SubInfoRecord index in database * @return SubInfoRecord, maybe null */ - SubInfoRecord getSubInfoUsingSubId(long subId); + SubInfoRecord getSubInfoForSubscriber(long subId); /** * Get the SubInfoRecord according to an IccId diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 79c72b88..fa9cad4 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -59,7 +59,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether it hung up */ - boolean endCallUsingSubId(long subId); + boolean endCallForSubscriber(long subId); /** * Answer the currently-ringing call. @@ -103,7 +103,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is OFFHOOK. */ - boolean isOffhookUsingSubId(long subId); + boolean isOffhookForSubscriber(long subId); /** * Check if an incoming phone call is ringing or call waiting @@ -112,7 +112,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is RINGING. */ - boolean isRingingUsingSubId(long subId); + boolean isRingingForSubscriber(long subId); /** * Check if an incoming phone call is ringing or call waiting. @@ -132,7 +132,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is IDLE. */ - boolean isIdleUsingSubId(long subId); + boolean isIdleForSubscriber(long subId); /** * Check to see if the radio is on or not. @@ -145,7 +145,7 @@ interface ITelephony { * @param subId user preferred subId. * @return returns true if the radio is on. */ - boolean isRadioOnUsingSubId(long subId); + boolean isRadioOnForSubscriber(long subId); /** * Check if the SIM pin lock is enabled. @@ -167,7 +167,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether the operation was a success. */ - boolean supplyPinUsingSubId(long subId, String pin); + boolean supplyPinForSubscriber(long subId, String pin); /** * Supply puk to unlock the SIM and set SIM pin to new pin. @@ -186,7 +186,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether the operation was a success. */ - boolean supplyPukUsingSubId(long subId, String puk, String pin); + boolean supplyPukForSubscriber(long subId, String puk, String pin); /** * Supply a pin to unlock the SIM. Blocks until a result is determined. @@ -204,7 +204,7 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPinReportResultUsingSubId(long subId, String pin); + int[] supplyPinReportResultForSubscriber(long subId, String pin); /** * Supply puk to unlock the SIM and set SIM pin to new pin. @@ -226,7 +226,7 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPukReportResultUsingSubId(long subId, String puk, String pin); + int[] supplyPukReportResultForSubscriber(long subId, String puk, String pin); /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated @@ -245,7 +245,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if MMI command is executed. */ - boolean handlePinMmiUsingSubId(long subId, String dialString); + boolean handlePinMmiForSubscriber(long subId, String dialString); /** * Toggles the radio on or off. @@ -256,7 +256,7 @@ interface ITelephony { * Toggles the radio on or off on particular subId. * @param subId user preferred subId. */ - void toggleRadioOnOffUsingSubId(long subId); + void toggleRadioOnOffForSubscriber(long subId); /** * Set the radio to on or off @@ -267,7 +267,7 @@ interface ITelephony { * Set the radio to on or off on particular subId. * @param subId user preferred subId. */ - boolean setRadioUsingSubId(long subId, boolean turnOn); + boolean setRadioForSubscriber(long subId, boolean turnOn); /** * Set the radio to on or off unconditionally @@ -283,7 +283,7 @@ interface ITelephony { * Request to update location information for a subscrition in service state * @param subId user preferred subId. */ - void updateServiceLocationUsingSubId(long subId); + void updateServiceLocationForSubscriber(long subId); /** * Enable location update notifications. @@ -294,7 +294,7 @@ interface ITelephony { * Enable location update notifications. * @param subId user preferred subId. */ - void enableLocationUpdatesUsingSubId(long subId); + void enableLocationUpdatesForSubscriber(long subId); /** * Disable location update notifications. @@ -305,7 +305,7 @@ interface ITelephony { * Disable location update notifications. * @param subId user preferred subId. */ - void disableLocationUpdatesUsingSubId(long subId); + void disableLocationUpdatesForSubscriber(long subId); /** * Allow mobile data connections. @@ -334,7 +334,7 @@ interface ITelephony { /** * Returns the call state for a subId. */ - int getCallStateUsingSubId(long subId); + int getCallStateForSubscriber(long subId); int getDataActivity(); int getDataState(); @@ -352,7 +352,7 @@ interface ITelephony { * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE * @param subId user preferred subId. */ - int getActivePhoneTypeUsingSubId(long subId); + int getActivePhoneTypeForSubscriber(long subId); /** * Returns the CDMA ERI icon index to display @@ -363,7 +363,7 @@ interface ITelephony { * Returns the CDMA ERI icon index to display on particular subId. * @param subId user preferred subId. */ - int getCdmaEriIconIndexUsingSubId(long subId); + int getCdmaEriIconIndexForSubscriber(long subId); /** * Returns the CDMA ERI icon mode, @@ -378,7 +378,7 @@ interface ITelephony { * 1 - FLASHING * @param subId user preferred subId. */ - int getCdmaEriIconModeUsingSubId(long subId); + int getCdmaEriIconModeForSubscriber(long subId); /** * Returns the CDMA ERI text, @@ -389,7 +389,7 @@ interface ITelephony { * Returns the CDMA ERI text for particular subId, * @param subId user preferred subId. */ - String getCdmaEriTextUsingSubId(long subId); + String getCdmaEriTextForSubscriber(long subId); /** * Returns true if OTA service provisioning needs to run. @@ -408,7 +408,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the unread count of voicemails */ - int getVoiceMessageCountUsingSubId(long subId); + int getVoiceMessageCountForSubscriber(long subId); /** * Returns the network type for data transmission @@ -420,7 +420,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getNetworkTypeUsingSubId(long subId); + int getNetworkTypeForSubscriber(long subId); /** * Returns the network type for data transmission @@ -432,7 +432,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getDataNetworkTypeUsingSubId(long subId); + int getDataNetworkTypeForSubscriber(long subId); /** * Returns the network type for voice @@ -444,7 +444,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getVoiceNetworkTypeUsingSubId(long subId); + int getVoiceNetworkTypeForSubscriber(long subId); /** * Return true if an ICC card is present @@ -476,7 +476,7 @@ interface ITelephony { * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} * or {@link PHone#LTE_ON_CDMA_TRUE} */ - int getLteOnCdmaModeUsingSubId(long subId); + int getLteOnCdmaModeForSubscriber(long subId); /** * Returns the all observed cell information of the device. @@ -715,7 +715,7 @@ interface ITelephony { * @param subId for which the simplified UI should be enabled or disabled. * @param enable true means enabling the simplified UI. */ - void enableSimplifiedNetworkSettings(long subId, boolean enable); + void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable); /** * Get whether a simplified Mobile Network Settings UI is enabled. @@ -723,7 +723,7 @@ interface ITelephony { * @param subId for which the simplified UI should be enabled or disabled. * @return true if the simplified UI is enabled. */ - boolean getSimplifiedNetworkSettingsEnabled(long subId); + boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId); /** * Set the phone number string and its alphatag for line 1 for display @@ -735,7 +735,7 @@ interface ITelephony { * @param alphaTag alpha-tagging of the dailing nubmer * @param number The dialing number */ - void setLine1NumberForDisplay(long subId, String alphaTag, String number); + void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number); /** * Returns the displayed dialing number string if it was set previously via diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index fd2d1c7..d776833 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -30,30 +30,30 @@ import com.android.internal.telephony.IPhoneStateListener; interface ITelephonyRegistry { void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenUsingSubId(in long subId, String pkg, IPhoneStateListener callback, int events, + void listenForSubscriber(in long subId, String pkg, IPhoneStateListener callback, int events, boolean notifyNow); void notifyCallState(int state, String incomingNumber); - void notifyCallStateUsingSubId(in long subId, int state, String incomingNumber); + void notifyCallStateForSubscriber(in long subId, int state, String incomingNumber); void notifyServiceState(in ServiceState state); - void notifyServiceStateUsingSubId(in long subId, in ServiceState state); + void notifyServiceStateForSubscriber(in long subId, in ServiceState state); void notifySignalStrength(in SignalStrength signalStrength); - void notifySignalStrengthUsingSubId(in long subId, in SignalStrength signalStrength); + void notifySignalStrengthForSubscriber(in long subId, in SignalStrength signalStrength); void notifyMessageWaitingChanged(boolean mwi); - void notifyMessageWaitingChangedUsingSubId(in long subId, boolean mwi); + void notifyMessageWaitingChangedForSubscriber(in long subId, boolean mwi); void notifyCallForwardingChanged(boolean cfi); - void notifyCallForwardingChangedUsingSubId(in long subId, boolean cfi); + void notifyCallForwardingChangedForSubscriber(in long subId, boolean cfi); void notifyDataActivity(int state); - void notifyDataActivityUsingSubId(in long subId, int state); + void notifyDataActivityForSubscriber(in long subId, int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionUsingSubId(long subId, int state, boolean isDataConnectivityPossible, + void notifyDataConnectionForSubscriber(long subId, int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); void notifyDataConnectionFailed(String reason, String apnType); - void notifyDataConnectionFailedUsingSubId(long subId, String reason, String apnType); + void notifyDataConnectionFailedForSubscriber(long subId, String reason, String apnType); void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationUsingSubId(in long subId, in Bundle cellLocation); + void notifyCellLocationForSubscriber(in long subId, in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); void notifyCellInfo(in List<CellInfo> cellInfo); void notifyPreciseCallState(int ringingCallState, int foregroundCallState, @@ -61,7 +61,7 @@ interface ITelephonyRegistry { void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause); void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause); - void notifyCellInfoUsingSubId(in long subId, in List<CellInfo> cellInfo); + void notifyCellInfoForSubscriber(in long subId, in List<CellInfo> cellInfo); void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo); void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); } diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 34992b8..c89208d 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -124,7 +124,7 @@ public interface TelephonyProperties static final String PROPERTY_ECM_EXIT_TIMER = "ro.cdma.ecmexittimer"; /** the international dialing prefix of current operator network */ - static final String PROPERTY_OPERATOR_IDP_STRING = "telephony.operator.idpstring"; + static final String PROPERTY_OPERATOR_IDP_STRING = "gsm.operator.idpstring"; /** * Defines the schema for the carrier specified OTASP number diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java index 44787e7..6837d22 100644 --- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java +++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java @@ -73,7 +73,7 @@ public class ActivityTestMain extends Activity { Intent intent = new Intent(ActivityTestMain.this, SpamActivity.class); Bundle options = null; if (fg) { - ActivityOptions opts = ActivityOptions.makeLaunchTaskBehindAnimation(); + ActivityOptions opts = ActivityOptions.makeTaskLaunchBehind(); options = opts.toBundle(); } startActivity(intent, options); diff --git a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java index 5bf59c7..a2e9117 100644 --- a/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java +++ b/tests/Compatibility/src/com/android/compatibilitytest/AppCompatibility.java @@ -208,6 +208,12 @@ public class AppCompatibility extends InstrumentationTestCase { Log.d(TAG, "Found process " + app.processName); return true; } + for (String relatedPackage : app.pkgList) { + if (relatedPackage.equalsIgnoreCase(processName)) { + Log.d(TAG, "Found process " + app.processName); + return true; + } + } } Log.d(TAG, "Failed to find process " + processName + " with package name " + packageName); diff --git a/tests/WallpaperTest/Android.mk b/tests/WallpaperTest/Android.mk new file mode 100644 index 0000000..b4259cd --- /dev/null +++ b/tests/WallpaperTest/Android.mk @@ -0,0 +1,15 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := WallpaperTest + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) + diff --git a/tests/WallpaperTest/AndroidManifest.xml b/tests/WallpaperTest/AndroidManifest.xml new file mode 100644 index 0000000..4c914dd --- /dev/null +++ b/tests/WallpaperTest/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.wallpapertest" > + + <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" /> + + <application + android:label="@string/app_name" + android:theme="@style/AppTheme" > + <activity + android:name=".MainActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <service + android:label="@string/test_wallpaper" + android:name=".TestWallpaper" + android:permission="android.permission.BIND_WALLPAPER" + android:enabled="true"> + <intent-filter> + <action android:name="android.service.wallpaper.WallpaperService" /> + </intent-filter> + <meta-data android:name="android.service.wallpaper" + android:resource="@xml/test_wallpaper" /> + </service> + </application> +</manifest> diff --git a/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png b/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png Binary files differnew file mode 100644 index 0000000..df92eb5 --- /dev/null +++ b/tests/WallpaperTest/res/drawable-hdpi/test_wallpaper_thumb.png diff --git a/tests/WallpaperTest/res/layout/activity_main.xml b/tests/WallpaperTest/res/layout/activity_main.xml new file mode 100644 index 0000000..d968396 --- /dev/null +++ b/tests/WallpaperTest/res/layout/activity_main.xml @@ -0,0 +1,177 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/window_background"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/dimens"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/width"/> + <EditText + android:id="@+id/dimen_width" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberDecimal"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/height"/> + <EditText + android:id="@+id/dimen_height" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberDecimal"/> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/wallpaper_offset"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/x"/> + <EditText + android:id="@+id/walloff_x" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberDecimal"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/y"/> + <EditText + android:id="@+id/walloff_y" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberDecimal"/> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/padding"/> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/left"/> + <EditText + android:id="@+id/padding_left" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="number"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/right"/> + <EditText + android:id="@+id/padding_right" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="number"/> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/top"/> + <EditText + android:id="@+id/padding_top" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="number"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/bottom"/> + <EditText + android:id="@+id/padding_bottom" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="number"/> + </LinearLayout> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/display_offset"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/x"/> + <EditText + android:id="@+id/dispoff_x" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberSigned"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="15dp" + android:textSize="17sp" + android:text="@string/y"/> + <EditText + android:id="@+id/dispoff_y" + android:layout_width="60sp" + android:layout_height="wrap_content" + android:inputType="numberSigned"/> + </LinearLayout> + </LinearLayout> +</ScrollView> diff --git a/tests/WallpaperTest/res/values-v11/styles.xml b/tests/WallpaperTest/res/values-v11/styles.xml new file mode 100644 index 0000000..95000b2 --- /dev/null +++ b/tests/WallpaperTest/res/values-v11/styles.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme for API 11+. This theme completely replaces + AppBaseTheme from res/values/styles.xml on API 11+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Holo.Wallpaper"> + <!-- API 11 theme customizations can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/WallpaperTest/res/values-v21/styles.xml b/tests/WallpaperTest/res/values-v21/styles.xml new file mode 100644 index 0000000..e42d526 --- /dev/null +++ b/tests/WallpaperTest/res/values-v21/styles.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme for API 21+. This theme completely replaces + AppBaseTheme from BOTH res/values/styles.xml and + res/values-v11/styles.xml on API 14+ devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Material.Wallpaper"> + <!-- API 14 theme customizations can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/WallpaperTest/res/values/colors.xml b/tests/WallpaperTest/res/values/colors.xml new file mode 100644 index 0000000..8c08249 --- /dev/null +++ b/tests/WallpaperTest/res/values/colors.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ 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 + --> +<resources> + <color name="window_background">#80000000</color> +</resources>
\ No newline at end of file diff --git a/tests/WallpaperTest/res/values/strings.xml b/tests/WallpaperTest/res/values/strings.xml new file mode 100644 index 0000000..fd21259 --- /dev/null +++ b/tests/WallpaperTest/res/values/strings.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2014 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + <string name="app_name">Wallpaper Test</string> + + <string name="test_wallpaper">Test Wallpaper</string> + <string name="test_wallpaper_author">Google</string> + <string name="test_wallpaper_desc"> + Test wallpaper for use with the wallpaper test app. + </string> + + <string name="dimens">Dimens: </string> + <string name="width">Width: </string> + <string name="height">Height: </string> + + <string name="wallpaper_offset">Wall off: </string> + <string name="x">X: </string> + <string name="y">Y: </string> + + <string name="padding">Padding: </string> + <string name="left">Left: </string> + <string name="right">Right: </string> + <string name="top">Top: </string> + <string name="bottom">Bottom: </string> + + <string name="display_offset">Disp off: </string> +</resources> diff --git a/tests/WallpaperTest/res/values/styles.xml b/tests/WallpaperTest/res/values/styles.xml new file mode 100644 index 0000000..d2b91d6 --- /dev/null +++ b/tests/WallpaperTest/res/values/styles.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2013 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<resources> + + <!-- + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + --> + <style name="AppBaseTheme" parent="android:Theme.Wallpaper"> + <!-- + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + --> + </style> + + <!-- Application theme. --> + <style name="AppTheme" parent="AppBaseTheme"> + <!-- All customizations that are NOT specific to a particular API-level can go here. --> + </style> + +</resources>
\ No newline at end of file diff --git a/tests/WallpaperTest/res/xml/test_wallpaper.xml b/tests/WallpaperTest/res/xml/test_wallpaper.xml new file mode 100644 index 0000000..9f7d714 --- /dev/null +++ b/tests/WallpaperTest/res/xml/test_wallpaper.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2008, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * 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. + */ +--> + +<!-- The attributes in this XML file provide configuration information --> +<!-- about the polar clock. --> + +<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" + android:author="@string/test_wallpaper_author" + android:description="@string/test_wallpaper_desc" + android:thumbnail="@drawable/test_wallpaper_thumb" /> diff --git a/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java new file mode 100644 index 0000000..7880f67 --- /dev/null +++ b/tests/WallpaperTest/src/com/example/wallpapertest/MainActivity.java @@ -0,0 +1,176 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wallpapertest; + +import android.app.Activity; +import android.app.WallpaperManager; +import android.content.Context; +import android.graphics.Point; +import android.graphics.Rect; +import android.os.Bundle; +import android.os.IBinder; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Log; +import android.view.WindowManager; +import android.widget.TextView; + +public class MainActivity extends Activity { + private static final String TAG = "MainActivity"; + + WallpaperManager mWallpaperManager; + WindowManager mWindowManager; + + TextView mDimenWidthView; + TextView mDimenHeightView; + + TextView mWallOffXView; + TextView mWallOffYView; + + TextView mPaddingLeftView; + TextView mPaddingRightView; + TextView mPaddingTopView; + TextView mPaddingBottomView; + + TextView mDispOffXView; + TextView mDispOffYView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + mWallpaperManager = (WallpaperManager)getSystemService(Context.WALLPAPER_SERVICE); + mWindowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE); + + mDimenWidthView = (TextView) findViewById(R.id.dimen_width); + mDimenWidthView.addTextChangedListener(mTextWatcher); + mDimenHeightView = (TextView) findViewById(R.id.dimen_height); + mDimenHeightView.addTextChangedListener(mTextWatcher); + + mWallOffXView = (TextView) findViewById(R.id.walloff_x); + mWallOffXView.addTextChangedListener(mTextWatcher); + mWallOffYView = (TextView) findViewById(R.id.walloff_y); + mWallOffYView.addTextChangedListener(mTextWatcher); + + mPaddingLeftView = (TextView) findViewById(R.id.padding_left); + mPaddingLeftView.addTextChangedListener(mTextWatcher); + mPaddingRightView = (TextView) findViewById(R.id.padding_right); + mPaddingRightView.addTextChangedListener(mTextWatcher); + mPaddingTopView = (TextView) findViewById(R.id.padding_top); + mPaddingTopView.addTextChangedListener(mTextWatcher); + mPaddingBottomView = (TextView) findViewById(R.id.padding_bottom); + mPaddingBottomView.addTextChangedListener(mTextWatcher); + + mDispOffXView = (TextView) findViewById(R.id.dispoff_x); + mDispOffXView.addTextChangedListener(mTextWatcher); + mDispOffYView = (TextView) findViewById(R.id.dispoff_y); + mDispOffYView.addTextChangedListener(mTextWatcher); + + updateDimens(); + updateWallOff(); + updatePadding(); + updateDispOff(); + } + + private int loadPropIntText(TextView view, int baseVal) { + String str = view.getText().toString(); + if (str != null && !TextUtils.isEmpty(str)) { + try { + float fval = Float.parseFloat(str); + return (int)(fval*baseVal); + } catch (NumberFormatException e) { + Log.i(TAG, "Bad number: " + str, e); + } + } + return baseVal; + } + + private float loadFloatText(TextView view) { + String str = view.getText().toString(); + if (str != null && !TextUtils.isEmpty(str)) { + try { + return Float.parseFloat(str); + } catch (NumberFormatException e) { + Log.i(TAG, "Bad number: " + str, e); + } + } + return 0; + } + + private int loadIntText(TextView view) { + String str = view.getText().toString(); + if (str != null && !TextUtils.isEmpty(str)) { + try { + return Integer.parseInt(str); + } catch (NumberFormatException e) { + Log.i(TAG, "Bad number: " + str, e); + } + } + return 0; + } + + public void updateDimens() { + Point minDims = new Point(); + Point maxDims = new Point(); + mWindowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims); + mWallpaperManager.suggestDesiredDimensions( + loadPropIntText(mDimenWidthView, maxDims.x), + loadPropIntText(mDimenHeightView, maxDims.y)); + } + + public void updateWallOff() { + IBinder token = getWindow().getDecorView().getWindowToken(); + if (token != null) { + mWallpaperManager.setWallpaperOffsets(token, loadFloatText(mWallOffXView), + loadFloatText(mWallOffYView)); + } + } + + public void updatePadding() { + Rect padding = new Rect(); + padding.left = loadIntText(mPaddingLeftView); + padding.top = loadIntText(mPaddingTopView); + padding.right = loadIntText(mPaddingRightView); + padding.bottom = loadIntText(mPaddingBottomView); + mWallpaperManager.setDisplayPadding(padding); + } + + public void updateDispOff() { + IBinder token = getWindow().getDecorView().getWindowToken(); + if (token != null) { + mWallpaperManager.setDisplayOffset(token, loadIntText(mDispOffXView), + loadIntText(mDispOffYView)); + } + } + + final TextWatcher mTextWatcher = new TextWatcher() { + @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override public void onTextChanged(CharSequence s, int start, int before, int count) { + updateDimens(); + updateWallOff(); + updatePadding(); + updateDispOff(); + } + + @Override public void afterTextChanged(Editable s) { + } + }; +} diff --git a/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java b/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java new file mode 100644 index 0000000..95db6d1 --- /dev/null +++ b/tests/WallpaperTest/src/com/example/wallpapertest/TestWallpaper.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.wallpapertest; + +import android.service.wallpaper.WallpaperService; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.Paint; +import android.graphics.Color; +import android.graphics.RectF; +import android.text.TextPaint; +import android.view.SurfaceHolder; +import android.content.res.XmlResourceParser; + +import android.os.Handler; +import android.util.Log; + +import android.view.WindowInsets; + +public class TestWallpaper extends WallpaperService { + private static final String LOG_TAG = "PolarClock"; + + private final Handler mHandler = new Handler(); + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + public Engine onCreateEngine() { + return new ClockEngine(); + } + + class ClockEngine extends Engine { + private static final int OUTER_COLOR = 0xffff0000; + private static final int INNER_COLOR = 0xff000080; + private static final int STABLE_COLOR = 0xa000ff00; + private static final int TEXT_COLOR = 0xa0ffffff; + + private final Paint.FontMetrics mTextMetrics = new Paint.FontMetrics(); + + private int mPadding; + + private final Rect mMainInsets = new Rect(); + private final Rect mStableInsets = new Rect(); + private boolean mRound = false; + + private int mDesiredWidth; + private int mDesiredHeight; + + private float mOffsetX; + private float mOffsetY; + private float mOffsetXStep; + private float mOffsetYStep; + private int mOffsetXPixels; + private int mOffsetYPixels; + + private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Paint mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + + private final Runnable mDrawClock = new Runnable() { + public void run() { + drawFrame(); + } + }; + private boolean mVisible; + + ClockEngine() { + } + + @Override + public void onCreate(SurfaceHolder surfaceHolder) { + super.onCreate(surfaceHolder); + + mDesiredWidth = getDesiredMinimumWidth(); + mDesiredHeight = getDesiredMinimumHeight(); + + Paint paint = mFillPaint; + paint.setStyle(Paint.Style.FILL); + + paint = mStrokePaint; + paint.setStrokeWidth(3); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStyle(Paint.Style.STROKE); + + TextPaint tpaint = mTextPaint; + tpaint.density = getResources().getDisplayMetrics().density; + tpaint.setCompatibilityScaling(getResources().getCompatibilityInfo().applicationScale); + tpaint.setColor(TEXT_COLOR); + tpaint.setTextSize(18 * getResources().getDisplayMetrics().scaledDensity); + tpaint.setShadowLayer(4 * getResources().getDisplayMetrics().density, 0, 0, 0xff000000); + + mTextPaint.getFontMetrics(mTextMetrics); + + mPadding = (int)(16 * getResources().getDisplayMetrics().density); + + if (isPreview()) { + mOffsetX = 0.5f; + mOffsetY = 0.5f; + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + mHandler.removeCallbacks(mDrawClock); + } + + @Override + public void onVisibilityChanged(boolean visible) { + mVisible = visible; + if (!visible) { + mHandler.removeCallbacks(mDrawClock); + } + drawFrame(); + } + + @Override + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { + super.onSurfaceChanged(holder, format, width, height); + drawFrame(); + } + + @Override + public void onSurfaceCreated(SurfaceHolder holder) { + super.onSurfaceCreated(holder); + } + + @Override + public void onSurfaceDestroyed(SurfaceHolder holder) { + super.onSurfaceDestroyed(holder); + mVisible = false; + mHandler.removeCallbacks(mDrawClock); + } + + @Override + public void onApplyWindowInsets(WindowInsets insets) { + super.onApplyWindowInsets(insets); + mMainInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), + insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); + mStableInsets.set(insets.getStableInsetLeft(), insets.getStableInsetTop(), + insets.getStableInsetRight(), insets.getStableInsetBottom()); + mRound = insets.isRound(); + drawFrame(); + } + + @Override + public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) { + super.onDesiredSizeChanged(desiredWidth, desiredHeight); + mDesiredWidth = desiredWidth; + mDesiredHeight = desiredHeight; + drawFrame(); + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, + float xStep, float yStep, int xPixels, int yPixels) { + super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels); + + if (isPreview()) return; + + mOffsetX = xOffset; + mOffsetY = yOffset; + mOffsetXStep = xStep; + mOffsetYStep = yStep; + mOffsetXPixels = xPixels; + mOffsetYPixels = yPixels; + + drawFrame(); + } + + void drawFrame() { + final SurfaceHolder holder = getSurfaceHolder(); + final Rect frame = holder.getSurfaceFrame(); + final int width = frame.width(); + final int height = frame.height(); + + Canvas c = null; + try { + c = holder.lockCanvas(); + if (c != null) { + final Paint paint = mFillPaint; + + paint.setColor(OUTER_COLOR); + c.drawRect(0, 0, width, height, paint); + + paint.setColor(INNER_COLOR); + c.drawRect(0+mMainInsets.left, 0+mMainInsets.top, + width-mMainInsets.right, height-mMainInsets.bottom, paint); + + mStrokePaint.setColor(STABLE_COLOR); + c.drawRect(0 + mStableInsets.left, 0 + mStableInsets.top, + width - mStableInsets.right, height - mStableInsets.bottom, + mStrokePaint); + + final int ascdesc = (int)(-mTextMetrics.ascent + mTextMetrics.descent); + final int linegap = (int)(-mTextMetrics.ascent + mTextMetrics.descent + + mTextMetrics.leading); + + int x = mStableInsets.left + mPadding; + int y = height - mStableInsets.bottom - mPadding - ascdesc; + c.drawText("Surface Size: " + width + " x " + height, + x, y, mTextPaint); + y -= linegap; + c.drawText("Desired Size: " + mDesiredWidth + " x " + mDesiredHeight, + x, y, mTextPaint); + y -= linegap; + c.drawText("Cur Offset Raw: " + mOffsetX + ", " + mOffsetY, + x, y, mTextPaint); + y -= linegap; + c.drawText("Cur Offset Step: " + mOffsetXStep + ", " + mOffsetYStep, + x, y, mTextPaint); + y -= linegap; + c.drawText("Cur Offset Pixels: " + mOffsetXPixels + ", " + mOffsetYPixels, + x, y, mTextPaint); + y -= linegap; + c.drawText("Stable Insets: (" + mStableInsets.left + ", " + mStableInsets.top + + ") - (" + mStableInsets.right + ", " + mStableInsets.bottom + ")", + x, y, mTextPaint); + y -= linegap; + c.drawText("System Insets: (" + mMainInsets.left + ", " + mMainInsets.top + + ") - (" + mMainInsets.right + ", " + mMainInsets.bottom + ")", + x, y, mTextPaint); + + } + } finally { + if (c != null) holder.unlockCanvasAndPost(c); + } + } + } +} diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index b3c364b..8341de6 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2574,8 +2574,12 @@ status_t ResourceTable::addSymbols(const sp<AaptSymbols>& outSymbols) { continue; } const size_t N = t->getOrderedConfigs().size(); - sp<AaptSymbols> typeSymbols; - typeSymbols = outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); + sp<AaptSymbols> typeSymbols = + outSymbols->addNestedSymbol(String8(t->getName()), t->getPos()); + if (typeSymbols == NULL) { + return UNKNOWN_ERROR; + } + for (size_t ci=0; ci<N; ci++) { sp<ConfigList> c = t->getOrderedConfigs().itemAt(ci); if (c == NULL) { diff --git a/tools/layoutlib/.idea/codeStyleSettings.xml b/tools/layoutlib/.idea/codeStyleSettings.xml index 33937b3..b324213 100644 --- a/tools/layoutlib/.idea/codeStyleSettings.xml +++ b/tools/layoutlib/.idea/codeStyleSettings.xml @@ -27,12 +27,12 @@ <package name="" withSubpackages="true" static="true" /> </value> </option> + <option name="RIGHT_MARGIN" value="100" /> <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" /> <option name="JD_ALIGN_PARAM_COMMENTS" value="false" /> <option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" /> <option name="JD_ADD_BLANK_AFTER_RETURN" value="true" /> <option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" /> - <option name="RIGHT_MARGIN" value="100" /> <option name="WRAP_COMMENTS" value="true" /> <XML> <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" /> diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java index fbe21a8..aaba545 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java @@ -809,11 +809,6 @@ public final class BridgeTypedArray extends TypedArray { return new CharSequence[] { value }; } - Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, - String.format( - String.format("Unknown value for getTextArray(%d) => %s", //DEBUG - index, mResourceData[index].getName())), null); - return null; } 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 130500a..0ed6ab1 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 @@ -174,6 +174,11 @@ public final class BridgeWindowSession implements IWindowSession { } @Override + public void setWallpaperDisplayOffset(IBinder windowToken, int x, int y) { + // pass for now. + } + + @Override public Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, int z, Bundle extras, boolean sync) { // pass for now. diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk index 7a9e067..5e47c8c 100644 --- a/tools/layoutlib/bridge/tests/Android.mk +++ b/tools/layoutlib/bridge/tests/Android.mk @@ -34,5 +34,8 @@ LOCAL_JAVA_LIBRARIES := layoutlib \ include $(BUILD_HOST_JAVA_LIBRARY) +# Copy the jar to DIST_DIR for sdk builds +$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE)) + # Build all sub-directories include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk index 9bd48ab..e6f0bc3 100644 --- a/tools/layoutlib/create/Android.mk +++ b/tools/layoutlib/create/Android.mk @@ -26,3 +26,6 @@ LOCAL_MODULE := layoutlib_create include $(BUILD_HOST_JAVA_LIBRARY) +# Build all sub-directories +include $(call all-makefiles-under,$(LOCAL_PATH)) + diff --git a/tools/layoutlib/create/tests/Android.mk b/tools/layoutlib/create/tests/Android.mk index 0052ec2..c197d57 100644 --- a/tools/layoutlib/create/tests/Android.mk +++ b/tools/layoutlib/create/tests/Android.mk @@ -28,5 +28,8 @@ LOCAL_STATIC_JAVA_LIBRARIES := asm-4.0 include $(BUILD_HOST_JAVA_LIBRARY) +# Copy the jar to DIST_DIR for sdk builds +$(call dist-for-goals, sdk win_sdk, $(LOCAL_INSTALLED_MODULE)) + # Build all sub-directories include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/wifi/java/android/net/wifi/IWifiScanner.aidl b/wifi/java/android/net/wifi/IWifiScanner.aidl index fef2d11..3984934 100644 --- a/wifi/java/android/net/wifi/IWifiScanner.aidl +++ b/wifi/java/android/net/wifi/IWifiScanner.aidl @@ -17,6 +17,7 @@ package android.net.wifi; import android.os.Messenger; +import android.os.Bundle; /** * {@hide} @@ -24,4 +25,6 @@ import android.os.Messenger; interface IWifiScanner { Messenger getMessenger(); + + Bundle getAvailableChannels(int band); } diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java index ac2a176..21f200f 100644 --- a/wifi/java/android/net/wifi/WifiConfiguration.java +++ b/wifi/java/android/net/wifi/WifiConfiguration.java @@ -341,6 +341,12 @@ public class WifiConfiguration implements Parcelable { /** * @hide + * last time we connected, this configuration had no internet access + */ + public boolean noInternetAccess; + + /** + * @hide * Uid of app creating the configuration */ @SystemApi @@ -673,6 +679,49 @@ public class WifiConfiguration implements Parcelable { @SystemApi public int numAssociation; + /** + * @hide + * Number of time user disabled WiFi while associated to this configuration with Low RSSI. + */ + public int numUserTriggeredWifiDisableLowRSSI; + + /** + * @hide + * Number of time user disabled WiFi while associated to this configuration with Bad RSSI. + */ + public int numUserTriggeredWifiDisableBadRSSI; + + /** + * @hide + * Number of time user disabled WiFi while associated to this configuration + * and RSSI was not HIGH. + */ + public int numUserTriggeredWifiDisableNotHighRSSI; + + /** + * @hide + * Number of ticks associated to this configuration with Low RSSI. + */ + public int numTicksAtLowRSSI; + + /** + * @hide + * Number of ticks associated to this configuration with Bad RSSI. + */ + public int numTicksAtBadRSSI; + + /** + * @hide + * Number of ticks associated to this configuration + * and RSSI was not HIGH. + */ + public int numTicksAtNotHighRSSI; + /** + * @hide + * Number of time user (WifiManager) triggered association to this configuration. + * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps + */ + public int numUserTriggeredJoinAttempts; /** * @hide @@ -725,6 +774,7 @@ public class WifiConfiguration implements Parcelable { selfAdded = false; didSelfAdd = false; ephemeral = false; + noInternetAccess = false; mIpConfiguration = new IpConfiguration(); } @@ -824,8 +874,10 @@ public class WifiConfiguration implements Parcelable { sbuf.append(" autoJoinStatus ").append(this.numConnectionFailures).append("\n"); } if (this.didSelfAdd || this.selfAdded) { - if (this.didSelfAdd) sbuf.append(" didSelfAdd "); - if (this.selfAdded) sbuf.append(" selfAdded "); + if (this.didSelfAdd) sbuf.append(" didSelfAdd"); + if (this.selfAdded) sbuf.append(" selfAdded"); + if (this.noInternetAccess) sbuf.append(" noInternetAccess"); + sbuf.append("\n"); } sbuf.append(" KeyMgmt:"); @@ -896,18 +948,44 @@ public class WifiConfiguration implements Parcelable { sbuf.append(mIpConfiguration.toString()); - if (selfAdded) sbuf.append("selfAdded"); - if (creatorUid != 0) sbuf.append("uid=" + Integer.toString(creatorUid)); + if (this.creatorUid != 0) sbuf.append("uid=" + Integer.toString(creatorUid)); - if (blackListTimestamp != 0) { + if (this.blackListTimestamp != 0) { long now_ms = System.currentTimeMillis(); - long diff = now_ms - blackListTimestamp; + long diff = now_ms - this.blackListTimestamp; if (diff <= 0) { sbuf.append("blackListed since <incorrect>"); } else { sbuf.append("blackListed since ").append(Long.toString(diff/1000)).append( "sec"); } } + sbuf.append('\n'); + if (this.linkedConfigurations != null) { + for(String key : this.linkedConfigurations.keySet()) { + sbuf.append(" linked: ").append(key); + sbuf.append('\n'); + } + } + if (this.connectChoices != null) { + for(String key : this.connectChoices.keySet()) { + Integer choice = this.connectChoices.get(key); + if (choice != null) { + sbuf.append(" choice: ").append(key); + sbuf.append(" = ").append(choice); + sbuf.append('\n'); + } + } + } + sbuf.append(" triggeredLow: ").append(numUserTriggeredWifiDisableLowRSSI); + sbuf.append(" triggeredBad: ").append(numUserTriggeredWifiDisableBadRSSI); + sbuf.append(" triggeredNotHigh: ").append(numUserTriggeredWifiDisableNotHighRSSI); + sbuf.append('\n'); + sbuf.append(" ticksLow: ").append(numTicksAtLowRSSI); + sbuf.append(" ticksBad: ").append(numTicksAtBadRSSI); + sbuf.append(" ticksNotHigh: ").append(numTicksAtNotHighRSSI); + sbuf.append('\n'); + sbuf.append(" triggeredJoin: ").append(numUserTriggeredJoinAttempts); + sbuf.append('\n'); return sbuf.toString(); } @@ -1197,7 +1275,7 @@ public class WifiConfiguration implements Parcelable { mCachedConfigKey = null; //force null configKey autoJoinStatus = source.autoJoinStatus; selfAdded = source.selfAdded; - + noInternetAccess = source.noInternetAccess; if (source.visibility != null) { visibility = new Visibility(source.visibility); } @@ -1217,6 +1295,13 @@ public class WifiConfiguration implements Parcelable { numScorerOverride = source.numScorerOverride; numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; numAssociation = source.numAssociation; + numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI; + numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI; + numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI; + numTicksAtLowRSSI = source.numTicksAtLowRSSI; + numTicksAtBadRSSI = source.numTicksAtBadRSSI; + numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI; + numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts; } } @@ -1259,6 +1344,7 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(autoJoinStatus); dest.writeInt(selfAdded ? 1 : 0); dest.writeInt(didSelfAdd ? 1 : 0); + dest.writeInt(noInternetAccess ? 1 : 0); dest.writeInt(creatorUid); dest.writeInt(lastConnectUid); dest.writeInt(lastUpdateUid); @@ -1269,6 +1355,14 @@ public class WifiConfiguration implements Parcelable { dest.writeInt(numScorerOverride); dest.writeInt(numScorerOverrideAndSwitchedNetwork); dest.writeInt(numAssociation); + dest.writeInt(numUserTriggeredWifiDisableLowRSSI); + dest.writeInt(numUserTriggeredWifiDisableBadRSSI); + dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI); + dest.writeInt(numTicksAtLowRSSI); + dest.writeInt(numTicksAtBadRSSI); + dest.writeInt(numTicksAtNotHighRSSI); + dest.writeInt(numUserTriggeredJoinAttempts); + } /** Implement the Parcelable interface {@hide} */ @@ -1307,6 +1401,7 @@ public class WifiConfiguration implements Parcelable { config.autoJoinStatus = in.readInt(); config.selfAdded = in.readInt() != 0; config.didSelfAdd = in.readInt() != 0; + config.noInternetAccess = in.readInt() != 0; config.creatorUid = in.readInt(); config.lastConnectUid = in.readInt(); config.lastUpdateUid = in.readInt(); @@ -1317,6 +1412,13 @@ public class WifiConfiguration implements Parcelable { config.numScorerOverride = in.readInt(); config.numScorerOverrideAndSwitchedNetwork = in.readInt(); config.numAssociation = in.readInt(); + config.numUserTriggeredWifiDisableLowRSSI = in.readInt(); + config.numUserTriggeredWifiDisableBadRSSI = in.readInt(); + config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt(); + config.numTicksAtLowRSSI = in.readInt(); + config.numTicksAtBadRSSI = in.readInt(); + config.numTicksAtNotHighRSSI = in.readInt(); + config.numUserTriggeredJoinAttempts = in.readInt(); return config; } diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index e7bcb23..aaa2f98 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -18,6 +18,7 @@ package android.net.wifi; import android.annotation.SystemApi; import android.content.Context; +import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -75,6 +76,11 @@ public class WifiScanner { public static final int REASON_INVALID_LISTENER = -2; /** Invalid request */ public static final int REASON_INVALID_REQUEST = -3; + /** Invalid request */ + public static final int REASON_NOT_AUTHORIZED = -4; + + /** @hide */ + public static final String GET_AVAILABLE_CHANNELS_EXTRA = "Channels"; /** * Generic action callback invocation interface @@ -92,7 +98,12 @@ public class WifiScanner { * @hide */ public List<Integer> getAvailableChannels(int band) { - return null; + try { + Bundle bundle = mService.getAvailableChannels(band); + return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA); + } catch (RemoteException e) { + return null; + } } /** |