diff options
Diffstat (limited to 'core/java')
57 files changed, 1519 insertions, 844 deletions
diff --git a/core/java/android/annotation/PrivateApi.java b/core/java/android/annotation/SystemApi.java index 985eafe..55028eb 100644 --- a/core/java/android/annotation/PrivateApi.java +++ b/core/java/android/annotation/SystemApi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * 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. @@ -16,16 +16,29 @@ package android.annotation; +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** - * Indicates an API is exposed for use by bundled applications. + * Indicates an API is exposed for use by bundled system applications. * <p> * These APIs are not guaranteed to remain consistent release-to-release, - * and are not for use by apps linking against the SDK. + * and are not for use by apps linking against the Android SDK. + * </p><p> + * This annotation should only appear on API that is already marked <pre>@hide</pre>. + * </p> + * * @hide */ +@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE}) @Retention(RetentionPolicy.SOURCE) -public @interface PrivateApi { +public @interface SystemApi { } diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index d4c4318..628875f 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -68,7 +68,7 @@ import java.util.Map; * select items accessible directly from the action bar as "action items". You can also * modify various characteristics of the action bar or remove it completely.</p> * - * <p>When using the Quantum themes (default in API 21 or newer) the navigation button + * <p>When using the Material themes (default in API 21 or newer) the navigation button * (formerly "Home") takes over the space previously occupied by the application icon. * Apps wishing to express a stronger branding should use their brand colors heavily * in the action bar and other application chrome or use a {@link #setLogo(int) logo} diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java index b739387..a4384f8 100644 --- a/core/java/android/app/ActivityTransitionCoordinator.java +++ b/core/java/android/app/ActivityTransitionCoordinator.java @@ -251,13 +251,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { if (view == null) { mEpicenterCallback.setEpicenter(null); } else { - int[] loc = new int[2]; - view.getLocationOnScreen(loc); - int left = loc[0] + Math.round(view.getTranslationX()); - int top = loc[1] + Math.round(view.getTranslationY()); - int right = left + view.getWidth(); - int bottom = top + view.getHeight(); - Rect epicenter = new Rect(left, top, right, bottom); + Rect epicenter = new Rect(); + view.getBoundsOnScreen(epicenter); mEpicenterCallback.setEpicenter(epicenter); } } @@ -492,11 +487,11 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { protected Bundle captureSharedElementState() { Bundle bundle = new Bundle(); - int[] tempLoc = new int[2]; + Rect tempBounds = new Rect(); for (int i = 0; i < mSharedElementNames.size(); i++) { View sharedElement = mSharedElements.get(i); String name = mSharedElementNames.get(i); - captureSharedElementState(sharedElement, name, bundle, tempLoc); + captureSharedElementState(sharedElement, name, bundle, tempBounds); } return bundle; } @@ -509,20 +504,19 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { * @param name The shared element name in the target Activity to apply the placement * information for. * @param transitionArgs Bundle to store shared element placement information. - * @param tempLoc A temporary int[2] for capturing the current location of views. + * @param tempBounds A temporary Rect for capturing the current location of views. */ private static void captureSharedElementState(View view, String name, Bundle transitionArgs, - int[] tempLoc) { + Rect tempBounds) { Bundle sharedElementBundle = new Bundle(); - view.getLocationOnScreen(tempLoc); - float scaleX = view.getScaleX(); - sharedElementBundle.putInt(KEY_SCREEN_X, tempLoc[0]); - int width = Math.round(view.getWidth() * scaleX); + tempBounds.set(0, 0, view.getWidth(), view.getHeight()); + view.getBoundsOnScreen(tempBounds); + sharedElementBundle.putInt(KEY_SCREEN_X, tempBounds.left); + int width = tempBounds.width(); sharedElementBundle.putInt(KEY_WIDTH, width); - float scaleY = view.getScaleY(); - sharedElementBundle.putInt(KEY_SCREEN_Y, tempLoc[1]); - int height = Math.round(view.getHeight() * scaleY); + sharedElementBundle.putInt(KEY_SCREEN_Y, tempBounds.top); + int height = tempBounds.height(); sharedElementBundle.putInt(KEY_HEIGHT, height); sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ()); @@ -563,7 +557,7 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver { public void setEpicenter(Rect epicenter) { mEpicenter = epicenter; } @Override - public Rect getEpicenter(Transition transition) { + public Rect onGetEpicenter(Transition transition) { return mEpicenter; } } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 5ac2a33..72b5cd9 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2499,7 +2499,7 @@ public class Notification implements Parcelable /** * @return Whether we are currently building a notification from a legacy (an app that - * doesn't create quantum notifications by itself) app. + * doesn't create material notifications by itself) app. */ private boolean isLegacy() { return mColorUtil != null; @@ -2719,31 +2719,31 @@ public class Notification implements Parcelable private int getBaseLayoutResource() { - return R.layout.notification_template_quantum_base; + return R.layout.notification_template_material_base; } private int getBigBaseLayoutResource() { - return R.layout.notification_template_quantum_big_base; + return R.layout.notification_template_material_big_base; } private int getBigPictureLayoutResource() { - return R.layout.notification_template_quantum_big_picture; + return R.layout.notification_template_material_big_picture; } private int getBigTextLayoutResource() { - return R.layout.notification_template_quantum_big_text; + return R.layout.notification_template_material_big_text; } private int getInboxLayoutResource() { - return R.layout.notification_template_quantum_inbox; + return R.layout.notification_template_material_inbox; } private int getActionLayoutResource() { - return R.layout.notification_quantum_action; + return R.layout.notification_material_action; } private int getActionTombstoneLayoutResource() { - return R.layout.notification_quantum_action_tombstone; + return R.layout.notification_material_action_tombstone; } } @@ -3238,7 +3238,7 @@ public class Notification implements Parcelable private RemoteViews generateMediaActionButton(Action action) { final boolean tombstone = (action.actionIntent == null); RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(), - R.layout.notification_quantum_media_action); + R.layout.notification_material_media_action); button.setImageViewResource(R.id.action0, action.icon); if (!tombstone) { button.setOnClickPendingIntent(R.id.action0, action.actionIntent); @@ -3249,7 +3249,7 @@ public class Notification implements Parcelable private RemoteViews makeMediaContentView() { RemoteViews view = mBuilder.applyStandardTemplate( - R.layout.notification_template_quantum_media, true /* 1U */); + R.layout.notification_template_material_media, true /* 1U */); final int numActions = mBuilder.mActions.size(); final int N = mActionsToShowInCompact == null @@ -3274,7 +3274,7 @@ public class Notification implements Parcelable private RemoteViews makeMediaBigContentView() { RemoteViews big = mBuilder.applyStandardTemplate( - R.layout.notification_template_quantum_big_media, false); + R.layout.notification_template_material_big_media, false); final int N = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS); if (N > 0) { diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index cea5545..5579470 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -26,6 +26,7 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.RestrictionsManager; +import android.net.ProxyInfo; import android.os.Bundle; import android.os.Handler; import android.os.Process; @@ -1287,6 +1288,32 @@ public class DevicePolicyManager { } /** + * Set a network-independent global HTTP proxy. This is not normally what you want + * for typical HTTP proxies - they are generally network dependent. However if you're + * doing something unusual like general internal filtering this may be useful. On + * a private network where the proxy is not accessible, you may break HTTP using this. + * + * <p>This method requires the caller to be the device owner. + * + * <p>This proxy is only a recommendation and it is possible that some apps will ignore it. + * @see ProxyInfo + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated + * with. + * @param proxyInfo The a {@link ProxyInfo} object defining the new global + * HTTP proxy. A {@code null} value will clear the global HTTP proxy. + */ + public void setRecommendedGlobalProxy(ComponentName admin, ProxyInfo proxyInfo) { + if (mService != null) { + try { + mService.setRecommendedGlobalProxy(admin, proxyInfo); + } catch (RemoteException e) { + Log.w(TAG, "Failed talking with device policy service", e); + } + } + } + + /** * Returns the component name setting the global proxy. * @return ComponentName object of the device admin that set the global proxy, or * null if no admin has set the proxy. @@ -1805,6 +1832,23 @@ public class DevicePolicyManager { return isDeviceOwnerApp(packageName); } + /** + * Clears the current device owner. The caller must be the device owner. + * + * This function should be used cautiously as once it is called it cannot + * be undone. The device owner can only be set as a part of device setup + * before setup completes. + */ + public void clearDeviceOwnerApp() { + if (mService != null) { + try { + mService.clearDeviceOwner(mContext.getPackageName()); + } catch (RemoteException re) { + Log.w(TAG, "Failed to clear device owner"); + } + } + } + /** @hide */ public String getDeviceOwner() { if (mService != null) { @@ -2017,6 +2061,8 @@ public class DevicePolicyManager { * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param filter The {@link IntentFilter} the intent has to match to be also resolved in the * other profile + * @param flags {@link DevicePolicyManager#FLAG_MANAGED_CAN_ACCESS_PARENT} and + * {@link DevicePolicyManager#FLAG_PARENT_CAN_ACCESS_MANAGED} are supported. */ public void addCrossProfileIntentFilter(ComponentName admin, IntentFilter filter, int flags) { if (mService != null) { diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 7d7a312..4935ddc 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -20,6 +20,7 @@ package android.app.admin; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; +import android.net.ProxyInfo; import android.os.Bundle; import android.os.RemoteCallback; import android.os.UserHandle; @@ -78,6 +79,7 @@ interface IDevicePolicyManager { ComponentName setGlobalProxy(in ComponentName admin, String proxySpec, String exclusionList, int userHandle); ComponentName getGlobalProxyAdmin(int userHandle); + void setRecommendedGlobalProxy(in ComponentName admin, in ProxyInfo proxyInfo); int setStorageEncryption(in ComponentName who, boolean encrypt, int userHandle); boolean getStorageEncryption(in ComponentName who, int userHandle); @@ -106,6 +108,7 @@ interface IDevicePolicyManager { boolean isDeviceOwner(String packageName); String getDeviceOwner(); String getDeviceOwnerName(); + void clearDeviceOwner(String packageName); boolean setProfileOwner(String packageName, String ownerName, int userHandle); String getProfileOwner(int userHandle); diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index c2fe3a2..cfe4712 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -99,6 +99,12 @@ public class ActivityInfo extends ComponentInfo public int documentLaunchMode; /** + * The maximum number of tasks rooted at this activity that can be in the recent task list. + * Refer to {@link android.R.attr#maxRecents}. + */ + public int maxRecents; + + /** * Optional name of a permission required to be able to access this * Activity. From the "permission" attribute. */ diff --git a/core/java/android/content/pm/ContainerEncryptionParams.java b/core/java/android/content/pm/ContainerEncryptionParams.java index dd1332b..ab3aa27 100644 --- a/core/java/android/content/pm/ContainerEncryptionParams.java +++ b/core/java/android/content/pm/ContainerEncryptionParams.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.PrivateApi; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; @@ -35,7 +35,7 @@ import javax.crypto.spec.IvParameterSpec; * @deprecated encrypted containers are legacy. * @hide */ -@PrivateApi +@SystemApi @Deprecated public class ContainerEncryptionParams implements Parcelable { protected static final String TAG = "ContainerEncryptionParams"; diff --git a/core/java/android/content/pm/ManifestDigest.java b/core/java/android/content/pm/ManifestDigest.java index 943534f..1fbef7a 100644 --- a/core/java/android/content/pm/ManifestDigest.java +++ b/core/java/android/content/pm/ManifestDigest.java @@ -16,7 +16,7 @@ package android.content.pm; -import android.annotation.PrivateApi; +import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; import android.util.Slog; @@ -37,7 +37,7 @@ import libcore.io.IoUtils; * * @hide */ -@PrivateApi +@SystemApi public class ManifestDigest implements Parcelable { private static final String TAG = "ManifestDigest"; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index a34a1b6..550c1f1 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -17,7 +17,7 @@ package android.content.pm; import android.annotation.IntDef; -import android.annotation.PrivateApi; +import android.annotation.SystemApi; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.PackageInstallObserver; @@ -370,7 +370,7 @@ public abstract class PackageManager { * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_SUCCEEDED = 1; /** @@ -379,7 +379,7 @@ public abstract class PackageManager { * already installed. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_ALREADY_EXISTS = -1; /** @@ -388,7 +388,7 @@ public abstract class PackageManager { * file is invalid. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_INVALID_APK = -2; /** @@ -397,7 +397,7 @@ public abstract class PackageManager { * is invalid. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_INVALID_URI = -3; /** @@ -406,7 +406,7 @@ public abstract class PackageManager { * service found that the device didn't have enough storage space to install the app. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4; /** @@ -415,7 +415,7 @@ public abstract class PackageManager { * package is already installed with the same name. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5; /** @@ -424,7 +424,7 @@ public abstract class PackageManager { * the requested shared user does not exist. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_NO_SHARED_USER = -6; /** @@ -434,7 +434,7 @@ public abstract class PackageManager { * than the new package (and the old package's data was not removed). * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7; /** @@ -444,7 +444,7 @@ public abstract class PackageManager { * device and does not have matching signature. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; /** @@ -453,7 +453,7 @@ public abstract class PackageManager { * the new package uses a shared library that is not available. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9; /** @@ -462,7 +462,7 @@ public abstract class PackageManager { * the new package uses a shared library that is not available. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; /** @@ -472,7 +472,7 @@ public abstract class PackageManager { * either because there was not enough storage or the validation failed. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_DEXOPT = -11; /** @@ -482,7 +482,7 @@ public abstract class PackageManager { * that required by the package. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_OLDER_SDK = -12; /** @@ -492,7 +492,7 @@ public abstract class PackageManager { * same authority as a provider already installed in the system. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_CONFLICTING_PROVIDER = -13; /** @@ -502,7 +502,7 @@ public abstract class PackageManager { * that required by the package. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_NEWER_SDK = -14; /** @@ -513,7 +513,7 @@ public abstract class PackageManager { * flag. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_TEST_ONLY = -15; /** @@ -523,7 +523,7 @@ public abstract class PackageManager { * compatible with the device's CPU_ABI. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16; /** @@ -532,7 +532,7 @@ public abstract class PackageManager { * the new package uses a feature that is not available. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_MISSING_FEATURE = -17; // ------ Errors related to sdcard @@ -542,7 +542,7 @@ public abstract class PackageManager { * a secure container mount point couldn't be accessed on external media. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_CONTAINER_ERROR = -18; /** @@ -552,7 +552,7 @@ public abstract class PackageManager { * location. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19; /** @@ -562,7 +562,7 @@ public abstract class PackageManager { * location because the media is not available. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20; /** @@ -571,7 +571,7 @@ public abstract class PackageManager { * the new package couldn't be installed because the verification timed out. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_VERIFICATION_TIMEOUT = -21; /** @@ -580,7 +580,7 @@ public abstract class PackageManager { * the new package couldn't be installed because the verification did not succeed. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_VERIFICATION_FAILURE = -22; /** @@ -589,7 +589,7 @@ public abstract class PackageManager { * the package changed from what the calling program expected. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23; /** @@ -615,7 +615,7 @@ public abstract class PackageManager { * '.apk' extension. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_NOT_APK = -100; /** @@ -624,7 +624,7 @@ public abstract class PackageManager { * if the parser was unable to retrieve the AndroidManifest.xml file. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101; /** @@ -633,7 +633,7 @@ public abstract class PackageManager { * if the parser encountered an unexpected exception. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; /** @@ -642,7 +642,7 @@ public abstract class PackageManager { * if the parser did not find any certificates in the .apk. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; /** @@ -651,7 +651,7 @@ public abstract class PackageManager { * if the parser found inconsistent certificates on the files in the .apk. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104; /** @@ -661,7 +661,7 @@ public abstract class PackageManager { * files in the .apk. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105; /** @@ -670,7 +670,7 @@ public abstract class PackageManager { * if the parser encountered a bad or missing package name in the manifest. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106; /** @@ -679,7 +679,7 @@ public abstract class PackageManager { * if the parser encountered a bad shared user id name in the manifest. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107; /** @@ -688,7 +688,7 @@ public abstract class PackageManager { * if the parser encountered some structural problem in the manifest. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108; /** @@ -698,7 +698,7 @@ public abstract class PackageManager { * in the manifest. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109; /** @@ -707,7 +707,7 @@ public abstract class PackageManager { * if the system failed to install the package because of system issues. * @hide */ - @PrivateApi + @SystemApi public static final int INSTALL_FAILED_INTERNAL_ERROR = -110; /** @@ -2907,7 +2907,7 @@ public abstract class PackageManager { * instead. This method will continue to be supported but the older observer interface * will not get additional failure details. */ - // @PrivateApi + // @SystemApi public abstract void installPackage( Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName); @@ -2942,7 +2942,7 @@ public abstract class PackageManager { * continue to be supported but the older observer interface will not get additional failure * details. */ - // @PrivateApi + // @SystemApi public abstract void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest, @@ -3071,7 +3071,7 @@ public abstract class PackageManager { * on the system for other users, also install it for the calling user. * @hide */ - // @PrivateApi + // @SystemApi public abstract int installExistingPackage(String packageName) throws NameNotFoundException; @@ -3161,7 +3161,7 @@ public abstract class PackageManager { * * @hide */ - // @PrivateApi + // @SystemApi public abstract void deletePackage( String packageName, IPackageDeleteObserver observer, int flags); @@ -3230,7 +3230,7 @@ public abstract class PackageManager { * * @hide */ - // @PrivateApi + // @SystemApi public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer); /** diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ab8bf61..4cac7fd 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -2511,6 +2511,9 @@ public class PackageParser { a.info.documentLaunchMode = sa.getInt( com.android.internal.R.styleable.AndroidManifestActivity_documentLaunchMode, ActivityInfo.DOCUMENT_LAUNCH_NONE); + a.info.maxRecents = sa.getInt( + com.android.internal.R.styleable.AndroidManifestActivity_maxRecents, + 15); a.info.screenOrientation = sa.getInt( com.android.internal.R.styleable.AndroidManifestActivity_screenOrientation, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index b96f166..27402668 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -22,6 +22,7 @@ import android.annotation.SdkConstant.SdkConstantType; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.net.NetworkUtils; import android.os.Binder; import android.os.Build.VERSION_CODES; import android.os.Handler; @@ -892,6 +893,7 @@ public class ConnectivityManager { case NetworkCapabilities.NET_CAPABILITY_IMS: case NetworkCapabilities.NET_CAPABILITY_RCS: case NetworkCapabilities.NET_CAPABILITY_XCAP: + case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default continue; default: // At least one capability usually provided by unrestricted @@ -981,13 +983,13 @@ public class ConnectivityManager { public void onAvailable(NetworkRequest request, Network network) { currentNetwork = network; Log.d(TAG, "startUsingNetworkFeature got Network:" + network); - network.bindProcessForHostResolution(); + setProcessDefaultNetworkForHostResolution(network); } @Override public void onLost(NetworkRequest request, Network network) { if (network.equals(currentNetwork)) { currentNetwork = null; - network.unbindProcessForHostResolution(); + setProcessDefaultNetworkForHostResolution(null); } Log.d(TAG, "startUsingNetworkFeature lost Network:" + network); } @@ -1071,7 +1073,7 @@ public class ConnectivityManager { * @return {@code true} on success, {@code false} on failure * * @deprecated Deprecated in favor of the {@link #requestNetwork}, - * {@link Network#bindProcess} and {@link Network#socketFactory} api. + * {@link #setProcessDefaultNetwork} and {@link Network#getSocketFactory} api. */ public boolean requestRouteToHost(int networkType, int hostAddress) { InetAddress inetAddress = NetworkUtils.intToInetAddress(hostAddress); @@ -1095,7 +1097,7 @@ public class ConnectivityManager { * @return {@code true} on success, {@code false} on failure * @hide * @deprecated Deprecated in favor of the {@link #requestNetwork} and - * {@link Network#bindProcess} api. + * {@link #setProcessDefaultNetwork} api. */ public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { byte[] address = hostAddress.getAddress(); @@ -2347,4 +2349,64 @@ public class ConnectivityManager { mService.releaseNetworkRequest(networkRequest); } catch (RemoteException e) {} } + + /** + * Binds the current process to {@code network}. All Sockets created in the future + * (and not explicitly bound via a bound SocketFactory from + * {@link Network#getSocketFactory() Network.getSocketFactory()}) will be bound to + * {@code network}. All host name resolutions will be limited to {@code network} as well. + * Note that if {@code network} ever disconnects, all Sockets created in this way will cease to + * work and all host name resolutions will fail. This is by design so an application doesn't + * accidentally use Sockets it thinks are still bound to a particular {@link Network}. + * To clear binding pass {@code null} for {@code network}. Using individually bound + * Sockets created by Network.getSocketFactory().createSocket() and + * performing network-specific host name resolutions via + * {@link Network#getAllByName Network.getAllByName} is preferred to calling + * {@code setProcessDefaultNetwork}. + * + * @param network The {@link Network} to bind the current process to, or {@code null} to clear + * the current binding. + * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. + */ + public static boolean setProcessDefaultNetwork(Network network) { + if (network == null) { + NetworkUtils.unbindProcessToNetwork(); + } else { + NetworkUtils.bindProcessToNetwork(network.netId); + } + // TODO fix return value + return true; + } + + /** + * Returns the {@link Network} currently bound to this process via + * {@link #setProcessDefaultNetwork}, or {@code null} if no {@link Network} is explicitly bound. + * + * @return {@code Network} to which this process is bound, or {@code null}. + */ + public static Network getProcessDefaultNetwork() { + int netId = NetworkUtils.getNetworkBoundToProcess(); + if (netId == 0) return null; + return new Network(netId); + } + + /** + * Binds host resolutions performed by this process to {@code network}. + * {@link #setProcessDefaultNetwork} takes precedence over this setting. + * + * @param network The {@link Network} to bind host resolutions from the current process to, or + * {@code null} to clear the current binding. + * @return {@code true} on success, {@code false} if the {@link Network} is no longer valid. + * @hide + * @deprecated This is strictly for legacy usage to support {@link #startUsingNetworkFeature}. + */ + public static boolean setProcessDefaultNetworkForHostResolution(Network network) { + if (network == null) { + NetworkUtils.unbindProcessToNetworkForHostResolution(); + } else { + NetworkUtils.bindProcessToNetworkForHostResolution(network.netId); + } + // TODO hook up the return value. + return true; + } } diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java index 22b26b1..49a307e 100644 --- a/core/java/android/net/DhcpResults.java +++ b/core/java/android/net/DhcpResults.java @@ -74,8 +74,10 @@ public class DhcpResults implements Parcelable { if (linkProperties.getRoutes().size() == 0) { for (RouteInfo r : orig.linkProperties.getRoutes()) linkProperties.addRoute(r); } - if (linkProperties.getDnses().size() == 0) { - for (InetAddress d : orig.linkProperties.getDnses()) linkProperties.addDns(d); + if (linkProperties.getDnsServers().size() == 0) { + for (InetAddress d : orig.linkProperties.getDnsServers()) { + linkProperties.addDnsServer(d); + } } } @@ -211,7 +213,7 @@ public class DhcpResults implements Parcelable { public boolean addDns(String addrString) { if (TextUtils.isEmpty(addrString) == false) { try { - linkProperties.addDns(NetworkUtils.numericToInetAddress(addrString)); + linkProperties.addDnsServer(NetworkUtils.numericToInetAddress(addrString)); } catch (IllegalArgumentException e) { Log.e(TAG, "addDns failed with addrString " + addrString); return true; diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java index 66f0fd0..7acf3f5 100644 --- a/core/java/android/net/DnsPinger.java +++ b/core/java/android/net/DnsPinger.java @@ -248,7 +248,7 @@ public final class DnsPinger extends Handler { return mDefaultDns; } - Collection<InetAddress> dnses = curLinkProps.getDnses(); + Collection<InetAddress> dnses = curLinkProps.getDnsServers(); if (dnses == null || dnses.size() == 0) { loge("getDns::LinkProps has null dns - returning default"); return mDefaultDns; diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 3c36679..cff9025 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Hashtable; +import java.util.List; /** * Describes the properties of a network link. @@ -58,10 +59,12 @@ public class LinkProperties implements Parcelable { private Hashtable<String, LinkProperties> mStackedLinks = new Hashtable<String, LinkProperties>(); - // @hide + /** + * @hide + */ public static class CompareResult<T> { - public Collection<T> removed = new ArrayList<T>(); - public Collection<T> added = new ArrayList<T>(); + public List<T> removed = new ArrayList<T>(); + public List<T> added = new ArrayList<T>(); @Override public String toString() { @@ -81,7 +84,7 @@ public class LinkProperties implements Parcelable { if (source != null) { mIfaceName = source.getInterfaceName(); for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l); - for (InetAddress i : source.getDnses()) mDnses.add(i); + for (InetAddress i : source.getDnsServers()) mDnses.add(i); mDomains = source.getDomains(); for (RouteInfo r : source.getRoutes()) mRoutes.add(r); mHttpProxy = (source.getHttpProxy() == null) ? @@ -98,6 +101,7 @@ public class LinkProperties implements Parcelable { * will have their interface changed to match this new value. * * @param iface The name of the network interface used for this link. + * @hide */ public void setInterfaceName(String iface) { mIfaceName = iface; @@ -117,9 +121,11 @@ public class LinkProperties implements Parcelable { return mIfaceName; } - // @hide - public Collection<String> getAllInterfaceNames() { - Collection interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1); + /** + * @hide + */ + public List<String> getAllInterfaceNames() { + List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1); if (mIfaceName != null) interfaceNames.add(new String(mIfaceName)); for (LinkProperties stacked: mStackedLinks.values()) { interfaceNames.addAll(stacked.getAllInterfaceNames()); @@ -134,23 +140,23 @@ public class LinkProperties implements Parcelable { * prefix lengths for each address. This is a simplified utility alternative to * {@link LinkProperties#getLinkAddresses}. * - * @return An umodifiable {@link Collection} of {@link InetAddress} for this link. + * @return An umodifiable {@link List} of {@link InetAddress} for this link. * @hide */ - public Collection<InetAddress> getAddresses() { - Collection<InetAddress> addresses = new ArrayList<InetAddress>(); + public List<InetAddress> getAddresses() { + List<InetAddress> addresses = new ArrayList<InetAddress>(); for (LinkAddress linkAddress : mLinkAddresses) { addresses.add(linkAddress.getAddress()); } - return Collections.unmodifiableCollection(addresses); + return Collections.unmodifiableList(addresses); } /** * Returns all the addresses on this link and all the links stacked above it. * @hide */ - public Collection<InetAddress> getAllAddresses() { - Collection<InetAddress> addresses = new ArrayList<InetAddress>(); + public List<InetAddress> getAllAddresses() { + List<InetAddress> addresses = new ArrayList<InetAddress>(); for (LinkAddress linkAddress : mLinkAddresses) { addresses.add(linkAddress.getAddress()); } @@ -174,6 +180,7 @@ public class LinkProperties implements Parcelable { * same address/prefix does not already exist. If it does exist it is replaced. * @param address The {@code LinkAddress} to add. * @return true if {@code address} was added or updated, false otherwise. + * @hide */ public boolean addLinkAddress(LinkAddress address) { if (address == null) { @@ -200,6 +207,7 @@ public class LinkProperties implements Parcelable { * * @param toRemove A {@link LinkAddress} specifying the address to remove. * @return true if the address was removed, false if it did not exist. + * @hide */ public boolean removeLinkAddress(LinkAddress toRemove) { int i = findLinkAddressIndex(toRemove); @@ -214,18 +222,18 @@ public class LinkProperties implements Parcelable { * Returns all the {@link LinkAddress} on this link. Typically a link will have * one IPv4 address and one or more IPv6 addresses. * - * @return An unmodifiable {@link Collection} of {@link LinkAddress} for this link. + * @return An unmodifiable {@link List} of {@link LinkAddress} for this link. */ - public Collection<LinkAddress> getLinkAddresses() { - return Collections.unmodifiableCollection(mLinkAddresses); + public List<LinkAddress> getLinkAddresses() { + return Collections.unmodifiableList(mLinkAddresses); } /** * Returns all the addresses on this link and all the links stacked above it. * @hide */ - public Collection<LinkAddress> getAllLinkAddresses() { - Collection<LinkAddress> addresses = new ArrayList<LinkAddress>(); + public List<LinkAddress> getAllLinkAddresses() { + List<LinkAddress> addresses = new ArrayList<LinkAddress>(); addresses.addAll(mLinkAddresses); for (LinkProperties stacked: mStackedLinks.values()) { addresses.addAll(stacked.getAllLinkAddresses()); @@ -239,6 +247,7 @@ public class LinkProperties implements Parcelable { * * @param addresses The {@link Collection} of {@link LinkAddress} to set in this * object. + * @hide */ public void setLinkAddresses(Collection<LinkAddress> addresses) { mLinkAddresses.clear(); @@ -250,20 +259,21 @@ public class LinkProperties implements Parcelable { /** * Adds the given {@link InetAddress} to the list of DNS servers. * - * @param dns The {@link InetAddress} to add to the list of DNS servers. + * @param dnsServer The {@link InetAddress} to add to the list of DNS servers. + * @hide */ - public void addDns(InetAddress dns) { - if (dns != null) mDnses.add(dns); + public void addDnsServer(InetAddress dnsServer) { + if (dnsServer != null) mDnses.add(dnsServer); } /** * Returns all the {@link LinkAddress} for DNS servers on this link. * - * @return An umodifiable {@link Collection} of {@link InetAddress} for DNS servers on + * @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on * this link. */ - public Collection<InetAddress> getDnses() { - return Collections.unmodifiableCollection(mDnses); + public List<InetAddress> getDnsServers() { + return Collections.unmodifiableList(mDnses); } /** @@ -271,6 +281,7 @@ public class LinkProperties implements Parcelable { * * @param domains A {@link String} listing in priority order the comma separated * domains to search when resolving host names on this link. + * @hide */ public void setDomains(String domains) { mDomains = domains; @@ -323,6 +334,7 @@ public class LinkProperties implements Parcelable { * proper course is to add either un-named or properly named {@link RouteInfo}. * * @param route A {@link RouteInfo} to add to this object. + * @hide */ public void addRoute(RouteInfo route) { if (route != null) { @@ -339,18 +351,18 @@ public class LinkProperties implements Parcelable { /** * Returns all the {@link RouteInfo} set on this link. * - * @return An unmodifiable {@link Collection} of {@link RouteInfo} for this link. + * @return An unmodifiable {@link List} of {@link RouteInfo} for this link. */ - public Collection<RouteInfo> getRoutes() { - return Collections.unmodifiableCollection(mRoutes); + public List<RouteInfo> getRoutes() { + return Collections.unmodifiableList(mRoutes); } /** * Returns all the routes on this link and all the links stacked above it. * @hide */ - public Collection<RouteInfo> getAllRoutes() { - Collection<RouteInfo> routes = new ArrayList(); + public List<RouteInfo> getAllRoutes() { + List<RouteInfo> routes = new ArrayList(); routes.addAll(mRoutes); for (LinkProperties stacked: mStackedLinks.values()) { routes.addAll(stacked.getAllRoutes()); @@ -364,6 +376,7 @@ public class LinkProperties implements Parcelable { * not enforce it and applications may ignore them. * * @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link. + * @hide */ public void setHttpProxy(ProxyInfo proxy) { mHttpProxy = proxy; @@ -419,16 +432,17 @@ public class LinkProperties implements Parcelable { * Returns all the links stacked on top of this link. * @hide */ - public Collection<LinkProperties> getStackedLinks() { - Collection<LinkProperties> stacked = new ArrayList<LinkProperties>(); + public List<LinkProperties> getStackedLinks() { + List<LinkProperties> stacked = new ArrayList<LinkProperties>(); for (LinkProperties link : mStackedLinks.values()) { stacked.add(new LinkProperties(link)); } - return Collections.unmodifiableCollection(stacked); + return Collections.unmodifiableList(stacked); } /** * Clears this object to its initial state. + * @hide */ public void clear() { mIfaceName = null; @@ -486,6 +500,7 @@ public class LinkProperties implements Parcelable { * Returns true if this link has an IPv4 address. * * @return {@code true} if there is an IPv4 address, {@code false} otherwise. + * @hide */ public boolean hasIPv4Address() { for (LinkAddress address : mLinkAddresses) { @@ -500,6 +515,7 @@ public class LinkProperties implements Parcelable { * Returns true if this link has an IPv6 address. * * @return {@code true} if there is an IPv6 address, {@code false} otherwise. + * @hide */ public boolean hasIPv6Address() { for (LinkAddress address : mLinkAddresses) { @@ -543,7 +559,7 @@ public class LinkProperties implements Parcelable { * @hide */ public boolean isIdenticalDnses(LinkProperties target) { - Collection<InetAddress> targetDnses = target.getDnses(); + Collection<InetAddress> targetDnses = target.getDnsServers(); String targetDomains = target.getDomains(); if (mDomains == null) { if (targetDomains != null) return false; @@ -696,7 +712,7 @@ public class LinkProperties implements Parcelable { result.removed = new ArrayList<InetAddress>(mDnses); result.added.clear(); if (target != null) { - for (InetAddress newAddress : target.getDnses()) { + for (InetAddress newAddress : target.getDnsServers()) { if (! result.removed.remove(newAddress)) { result.added.add(newAddress); } @@ -831,7 +847,7 @@ public class LinkProperties implements Parcelable { addressCount = in.readInt(); for (int i=0; i<addressCount; i++) { try { - netProp.addDns(InetAddress.getByAddress(in.createByteArray())); + netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray())); } catch (UnknownHostException e) { } } netProp.setDomains(in.readString()); diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 64516e6..d933f26 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -32,7 +32,8 @@ import javax.net.SocketFactory; * {@link ConnectivityManager.NetworkCallbackListener} in response to * {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}. * It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis - * through a targeted {@link SocketFactory} or process-wide via {@link #bindProcess}. + * through a targeted {@link SocketFactory} or process-wide via + * {@link ConnectivityManager#setProcessDefaultNetwork}. */ public class Network implements Parcelable { @@ -160,63 +161,13 @@ public class Network implements Parcelable { * @return a {@link SocketFactory} which produces {@link Socket} instances bound to this * {@code Network}. */ - public SocketFactory socketFactory() { + public SocketFactory getSocketFactory() { if (mNetworkBoundSocketFactory == null) { mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId); } return mNetworkBoundSocketFactory; } - /** - * Binds the current process to this network. All sockets created in the future (and not - * explicitly bound via a bound {@link SocketFactory} (see {@link Network#socketFactory}) - * will be bound to this network. Note that if this {@code Network} ever disconnects - * all sockets created in this way will cease to work. This is by design so an application - * doesn't accidentally use sockets it thinks are still bound to a particular {@code Network}. - */ - public void bindProcess() { - NetworkUtils.bindProcessToNetwork(netId); - } - - /** - * Binds host resolutions performed by this process to this network. {@link #bindProcess} - * takes precedence over this setting. - * - * @hide - * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature(). - */ - public void bindProcessForHostResolution() { - NetworkUtils.bindProcessToNetworkForHostResolution(netId); - } - - /** - * Clears any process specific {@link Network} binding for host resolution. This does - * not clear bindings enacted via {@link #bindProcess}. - * - * @hide - * @deprecated This is strictly for legacy usage to support startUsingNetworkFeature(). - */ - public void unbindProcessForHostResolution() { - NetworkUtils.unbindProcessToNetworkForHostResolution(); - } - - /** - * A static utility method to return any {@code Network} currently bound by this process. - * - * @return {@code Network} to which this process is bound. - */ - public static Network getProcessBoundNetwork() { - return new Network(NetworkUtils.getNetworkBoundToProcess()); - } - - /** - * Clear any process specific {@code Network} binding. This reverts a call to - * {@link Network#bindProcess}. - */ - public static void unbindProcess() { - NetworkUtils.unbindProcessToNetwork(); - } - // implement the Parcelable interface public int describeContents() { return 0; diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index edb3286..b02f88e 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -111,7 +111,7 @@ public class NetworkUtils { /** * Binds the current process to the network designated by {@code netId}. All sockets created * in the future (and not explicitly bound via a bound {@link SocketFactory} (see - * {@link Network#socketFactory}) will be bound to this network. Note that if this + * {@link Network#getSocketFactory}) will be bound to this network. Note that if this * {@code Network} ever disconnects all sockets created in this way will cease to work. This * is by design so an application doesn't accidentally use sockets it thinks are still bound to * a particular {@code Network}. diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java index 0340e7e..a578383 100644 --- a/core/java/android/net/ProxyDataTracker.java +++ b/core/java/android/net/ProxyDataTracker.java @@ -108,8 +108,8 @@ public class ProxyDataTracker extends BaseNetworkStateTracker { mNetworkCapabilities = new NetworkCapabilities(); mNetworkInfo.setIsAvailable(true); try { - mLinkProperties.addDns(InetAddress.getByName(DNS1)); - mLinkProperties.addDns(InetAddress.getByName(DNS2)); + mLinkProperties.addDnsServer(InetAddress.getByName(DNS1)); + mLinkProperties.addDnsServer(InetAddress.getByName(DNS2)); mLinkProperties.setInterfaceName(INTERFACE_NAME); } catch (UnknownHostException e) { Log.e(TAG, "Could not add DNS address", e); diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index 32050dc..537e993 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -128,29 +128,97 @@ public class BatteryManager { public static final int BATTERY_PLUGGED_ANY = BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS; + /* + * Battery property identifiers. These must match the values in + * frameworks/native/include/batteryservice/BatteryService.h + */ + /** Battery capacity in microampere-hours, as an integer. */ + public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; + + /** + * Instantaneous battery current in microamperes, as an integer. Positive + * values indicate net current entering the battery from a charge source, + * negative values indicate net current discharging from the battery. + */ + public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; + + /** + * Average battery current in microamperes, as an integer. Positive + * values indicate net current entering the battery from a charge source, + * negative values indicate net current discharging from the battery. + * The time period over which the average is computed may depend on the + * fuel gauge hardware and its configuration. + */ + public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; + + /** + * Remaining battery capacity as an integer percentage of total capacity + * (with no fractional part). + */ + public static final int BATTERY_PROPERTY_CAPACITY = 4; + + /** + * Battery remaining energy in nanowatt-hours, as a long integer. + */ + public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; + private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar; /** - * Return the requested battery property. + * Query a battery property from the batteryproperties service. * - * @param id identifier from {@link BatteryProperty} of the requested property - * @return a {@link BatteryProperty} object that returns the property value, or null on error + * Returns the requested value, or Long.MIN_VALUE if property not + * supported on this system or on other error. */ - public BatteryProperty getProperty(int id) throws RemoteException { + private long queryProperty(int id) { + long ret; + if (mBatteryPropertiesRegistrar == null) { IBinder b = ServiceManager.getService("batteryproperties"); mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b); if (mBatteryPropertiesRegistrar == null) - return null; + return Long.MIN_VALUE; } - BatteryProperty prop = new BatteryProperty(); - if ((mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) && - (prop.getLong() != Long.MIN_VALUE)) - return prop; - else - return null; + try { + BatteryProperty prop = new BatteryProperty(); + + if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0) + ret = prop.getLong(); + else + ret = Long.MIN_VALUE; + } catch (RemoteException e) { + ret = Long.MIN_VALUE; + } + + return ret; + } + + /** + * Return the value of a battery property of integer type. If the + * platform does not provide the property queried, this value will + * be Integer.MIN_VALUE. + * + * @param id identifier of the requested property + * + * @return the property value, or Integer.MIN_VALUE if not supported. + */ + public int getIntProperty(int id) { + return (int)queryProperty(id); + } + + /** + * Return the value of a battery property of long type If the + * platform does not provide the property queried, this value will + * be Long.MIN_VALUE. + * + * @param id identifier of the requested property + * + * @return the property value, or Long.MIN_VALUE if not supported. + */ + public long getLongProperty(int id) { + return queryProperty(id); } } diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java index 27dad4f..84119bd 100644 --- a/core/java/android/os/BatteryProperty.java +++ b/core/java/android/os/BatteryProperty.java @@ -20,44 +20,13 @@ import android.os.Parcelable; /** * Battery properties that may be queried using - * {@link BatteryManager#getProperty * BatteryManager.getProperty()} */ -public class BatteryProperty implements Parcelable { - /* - * Battery property identifiers. These must match the values in - * frameworks/native/include/batteryservice/BatteryService.h - */ - /** Battery capacity in microampere-hours, as an integer. */ - public static final int CHARGE_COUNTER = 1; - - /** - * Instantaneous battery current in microamperes, as an integer. Positive - * values indicate net current entering the battery from a charge source, - * negative values indicate net current discharging from the battery. - */ - public static final int CURRENT_NOW = 2; - - /** - * Average battery current in microamperes, as an integer. Positive - * values indicate net current entering the battery from a charge source, - * negative values indicate net current discharging from the battery. - * The time period over which the average is computed may depend on the - * fuel gauge hardware and its configuration. - */ - public static final int CURRENT_AVERAGE = 3; - - /** - * Remaining battery capacity as an integer percentage of total capacity - * (with no fractional part). - */ - public static final int CAPACITY = 4; - - /** - * Battery remaining energy in nanowatt-hours, as a long integer. - */ - public static final int ENERGY_COUNTER = 5; +/** + * @hide + */ +public class BatteryProperty implements Parcelable { private long mValueLong; /** @@ -68,30 +37,12 @@ public class BatteryProperty implements Parcelable { } /** - * Return the value of a property of integer type previously queried - * via {@link BatteryManager#getProperty - * BatteryManager.getProperty()}. If the platform does - * not provide the property queried, this value will be - * Integer.MIN_VALUE. - * - * @return The queried property value, or Integer.MIN_VALUE if not supported. - */ - public int getInt() { - return (int)mValueLong; - } - - /** - * Return the value of a property of long type previously queried - * via {@link BatteryManager#getProperty - * BatteryManager.getProperty()}. If the platform does - * not provide the property queried, this value will be - * Long.MIN_VALUE. - * - * @return The queried property value, or Long.MIN_VALUE if not supported. + * @hide */ public long getLong() { return mValueLong; } + /* * Parcel read/write code must be kept in sync with * frameworks/native/services/batteryservice/BatteryProperty.cpp diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 61194e9..658180b 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -41,6 +41,7 @@ interface IPowerManager void goToSleep(long time, int reason, int flags); void nap(long time); boolean isInteractive(); + boolean isPowerSaveMode(); void reboot(boolean confirm, String reason, boolean wait); void shutdown(boolean confirm, boolean wait); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index d5177e8..92e80a5 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -16,6 +16,7 @@ package android.os; +import android.annotation.SdkConstant; import android.content.Context; import android.util.Log; @@ -685,6 +686,30 @@ public final class PowerManager { } /** + * Returns true if the device is currently in power save mode. When in this mode, + * applications should reduce their functionality in order to conserve battery as + * much as possible. You can monitor for changes to this state with + * {@link #ACTION_POWER_SAVE_MODE_CHANGED}. + * + * @return Returns true if currently in low power mode, else false. + */ + public boolean isPowerSaveMode() { + try { + return mService.isPowerSaveMode(); + } catch (RemoteException e) { + return false; + } + } + + /** + * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. + * This broadcast is only sent to registered receivers. + */ + @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_POWER_SAVE_MODE_CHANGED + = "android.os.action.POWER_SAVE_MODE_CHANGED"; + + /** * A wake lock is a mechanism to indicate that your application needs * to have the device stay on. * <p> diff --git a/core/java/android/print/ILayoutResultCallback.aidl b/core/java/android/print/ILayoutResultCallback.aidl index 43b8c30..68c1dac 100644 --- a/core/java/android/print/ILayoutResultCallback.aidl +++ b/core/java/android/print/ILayoutResultCallback.aidl @@ -16,6 +16,7 @@ package android.print; +import android.os.ICancellationSignal; import android.print.PrintDocumentInfo; /** @@ -24,6 +25,8 @@ import android.print.PrintDocumentInfo; * @hide */ oneway interface ILayoutResultCallback { + void onLayoutStarted(ICancellationSignal cancellation, int sequence); void onLayoutFinished(in PrintDocumentInfo info, boolean changed, int sequence); void onLayoutFailed(CharSequence error, int sequence); + void onLayoutCanceled(int sequence); } diff --git a/core/java/android/print/IPrintDocumentAdapter.aidl b/core/java/android/print/IPrintDocumentAdapter.aidl index 2b95c12..9d384fb 100644 --- a/core/java/android/print/IPrintDocumentAdapter.aidl +++ b/core/java/android/print/IPrintDocumentAdapter.aidl @@ -37,5 +37,4 @@ oneway interface IPrintDocumentAdapter { void write(in PageRange[] pages, in ParcelFileDescriptor fd, IWriteResultCallback callback, int sequence); void finish(); - void cancel(); } diff --git a/core/java/android/print/IWriteResultCallback.aidl b/core/java/android/print/IWriteResultCallback.aidl index 8281c4e..8fb33e1 100644 --- a/core/java/android/print/IWriteResultCallback.aidl +++ b/core/java/android/print/IWriteResultCallback.aidl @@ -16,6 +16,7 @@ package android.print; +import android.os.ICancellationSignal; import android.print.PageRange; /** @@ -24,6 +25,8 @@ import android.print.PageRange; * @hide */ oneway interface IWriteResultCallback { + void onWriteStarted(ICancellationSignal cancellation, int sequence); void onWriteFinished(in PageRange[] pages, int sequence); void onWriteFailed(CharSequence error, int sequence); + void onWriteCanceled(int sequence); } diff --git a/core/java/android/print/PrintAttributes.java b/core/java/android/print/PrintAttributes.java index c6254e0..2810d55 100644 --- a/core/java/android/print/PrintAttributes.java +++ b/core/java/android/print/PrintAttributes.java @@ -151,6 +151,105 @@ public final class PrintAttributes implements Parcelable { mColorMode = colorMode; } + /** + * Gets whether this print attributes are in portrait orientation, + * which is the media size is in portrait and all orientation dependent + * attributes such as resolution and margins are properly adjusted. + * + * @return Whether this print attributes are in portrait. + * + * @hide + */ + public boolean isPortrait() { + return mMediaSize.isPortrait(); + } + + /** + * Gets a new print attributes instance which is in portrait orientation, + * which is the media size is in portrait and all orientation dependent + * attributes such as resolution and margins are properly adjusted. + * + * @return New instance in portrait orientation if this one is in + * landscape, otherwise this instance. + * + * @hide + */ + public PrintAttributes asPortrait() { + if (isPortrait()) { + return this; + } + + PrintAttributes attributes = new PrintAttributes(); + + // Rotate the media size. + attributes.setMediaSize(getMediaSize().asPortrait()); + + // Rotate the resolution. + Resolution oldResolution = getResolution(); + Resolution newResolution = new Resolution( + oldResolution.getId(), + oldResolution.getLabel(), + oldResolution.getVerticalDpi(), + oldResolution.getHorizontalDpi()); + attributes.setResolution(newResolution); + + // Rotate the physical margins. + Margins oldMinMargins = getMinMargins(); + Margins newMinMargins = new Margins( + oldMinMargins.getBottomMils(), + oldMinMargins.getLeftMils(), + oldMinMargins.getTopMils(), + oldMinMargins.getRightMils()); + attributes.setMinMargins(newMinMargins); + + attributes.setColorMode(getColorMode()); + + return attributes; + } + + /** + * Gets a new print attributes instance which is in landscape orientation, + * which is the media size is in landscape and all orientation dependent + * attributes such as resolution and margins are properly adjusted. + * + * @return New instance in landscape orientation if this one is in + * portrait, otherwise this instance. + * + * @hide + */ + public PrintAttributes asLandscape() { + if (!isPortrait()) { + return this; + } + + PrintAttributes attributes = new PrintAttributes(); + + // Rotate the media size. + attributes.setMediaSize(getMediaSize().asLandscape()); + + // Rotate the resolution. + Resolution oldResolution = getResolution(); + Resolution newResolution = new Resolution( + oldResolution.getId(), + oldResolution.getLabel(), + oldResolution.getVerticalDpi(), + oldResolution.getHorizontalDpi()); + attributes.setResolution(newResolution); + + // Rotate the physical margins. + Margins oldMinMargins = getMinMargins(); + Margins newMargins = new Margins( + oldMinMargins.getTopMils(), + oldMinMargins.getRightMils(), + oldMinMargins.getBottomMils(), + oldMinMargins.getLeftMils()); + attributes.setMinMargins(newMargins); + + attributes.setColorMode(getColorMode()); + + return attributes; + } + @Override public void writeToParcel(Parcel parcel, int flags) { if (mMediaSize != null) { diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java index 811751d..9361286 100644 --- a/core/java/android/print/PrintManager.java +++ b/core/java/android/print/PrintManager.java @@ -24,6 +24,7 @@ import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; +import android.os.ICancellationSignal; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; @@ -41,6 +42,7 @@ import libcore.io.IoUtils; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -50,12 +52,12 @@ import java.util.Map; * <p> * To obtain a handle to the print manager do the following: * </p> - * + * * <pre> * PrintManager printManager = * (PrintManager) context.getSystemService(Context.PRINT_SERVICE); * </pre> - * + * * <h3>Print mechanics</h3> * <p> * The key idea behind printing on the platform is that the content to be printed @@ -344,7 +346,7 @@ public final class PrintManager { try { mService.cancelPrintJob(printJobId, mAppId, mUserId); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error cancleing a print job: " + printJobId, re); + Log.e(LOG_TAG, "Error canceling a print job: " + printJobId, re); } } @@ -505,30 +507,17 @@ public final class PrintManager { private static final class PrintDocumentAdapterDelegate extends IPrintDocumentAdapter.Stub implements ActivityLifecycleCallbacks { - private final Object mLock = new Object(); - private CancellationSignal mLayoutOrWriteCancellation; - - private Activity mActivity; // Strong reference OK - cleared in finish() - - private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in finish + private Activity mActivity; // Strong reference OK - cleared in destroy - private Handler mHandler; // Strong reference OK - cleared in finish() + private PrintDocumentAdapter mDocumentAdapter; // Strong reference OK - cleared in destroy - private IPrintDocumentAdapterObserver mObserver; // Strong reference OK - cleared in finish + private Handler mHandler; // Strong reference OK - cleared in destroy - private LayoutSpec mLastLayoutSpec; + private IPrintDocumentAdapterObserver mObserver; // Strong reference OK - cleared in destroy - private WriteSpec mLastWriteSpec; - - private boolean mStartReqeusted; - private boolean mStarted; - - private boolean mFinishRequested; - private boolean mFinished; - - private boolean mDestroyed; + private DestroyableCallback mPendingCallback; public PrintDocumentAdapterDelegate(Activity activity, PrintDocumentAdapter documentAdapter) { @@ -542,11 +531,10 @@ public final class PrintManager { public void setObserver(IPrintDocumentAdapterObserver observer) { final boolean destroyed; synchronized (mLock) { - if (!mDestroyed) { - mObserver = observer; - } - destroyed = mDestroyed; + mObserver = observer; + destroyed = isDestroyedLocked(); } + if (destroyed) { try { observer.onDestroy(); @@ -559,126 +547,89 @@ public final class PrintManager { @Override public void start() { synchronized (mLock) { - // Started called or finish called or destroyed - nothing to do. - if (mStartReqeusted || mFinishRequested || mDestroyed) { - return; + // If destroyed the handler is null. + if (!isDestroyedLocked()) { + mHandler.obtainMessage(MyHandler.MSG_ON_START, + mDocumentAdapter).sendToTarget(); } - - mStartReqeusted = true; - - doPendingWorkLocked(); } } @Override public void layout(PrintAttributes oldAttributes, PrintAttributes newAttributes, ILayoutResultCallback callback, Bundle metadata, int sequence) { - final boolean destroyed; - synchronized (mLock) { - destroyed = mDestroyed; - // If start called and not finished called and not destroyed - do some work. - if (mStartReqeusted && !mFinishRequested && !mDestroyed) { - // Layout cancels write and overrides layout. - if (mLastWriteSpec != null) { - IoUtils.closeQuietly(mLastWriteSpec.fd); - mLastWriteSpec = null; - } - - mLastLayoutSpec = new LayoutSpec(); - mLastLayoutSpec.callback = callback; - mLastLayoutSpec.oldAttributes = oldAttributes; - mLastLayoutSpec.newAttributes = newAttributes; - mLastLayoutSpec.metadata = metadata; - mLastLayoutSpec.sequence = sequence; - - // Cancel the previous cancellable operation.When the - // cancellation completes we will do the pending work. - if (cancelPreviousCancellableOperationLocked()) { - return; - } - doPendingWorkLocked(); - } + ICancellationSignal cancellationTransport = CancellationSignal.createTransport(); + try { + callback.onLayoutStarted(cancellationTransport, sequence); + } catch (RemoteException re) { + // The spooler is dead - can't recover. + Log.e(LOG_TAG, "Error notifying for layout start", re); + return; } - if (destroyed) { - try { - callback.onLayoutFailed(null, sequence); - } catch (RemoteException re) { - Log.i(LOG_TAG, "Error notifying for cancelled layout", re); + + synchronized (mLock) { + // If destroyed the handler is null. + if (isDestroyedLocked()) { + return; } + + CancellationSignal cancellationSignal = CancellationSignal.fromTransport( + cancellationTransport); + + SomeArgs args = SomeArgs.obtain(); + args.arg1 = mDocumentAdapter; + args.arg2 = oldAttributes; + args.arg3 = newAttributes; + args.arg4 = cancellationSignal; + args.arg5 = new MyLayoutResultCallback(callback, sequence); + args.arg6 = metadata; + + mHandler.obtainMessage(MyHandler.MSG_ON_LAYOUT, args).sendToTarget(); } } @Override public void write(PageRange[] pages, ParcelFileDescriptor fd, IWriteResultCallback callback, int sequence) { - final boolean destroyed; - synchronized (mLock) { - destroyed = mDestroyed; - // If start called and not finished called and not destroyed - do some work. - if (mStartReqeusted && !mFinishRequested && !mDestroyed) { - // Write cancels previous writes. - if (mLastWriteSpec != null) { - IoUtils.closeQuietly(mLastWriteSpec.fd); - mLastWriteSpec = null; - } - mLastWriteSpec = new WriteSpec(); - mLastWriteSpec.callback = callback; - mLastWriteSpec.pages = pages; - mLastWriteSpec.fd = fd; - mLastWriteSpec.sequence = sequence; - - // Cancel the previous cancellable operation.When the - // cancellation completes we will do the pending work. - if (cancelPreviousCancellableOperationLocked()) { - return; - } - - doPendingWorkLocked(); - } - } - if (destroyed) { - try { - callback.onWriteFailed(null, sequence); - } catch (RemoteException re) { - Log.i(LOG_TAG, "Error notifying for cancelled write", re); - } + ICancellationSignal cancellationTransport = CancellationSignal.createTransport(); + try { + callback.onWriteStarted(cancellationTransport, sequence); + } catch (RemoteException re) { + // The spooler is dead - can't recover. + Log.e(LOG_TAG, "Error notifying for write start", re); + return; } - } - @Override - public void finish() { synchronized (mLock) { - // Start not called or finish called or destroyed - nothing to do. - if (!mStartReqeusted || mFinishRequested || mDestroyed) { + // If destroyed the handler is null. + if (isDestroyedLocked()) { return; } - mFinishRequested = true; + CancellationSignal cancellationSignal = CancellationSignal.fromTransport( + cancellationTransport); - // When the current write or layout complete we - // will do the pending work. - if (mLastLayoutSpec != null || mLastWriteSpec != null) { - if (DEBUG) { - Log.i(LOG_TAG, "Waiting for current operation"); - } - return; - } + SomeArgs args = SomeArgs.obtain(); + args.arg1 = mDocumentAdapter; + args.arg2 = pages; + args.arg3 = fd; + args.arg4 = cancellationSignal; + args.arg5 = new MyWriteResultCallback(callback, fd, sequence); - doPendingWorkLocked(); + mHandler.obtainMessage(MyHandler.MSG_ON_WRITE, args).sendToTarget(); } } @Override - public void cancel() { - // Start not called or finish called or destroyed - nothing to do. - if (!mStartReqeusted || mFinishRequested || mDestroyed) { - return; - } - // Request cancellation of pending work if needed. + public void finish() { synchronized (mLock) { - cancelPreviousCancellableOperationLocked(); + // If destroyed the handler is null. + if (!isDestroyedLocked()) { + mHandler.obtainMessage(MyHandler.MSG_ON_FINISH, + mDocumentAdapter).sendToTarget(); + } } } @@ -719,20 +670,14 @@ public final class PrintManager { // Note the the spooler has a death recipient that observes if // this process gets killed so we cover the case of onDestroy not // being called due to this process being killed to reclaim memory. - final IPrintDocumentAdapterObserver observer; + IPrintDocumentAdapterObserver observer = null; synchronized (mLock) { if (activity == mActivity) { - mDestroyed = true; observer = mObserver; - clearLocked(); - } else { - observer = null; - activity = null; + destroyLocked(); } } if (observer != null) { - activity.getApplication().unregisterActivityLifecycleCallbacks( - PrintDocumentAdapterDelegate.this); try { observer.onDestroy(); } catch (RemoteException re) { @@ -741,67 +686,39 @@ public final class PrintManager { } } - private boolean isFinished() { - return mDocumentAdapter == null; + private boolean isDestroyedLocked() { + return (mActivity == null); } - private void clearLocked() { + private void destroyLocked() { + mActivity.getApplication().unregisterActivityLifecycleCallbacks( + PrintDocumentAdapterDelegate.this); mActivity = null; + mDocumentAdapter = null; + + // This method is only called from the main thread, so + // clearing the messages guarantees that any time a + // message is handled we are not in a destroyed state. + mHandler.removeMessages(MyHandler.MSG_ON_START); + mHandler.removeMessages(MyHandler.MSG_ON_LAYOUT); + mHandler.removeMessages(MyHandler.MSG_ON_WRITE); + mHandler.removeMessages(MyHandler.MSG_ON_FINISH); mHandler = null; - mLayoutOrWriteCancellation = null; - mLastLayoutSpec = null; - if (mLastWriteSpec != null) { - IoUtils.closeQuietly(mLastWriteSpec.fd); - mLastWriteSpec = null; - } - } - private boolean cancelPreviousCancellableOperationLocked() { - if (mLayoutOrWriteCancellation != null) { - mLayoutOrWriteCancellation.cancel(); - if (DEBUG) { - Log.i(LOG_TAG, "Cancelling previous operation"); - } - return true; - } - return false; - } + mObserver = null; - private void doPendingWorkLocked() { - if (mStartReqeusted && !mStarted) { - mStarted = true; - mHandler.sendEmptyMessage(MyHandler.MSG_START); - } else if (mLastLayoutSpec != null) { - mHandler.sendEmptyMessage(MyHandler.MSG_LAYOUT); - } else if (mLastWriteSpec != null) { - mHandler.sendEmptyMessage(MyHandler.MSG_WRITE); - } else if (mFinishRequested && !mFinished) { - mFinished = true; - mHandler.sendEmptyMessage(MyHandler.MSG_FINISH); + if (mPendingCallback != null) { + mPendingCallback.destroy(); + mPendingCallback = null; } } - private class LayoutSpec { - ILayoutResultCallback callback; - PrintAttributes oldAttributes; - PrintAttributes newAttributes; - Bundle metadata; - int sequence; - } - - private class WriteSpec { - IWriteResultCallback callback; - PageRange[] pages; - ParcelFileDescriptor fd; - int sequence; - } - private final class MyHandler extends Handler { - public static final int MSG_START = 1; - public static final int MSG_LAYOUT = 2; - public static final int MSG_WRITE = 3; - public static final int MSG_FINISH = 4; + public static final int MSG_ON_START = 1; + public static final int MSG_ON_LAYOUT = 2; + public static final int MSG_ON_WRITE = 3; + public static final int MSG_ON_FINISH = 4; public MyHandler(Looper looper) { super(looper, null, true); @@ -809,84 +726,71 @@ public final class PrintManager { @Override public void handleMessage(Message message) { - if (isFinished()) { - return; - } switch (message.what) { - case MSG_START: { - final PrintDocumentAdapter adapter; - synchronized (mLock) { - adapter = mDocumentAdapter; - } - if (adapter != null) { - adapter.onStart(); + case MSG_ON_START: { + if (DEBUG) { + Log.i(LOG_TAG, "onStart()"); } + + ((PrintDocumentAdapter) message.obj).onStart(); } break; - case MSG_LAYOUT: { - final PrintDocumentAdapter adapter; - final CancellationSignal cancellation; - final LayoutSpec layoutSpec; + case MSG_ON_LAYOUT: { + SomeArgs args = (SomeArgs) message.obj; + PrintDocumentAdapter adapter = (PrintDocumentAdapter) args.arg1; + PrintAttributes oldAttributes = (PrintAttributes) args.arg2; + PrintAttributes newAttributes = (PrintAttributes) args.arg3; + CancellationSignal cancellation = (CancellationSignal) args.arg4; + LayoutResultCallback callback = (LayoutResultCallback) args.arg5; + Bundle metadata = (Bundle) args.arg6; + args.recycle(); - synchronized (mLock) { - adapter = mDocumentAdapter; - layoutSpec = mLastLayoutSpec; - mLastLayoutSpec = null; - cancellation = new CancellationSignal(); - mLayoutOrWriteCancellation = cancellation; + if (DEBUG) { + StringBuilder builder = new StringBuilder(); + builder.append("PrintDocumentAdapter#onLayout() {\n"); + builder.append("\n oldAttributes:").append(oldAttributes); + builder.append("\n newAttributes:").append(newAttributes); + builder.append("\n preview:").append(metadata.getBoolean( + PrintDocumentAdapter.EXTRA_PRINT_PREVIEW)); + builder.append("\n}"); + Log.i(LOG_TAG, builder.toString()); } - if (layoutSpec != null && adapter != null) { - if (DEBUG) { - Log.i(LOG_TAG, "Performing layout"); - } - adapter.onLayout(layoutSpec.oldAttributes, - layoutSpec.newAttributes, cancellation, - new MyLayoutResultCallback(layoutSpec.callback, - layoutSpec.sequence), layoutSpec.metadata); - } + adapter.onLayout(oldAttributes, newAttributes, cancellation, + callback, metadata); } break; - case MSG_WRITE: { - final PrintDocumentAdapter adapter; - final CancellationSignal cancellation; - final WriteSpec writeSpec; + case MSG_ON_WRITE: { + SomeArgs args = (SomeArgs) message.obj; + PrintDocumentAdapter adapter = (PrintDocumentAdapter) args.arg1; + PageRange[] pages = (PageRange[]) args.arg2; + ParcelFileDescriptor fd = (ParcelFileDescriptor) args.arg3; + CancellationSignal cancellation = (CancellationSignal) args.arg4; + WriteResultCallback callback = (WriteResultCallback) args.arg5; + args.recycle(); - synchronized (mLock) { - adapter = mDocumentAdapter; - writeSpec = mLastWriteSpec; - mLastWriteSpec = null; - cancellation = new CancellationSignal(); - mLayoutOrWriteCancellation = cancellation; + if (DEBUG) { + StringBuilder builder = new StringBuilder(); + builder.append("PrintDocumentAdapter#onWrite() {\n"); + builder.append("\n pages:").append(Arrays.toString(pages)); + builder.append("\n}"); + Log.i(LOG_TAG, builder.toString()); } - if (writeSpec != null && adapter != null) { - if (DEBUG) { - Log.i(LOG_TAG, "Performing write"); - } - adapter.onWrite(writeSpec.pages, writeSpec.fd, - cancellation, new MyWriteResultCallback(writeSpec.callback, - writeSpec.fd, writeSpec.sequence)); - } + adapter.onWrite(pages, fd, cancellation, callback); } break; - case MSG_FINISH: { + case MSG_ON_FINISH: { if (DEBUG) { - Log.i(LOG_TAG, "Performing finish"); + Log.i(LOG_TAG, "onFinish()"); } - final PrintDocumentAdapter adapter; - final Activity activity; + + ((PrintDocumentAdapter) message.obj).onFinish(); + + // Done printing, so destroy this instance as it + // should not be used anymore. synchronized (mLock) { - adapter = mDocumentAdapter; - activity = mActivity; - clearLocked(); - } - if (adapter != null) { - adapter.onFinish(); - } - if (activity != null) { - activity.getApplication().unregisterActivityLifecycleCallbacks( - PrintDocumentAdapterDelegate.this); + destroyLocked(); } } break; @@ -898,7 +802,12 @@ public final class PrintManager { } } - private final class MyLayoutResultCallback extends LayoutResultCallback { + private interface DestroyableCallback { + public void destroy(); + } + + private final class MyLayoutResultCallback extends LayoutResultCallback + implements DestroyableCallback { private ILayoutResultCallback mCallback; private final int mSequence; @@ -910,25 +819,31 @@ public final class PrintManager { @Override public void onLayoutFinished(PrintDocumentInfo info, boolean changed) { - if (info == null) { - throw new NullPointerException("document info cannot be null"); - } final ILayoutResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } callback = mCallback; - clearLocked(); } - if (callback != null) { + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; + } + + try { + if (info == null) { + throw new NullPointerException("document info cannot be null"); + } + try { callback.onLayoutFinished(info, changed, mSequence); } catch (RemoteException re) { Log.e(LOG_TAG, "Error calling onLayoutFinished", re); } + } finally { + destroy(); } } @@ -936,46 +851,64 @@ public final class PrintManager { public void onLayoutFailed(CharSequence error) { final ILayoutResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } callback = mCallback; - clearLocked(); } - if (callback != null) { - try { - callback.onLayoutFailed(error, mSequence); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling onLayoutFailed", re); - } + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; + } + + try { + callback.onLayoutFailed(error, mSequence); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onLayoutFailed", re); + } finally { + destroy(); } } @Override public void onLayoutCancelled() { + final ILayoutResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } - clearLocked(); + callback = mCallback; + } + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; + } + + try { + callback.onLayoutCanceled(mSequence); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onLayoutFailed", re); + } finally { + destroy(); } } - private void clearLocked() { - mLayoutOrWriteCancellation = null; - mCallback = null; - doPendingWorkLocked(); + @Override + public void destroy() { + synchronized (mLock) { + mCallback = null; + mPendingCallback = null; + } } } - private final class MyWriteResultCallback extends WriteResultCallback { + private final class MyWriteResultCallback extends WriteResultCallback + implements DestroyableCallback { private ParcelFileDescriptor mFd; - private int mSequence; private IWriteResultCallback mCallback; + private final int mSequence; public MyWriteResultCallback(IWriteResultCallback callback, ParcelFileDescriptor fd, int sequence) { @@ -988,26 +921,32 @@ public final class PrintManager { public void onWriteFinished(PageRange[] pages) { final IWriteResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } callback = mCallback; - clearLocked(); - } - if (pages == null) { - throw new IllegalArgumentException("pages cannot be null"); } - if (pages.length == 0) { - throw new IllegalArgumentException("pages cannot be empty"); + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; } - if (callback != null) { + + try { + if (pages == null) { + throw new IllegalArgumentException("pages cannot be null"); + } + if (pages.length == 0) { + throw new IllegalArgumentException("pages cannot be empty"); + } + try { callback.onWriteFinished(pages, mSequence); } catch (RemoteException re) { Log.e(LOG_TAG, "Error calling onWriteFinished", re); } + } finally { + destroy(); } } @@ -1015,41 +954,58 @@ public final class PrintManager { public void onWriteFailed(CharSequence error) { final IWriteResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } callback = mCallback; - clearLocked(); } - if (callback != null) { - try { - callback.onWriteFailed(error, mSequence); - } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling onWriteFailed", re); - } + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; + } + + try { + callback.onWriteFailed(error, mSequence); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onWriteFailed", re); + } finally { + destroy(); } } @Override public void onWriteCancelled() { + final IWriteResultCallback callback; synchronized (mLock) { - if (mDestroyed) { - Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " - + "finish the printing activity before print completion?"); - return; - } - clearLocked(); + callback = mCallback; + } + + // If the callback is null we are destroyed. + if (callback == null) { + Log.e(LOG_TAG, "PrintDocumentAdapter is destroyed. Did you " + + "finish the printing activity before print completion " + + "or did you invoke a callback after finish?"); + return; + } + + try { + callback.onWriteCanceled(mSequence); + } catch (RemoteException re) { + Log.e(LOG_TAG, "Error calling onWriteCanceled", re); + } finally { + destroy(); } } - private void clearLocked() { - mLayoutOrWriteCancellation = null; - IoUtils.closeQuietly(mFd); - mCallback = null; - mFd = null; - doPendingWorkLocked(); + @Override + public void destroy() { + synchronized (mLock) { + IoUtils.closeQuietly(mFd); + mCallback = null; + mFd = null; + mPendingCallback = null; + } } } } diff --git a/core/java/android/print/PrinterDiscoverySession.java b/core/java/android/print/PrinterDiscoverySession.java index d32b71b..abb441b 100644 --- a/core/java/android/print/PrinterDiscoverySession.java +++ b/core/java/android/print/PrinterDiscoverySession.java @@ -72,9 +72,9 @@ public final class PrinterDiscoverySession { } } - public final void startPrinterDisovery(List<PrinterId> priorityList) { + public final void startPrinterDiscovery(List<PrinterId> priorityList) { if (isDestroyed()) { - Log.w(LOG_TAG, "Ignoring start printers dsicovery - session destroyed"); + Log.w(LOG_TAG, "Ignoring start printers discovery - session destroyed"); return; } if (!mIsPrinterDiscoveryStarted) { @@ -122,7 +122,7 @@ public final class PrinterDiscoverySession { try { mPrintManager.stopPrinterStateTracking(printerId, mUserId); } catch (RemoteException re) { - Log.e(LOG_TAG, "Error stoping printer state tracking", re); + Log.e(LOG_TAG, "Error stopping printer state tracking", re); } } diff --git a/core/java/android/printservice/PrintService.java b/core/java/android/printservice/PrintService.java index eb0ac2e..1557ab0 100644 --- a/core/java/android/printservice/PrintService.java +++ b/core/java/android/printservice/PrintService.java @@ -201,9 +201,9 @@ public abstract class PrintService extends Service { * should build another one using the {@link PrintJobInfo.Builder} class. You * can specify any standard properties and add advanced, printer specific, * ones via {@link PrintJobInfo.Builder#putAdvancedOption(String, String) - * PrintJobInfo.Builder#putAdvancedOption(String, String)} and {@link + * PrintJobInfo.Builder.putAdvancedOption(String, String)} and {@link * PrintJobInfo.Builder#putAdvancedOption(String, int) - * PrintJobInfo.Builder#putAdvancedOption(String, int)}. The advanced options + * PrintJobInfo.Builder.putAdvancedOption(String, int)}. The advanced options * are not interpreted by the system, they will not be visible to applications, * and can only be accessed by your print service via {@link * PrintJob#getAdvancedStringOption(String) PrintJob.getAdvancedStringOption(String)} @@ -212,14 +212,26 @@ public abstract class PrintService extends Service { * <p> * If the advanced print options activity offers changes to the standard print * options, you can get the current {@link android.print.PrinterInfo} using the - * "android.intent.extra.print.EXTRA_PRINTER_INFO" extra which will allow you to - * present the user with UI options supported by the current printer. For example, - * if the current printer does not support a give media size, you should not - * offer it in the advanced print options dialog. + * {@link #EXTRA_PRINTER_INFO} extra which will allow you to present the user + * with UI options supported by the current printer. For example, if the current + * printer does not support a given media size, you should not offer it in the + * advanced print options UI. * </p> + * + * @see #EXTRA_PRINTER_INFO */ public static final String EXTRA_PRINT_JOB_INFO = "android.intent.extra.print.PRINT_JOB_INFO"; + /** + * If you declared an optional activity with advanced print options via the + * {@link R.attr#advancedPrintOptionsActivity advancedPrintOptionsActivity} + * attribute, this extra is used to pass in the currently selected printer's + * {@link android.print.PrinterInfo} to your activity allowing you to inspect it. + * + * @see #EXTRA_PRINT_JOB_INFO + */ + public static final String EXTRA_PRINTER_INFO = "android.intent.extra.print.PRINTER_INFO"; + private Handler mHandler; private IPrintServiceClient mClient; diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index cfab1b3..0fe764f 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -1886,6 +1886,9 @@ public final class MediaStore { * The MIME type for entries in this table. */ public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio"; + + // Not instantiable. + private Radio() { } } } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 557f5a6..fd475cd 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -16,7 +16,7 @@ package android.service.notification; -import android.annotation.PrivateApi; +import android.annotation.SystemApi; import android.annotation.SdkConstant; import android.app.INotificationManager; import android.app.Service; @@ -279,7 +279,7 @@ public abstract class NotificationListenerService extends Service { * @param currentUser the user to use as the stream filter * @hide */ - @PrivateApi + @SystemApi public void registerAsSystemService(ComponentName componentName, int currentUser) throws RemoteException { if (mWrapper == null) { @@ -297,7 +297,7 @@ public abstract class NotificationListenerService extends Service { * with (@link registerAsService). * @hide */ - @PrivateApi + @SystemApi public void unregisterAsSystemService() throws RemoteException { if (mWrapper != null) { INotificationManager noMan = getNotificationInterface(); diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index f06ae71..48122d6 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -48,10 +48,11 @@ import android.text.style.URLSpan; import android.text.style.UnderlineSpan; import android.util.Log; import android.util.Printer; - import android.view.View; + import com.android.internal.R; import com.android.internal.util.ArrayUtils; + import libcore.icu.ICU; import java.lang.reflect.Array; @@ -229,7 +230,12 @@ public class TextUtils { public static boolean regionMatches(CharSequence one, int toffset, CharSequence two, int ooffset, int len) { - char[] temp = obtain(2 * len); + int tempLen = 2 * len; + if (tempLen < len) { + // Integer overflow; len is unreasonably large + throw new IndexOutOfBoundsException(); + } + char[] temp = obtain(tempLen); getChars(one, toffset, toffset + len, temp, 0); getChars(two, ooffset, ooffset + len, temp, len); diff --git a/core/java/android/transition/SidePropagation.java b/core/java/android/transition/SidePropagation.java index 5d38ac8..623cdd1 100644 --- a/core/java/android/transition/SidePropagation.java +++ b/core/java/android/transition/SidePropagation.java @@ -18,6 +18,7 @@ package android.transition; import android.graphics.Rect; import android.util.FloatMath; import android.util.Log; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -32,38 +33,19 @@ import android.view.ViewGroup; public class SidePropagation extends VisibilityPropagation { private static final String TAG = "SlidePropagation"; - /** - * Transition propagates relative to the distance of the left side of the scene. - */ - public static final int LEFT = Slide.LEFT; - - /** - * Transition propagates relative to the distance of the top of the scene. - */ - public static final int TOP = Slide.TOP; - - /** - * Transition propagates relative to the distance of the right side of the scene. - */ - public static final int RIGHT = Slide.RIGHT; - - /** - * Transition propagates relative to the distance of the bottom of the scene. - */ - public static final int BOTTOM = Slide.BOTTOM; - private float mPropagationSpeed = 3.0f; - private int mSide = BOTTOM; + private int mSide = Gravity.BOTTOM; /** * Sets the side that is used to calculate the transition propagation. If the transitioning * View is visible in the start of the transition, then it will transition sooner when * closer to the side and later when farther. If the view is not visible in the start of * the transition, then it will transition later when closer to the side and sooner when - * farther from the edge. The default is {@link #BOTTOM}. + * farther from the edge. The default is {@link Gravity#BOTTOM}. * * @param side The side that is used to calculate the transition propagation. Must be one of - * {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, or {@link #BOTTOM}. + * {@link Gravity#LEFT}, {@link Gravity#TOP}, {@link Gravity#RIGHT}, or + * {@link Gravity#BOTTOM}. */ public void setSide(int side) { mSide = side; @@ -141,16 +123,16 @@ public class SidePropagation extends VisibilityPropagation { int left, int top, int right, int bottom) { int distance = 0; switch (mSide) { - case LEFT: + case Gravity.LEFT: distance = right - viewX + Math.abs(epicenterY - viewY); break; - case TOP: + case Gravity.TOP: distance = bottom - viewY + Math.abs(epicenterX - viewX); break; - case RIGHT: + case Gravity.RIGHT: distance = viewX - left + Math.abs(epicenterY - viewY); break; - case BOTTOM: + case Gravity.BOTTOM: distance = viewY - top + Math.abs(epicenterX - viewX); break; } @@ -159,8 +141,8 @@ public class SidePropagation extends VisibilityPropagation { private int getMaxDistance(ViewGroup sceneRoot) { switch (mSide) { - case LEFT: - case RIGHT: + case Gravity.LEFT: + case Gravity.RIGHT: return sceneRoot.getWidth(); default: return sceneRoot.getHeight(); diff --git a/core/java/android/transition/Slide.java b/core/java/android/transition/Slide.java index 0ff8ddd..8269258 100644 --- a/core/java/android/transition/Slide.java +++ b/core/java/android/transition/Slide.java @@ -24,6 +24,7 @@ import android.animation.ValueAnimator; import android.graphics.Rect; import android.util.Log; import android.util.Property; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; @@ -41,35 +42,9 @@ import android.view.animation.DecelerateInterpolator; public class Slide extends Visibility { private static final String TAG = "Slide"; - /** - * Move Views in or out of the left edge of the scene. - * @see #setSlideEdge(int) - */ - public static final int LEFT = 0; - - /** - * Move Views in or out of the top edge of the scene. - * @see #setSlideEdge(int) - */ - public static final int TOP = 1; - - /** - * Move Views in or out of the right edge of the scene. - * @see #setSlideEdge(int) - */ - public static final int RIGHT = 2; - - /** - * Move Views in or out of the bottom edge of the scene. This is the - * default slide direction. - * @see #setSlideEdge(int) - */ - public static final int BOTTOM = 3; - private static final TimeInterpolator sDecelerate = new DecelerateInterpolator(); private static final TimeInterpolator sAccelerate = new AccelerateInterpolator(); - private int[] mTempLoc = new int[2]; private CalculateSlide mSlideCalculator = sCalculateBottom; private interface CalculateSlide { @@ -136,11 +111,11 @@ public class Slide extends Visibility { }; /** - * Constructor using the default {@link android.transition.Slide#BOTTOM} + * Constructor using the default {@link Gravity#BOTTOM} * slide edge direction. */ public Slide() { - setSlideEdge(BOTTOM); + setSlideEdge(Gravity.BOTTOM); } /** @@ -152,20 +127,22 @@ public class Slide extends Visibility { /** * Change the edge that Views appear and disappear from. - * @param slideEdge The edge of the scene to use for Views appearing and disappearing. + * @param slideEdge The edge of the scene to use for Views appearing and disappearing. One of + * {@link android.view.Gravity#LEFT}, {@link android.view.Gravity#TOP}, + * {@link android.view.Gravity#RIGHT}, {@link android.view.Gravity#BOTTOM}. */ public void setSlideEdge(int slideEdge) { switch (slideEdge) { - case LEFT: + case Gravity.LEFT: mSlideCalculator = sCalculateLeft; break; - case TOP: + case Gravity.TOP: mSlideCalculator = sCalculateTop; break; - case RIGHT: + case Gravity.RIGHT: mSlideCalculator = sCalculateRight; break; - case BOTTOM: + case Gravity.BOTTOM: mSlideCalculator = sCalculateBottom; break; default: diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 9a70099..e9c2bba 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -1763,7 +1763,7 @@ public abstract class Transition implements Cloneable { /** * Sets the callback to use to find the epicenter of a Transition. A null value indicates - * that there is no epicenter in the Transition and getEpicenter() will return null. + * that there is no epicenter in the Transition and onGetEpicenter() will return null. * Transitions like {@link android.transition.Explode} use a point or Rect to orient * the direction of travel. This is called the epicenter of the Transition and is * typically centered on a touched View. The @@ -1799,7 +1799,7 @@ public abstract class Transition implements Cloneable { if (mEpicenterCallback == null) { return null; } - return mEpicenterCallback.getEpicenter(this); + return mEpicenterCallback.onGetEpicenter(this); } /** @@ -2112,6 +2112,6 @@ public abstract class Transition implements Cloneable { * @return The Rect region of the epicenter of <code>transition</code> or null if * there is no epicenter. */ - public abstract Rect getEpicenter(Transition transition); + public abstract Rect onGetEpicenter(Transition transition); } } diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java index f4b562f..5b7c737 100644 --- a/core/java/android/transition/TransitionInflater.java +++ b/core/java/android/transition/TransitionInflater.java @@ -22,6 +22,7 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.util.AttributeSet; import android.util.Xml; +import android.view.Gravity; import android.view.InflateException; import android.view.ViewGroup; import android.view.animation.AnimationUtils; @@ -208,7 +209,7 @@ public class TransitionInflater { private Slide createSlideTransition(AttributeSet attrs) { TypedArray a = mContext.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Slide); - int edge = a.getInt(com.android.internal.R.styleable.Slide_slideEdge, Slide.BOTTOM); + int edge = a.getInt(com.android.internal.R.styleable.Slide_slideEdge, Gravity.BOTTOM); Slide slide = new Slide(edge); a.recycle(); return slide; diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java index d7e8cf0..3907e77 100644 --- a/core/java/android/util/Range.java +++ b/core/java/android/util/Range.java @@ -97,6 +97,27 @@ public final class Range<T extends Comparable<? super T>> { } /** + * Checks if the {@code value} is within the bounds of this range. + * + * <p>A value is considered to be within this range if it's {@code >=} then + * the lower endpoint <i>and</i> {@code <=} to the upper endpoint (using the {@link Comparable} + * interface.</p> + * + * @param value a non-{@code null} {@code T} reference + * @return {@code true} if the value is within this inclusive range, {@code false} otherwise + * + * @throws NullPointerException if {@code value} was {@code null} + */ + public boolean inRange(T value) { + checkNotNull(value, "value must not be null"); + + boolean gteLower = value.compareTo(mLower) >= 0; + boolean lteUpper = value.compareTo(mUpper) <= 0; + + return gteLower && lteUpper; + } + + /** * Compare two ranges for equality. * * <p>A range is considered equal if and only if both the lower and upper endpoints @@ -105,16 +126,13 @@ public final class Range<T extends Comparable<? super T>> { * @return {@code true} if the ranges are equal, {@code false} otherwise */ @Override - public boolean equals(final Object obj) { + public boolean equals(Object obj) { if (obj == null) { return false; - } - if (this == obj) { + } else if (this == obj) { return true; - } - if (obj instanceof Range) { + } else if (obj instanceof Range) { @SuppressWarnings("rawtypes") - final Range other = (Range) obj; return mLower.equals(other.mLower) && mUpper.equals(other.mUpper); } diff --git a/core/java/android/util/Rational.java b/core/java/android/util/Rational.java index 8d4c67f..9952859 100644 --- a/core/java/android/util/Rational.java +++ b/core/java/android/util/Rational.java @@ -15,29 +15,88 @@ */ package android.util; +import static com.android.internal.util.Preconditions.*; + +import java.io.IOException; +import java.io.InvalidObjectException; + /** * <p>An immutable data type representation a rational number.</p> * * <p>Contains a pair of {@code int}s representing the numerator and denominator of a * Rational number. </p> */ -public final class Rational { +public final class Rational extends Number implements Comparable<Rational> { + /** + * Constant for the <em>Not-a-Number (NaN)</em> value of the {@code Rational} type. + * + * <p>A {@code NaN} value is considered to be equal to itself (that is {@code NaN.equals(NaN)} + * will return {@code true}; it is always greater than any non-{@code NaN} value (that is + * {@code NaN.compareTo(notNaN)} will return a number greater than {@code 0}).</p> + * + * <p>Equivalent to constructing a new rational with both the numerator and denominator + * equal to {@code 0}.</p> + */ + public static final Rational NaN = new Rational(0, 0); + + /** + * Constant for the positive infinity value of the {@code Rational} type. + * + * <p>Equivalent to constructing a new rational with a positive numerator and a denominator + * equal to {@code 0}.</p> + */ + public static final Rational POSITIVE_INFINITY = new Rational(1, 0); + + /** + * Constant for the negative infinity value of the {@code Rational} type. + * + * <p>Equivalent to constructing a new rational with a negative numerator and a denominator + * equal to {@code 0}.</p> + */ + public static final Rational NEGATIVE_INFINITY = new Rational(-1, 0); + + /** + * Constant for the zero value of the {@code Rational} type. + * + * <p>Equivalent to constructing a new rational with a numerator equal to {@code 0} and + * any non-zero denominator.</p> + */ + public static final Rational ZERO = new Rational(0, 1); + + /** + * Unique version number per class to be compliant with {@link java.io.Serializable}. + * + * <p>Increment each time the fields change in any way.</p> + */ + private static final long serialVersionUID = 1L; + + /* + * Do not change the order of these fields or add new instance fields to maintain the + * Serializable compatibility across API revisions. + */ private final int mNumerator; private final int mDenominator; /** - * <p>Create a Rational with a given numerator and denominator.</p> + * <p>Create a {@code Rational} with a given numerator and denominator.</p> * * <p>The signs of the numerator and the denominator may be flipped such that the denominator - * is always positive.</p> + * is always positive. Both the numerator and denominator will be converted to their reduced + * forms (see {@link #equals} for more details).</p> * - * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics - * as float {@code NaN} and {@code INF} values. For {@code NaN}, - * both {@link #getNumerator} and {@link #getDenominator} functions will return 0. For - * positive or negative {@code INF}, only the {@link #getDenominator} will return 0.</p> + * <p>For example, + * <ul> + * <li>a rational of {@code 2/4} will be reduced to {@code 1/2}. + * <li>a rational of {@code 1/-1} will be flipped to {@code -1/1} + * <li>a rational of {@code 5/0} will be reduced to {@code 1/0} + * <li>a rational of {@code 0/5} will be reduced to {@code 0/1} + * </ul> + * </p> * * @param numerator the numerator of the rational * @param denominator the denominator of the rational + * + * @see #equals */ public Rational(int numerator, int denominator) { @@ -46,32 +105,100 @@ public final class Rational { denominator = -denominator; } - mNumerator = numerator; - mDenominator = denominator; + // Convert to reduced form + if (denominator == 0 && numerator > 0) { + mNumerator = 1; // +Inf + mDenominator = 0; + } else if (denominator == 0 && numerator < 0) { + mNumerator = -1; // -Inf + mDenominator = 0; + } else if (denominator == 0 && numerator == 0) { + mNumerator = 0; // NaN + mDenominator = 0; + } else if (numerator == 0) { + mNumerator = 0; + mDenominator = 1; + } else { + int gcd = gcd(numerator, denominator); + + mNumerator = numerator / gcd; + mDenominator = denominator / gcd; + } } /** * Gets the numerator of the rational. + * + * <p>The numerator will always return {@code 1} if this rational represents + * infinity (that is, the denominator is {@code 0}).</p> */ public int getNumerator() { - if (mDenominator == 0) { - return 0; - } return mNumerator; } /** * Gets the denominator of the rational + * + * <p>The denominator may return {@code 0}, in which case the rational may represent + * positive infinity (if the numerator was positive), negative infinity (if the numerator + * was negative), or {@code NaN} (if the numerator was {@code 0}).</p> + * + * <p>The denominator will always return {@code 1} if the numerator is {@code 0}. */ public int getDenominator() { return mDenominator; } - private boolean isNaN() { + /** + * Indicates whether this rational is a <em>Not-a-Number (NaN)</em> value. + * + * <p>A {@code NaN} value occurs when both the numerator and the denominator are {@code 0}.</p> + * + * @return {@code true} if this rational is a <em>Not-a-Number (NaN)</em> value; + * {@code false} if this is a (potentially infinite) number value + */ + public boolean isNaN() { return mDenominator == 0 && mNumerator == 0; } - private boolean isInf() { + /** + * Indicates whether this rational represents an infinite value. + * + * <p>An infinite value occurs when the denominator is {@code 0} (but the numerator is not).</p> + * + * @return {@code true} if this rational is a (positive or negative) infinite value; + * {@code false} if this is a finite number value (or {@code NaN}) + */ + public boolean isInfinite() { + return mNumerator != 0 && mDenominator == 0; + } + + /** + * Indicates whether this rational represents a finite value. + * + * <p>A finite value occurs when the denominator is not {@code 0}; in other words + * the rational is neither infinity or {@code NaN}.</p> + * + * @return {@code true} if this rational is a (positive or negative) infinite value; + * {@code false} if this is a finite number value (or {@code NaN}) + */ + public boolean isFinite() { + return mDenominator != 0; + } + + /** + * Indicates whether this rational represents a zero value. + * + * <p>A zero value is a {@link #isFinite finite} rational with a numerator of {@code 0}.</p> + * + * @return {@code true} if this rational is finite zero value; + * {@code false} otherwise + */ + public boolean isZero() { + return isFinite() && mNumerator == 0; + } + + private boolean isPosInf() { return mDenominator == 0 && mNumerator > 0; } @@ -82,12 +209,12 @@ public final class Rational { /** * <p>Compare this Rational to another object and see if they are equal.</p> * - * <p>A Rational object can only be equal to another Rational object (comparing against any other - * type will return false).</p> + * <p>A Rational object can only be equal to another Rational object (comparing against any + * other type will return {@code false}).</p> * * <p>A Rational object is considered equal to another Rational object if and only if one of - * the following holds</p>: - * <ul><li>Both are NaN</li> + * the following holds:</p> + * <ul><li>Both are {@code NaN}</li> * <li>Both are infinities of the same sign</li> * <li>Both have the same numerator and denominator in their reduced form</li> * </ul> @@ -96,12 +223,12 @@ public final class Rational { * denominator by their greatest common divisor.</p> * * <pre>{@code - * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true - * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false - * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction - * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN) - * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity - * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity + * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true + * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false + * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction + * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN) + * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity + * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity * }</pre> * * @param obj a reference to another object @@ -110,41 +237,31 @@ public final class Rational { */ @Override public boolean equals(Object obj) { - if (obj == null) { - return false; - } else if (obj instanceof Rational) { - Rational other = (Rational) obj; - if (mDenominator == 0 || other.mDenominator == 0) { - if (isNaN() && other.isNaN()) { - return true; - } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) { - return true; - } else { - return false; - } - } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) { - return true; - } else { - int thisGcd = gcd(); - int otherGcd = other.gcd(); - - int thisNumerator = mNumerator / thisGcd; - int thisDenominator = mDenominator / thisGcd; - - int otherNumerator = other.mNumerator / otherGcd; - int otherDenominator = other.mDenominator / otherGcd; - - return (thisNumerator == otherNumerator && thisDenominator == otherDenominator); - } - } - return false; + return obj instanceof Rational && equals((Rational) obj); + } + + private boolean equals(Rational other) { + return (mNumerator == other.mNumerator && mDenominator == other.mDenominator); } + /** + * Return a string representation of this rational, e.g. {@code "1/2"}. + * + * <p>The following rules of conversion apply: + * <ul> + * <li>{@code NaN} values will return {@code "NaN"} + * <li>Positive infinity values will return {@code "Infinity"} + * <li>Negative infinity values will return {@code "-Infinity"} + * <li>All other values will return {@code "numerator/denominator"} where {@code numerator} + * and {@code denominator} are substituted with the appropriate numerator and denominator + * values. + * </ul></p> + */ @Override public String toString() { if (isNaN()) { return "NaN"; - } else if (isInf()) { + } else if (isPosInf()) { return "Infinity"; } else if (isNegInf()) { return "-Infinity"; @@ -160,7 +277,8 @@ public final class Rational { * @hide */ public float toFloat() { - return (float) mNumerator / (float) mDenominator; + // TODO: remove this duplicate function (used in CTS and the shim) + return floatValue(); } /** @@ -177,20 +295,24 @@ public final class Rational { /** * Calculates the greatest common divisor using Euclid's algorithm. * + * <p><em>Visible for testing only.</em></p> + * + * @param numerator the numerator in a fraction + * @param denominator the denominator in a fraction + * * @return An int value representing the gcd. Always positive. * @hide */ - public int gcd() { - /** + public static int gcd(int numerator, int denominator) { + /* * Non-recursive implementation of Euclid's algorithm: * * gcd(a, 0) := a * gcd(a, b) := gcd(b, a mod b) * */ - - int a = mNumerator; - int b = mDenominator; + int a = numerator; + int b = denominator; while (b != 0) { int oldB = b; @@ -201,4 +323,221 @@ public final class Rational { return Math.abs(a); } + + /** + * Returns the value of the specified number as a {@code double}. + * + * <p>The {@code double} is calculated by converting both the numerator and denominator + * to a {@code double}; then returning the result of dividing the numerator by the + * denominator.</p> + * + * @return the divided value of the numerator and denominator as a {@code double}. + */ + @Override + public double doubleValue() { + double num = mNumerator; + double den = mDenominator; + + return num / den; + } + + /** + * Returns the value of the specified number as a {@code float}. + * + * <p>The {@code float} is calculated by converting both the numerator and denominator + * to a {@code float}; then returning the result of dividing the numerator by the + * denominator.</p> + * + * @return the divided value of the numerator and denominator as a {@code float}. + */ + @Override + public float floatValue() { + float num = mNumerator; + float den = mDenominator; + + return num / den; + } + + /** + * Returns the value of the specified number as a {@code int}. + * + * <p>{@link #isInfinite Finite} rationals are converted to an {@code int} value + * by dividing the numerator by the denominator; conversion for non-finite values happens + * identically to casting a floating point value to an {@code int}, in particular: + * + * <p> + * <ul> + * <li>Positive infinity saturates to the largest maximum integer + * {@link Integer#MAX_VALUE}</li> + * <li>Negative infinity saturates to the smallest maximum integer + * {@link Integer#MIN_VALUE}</li> + * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li> + * </ul> + * </p> + * + * @return the divided value of the numerator and denominator as a {@code int}. + */ + @Override + public int intValue() { + // Mimic float to int conversion rules from JLS 5.1.3 + + if (isPosInf()) { + return Integer.MAX_VALUE; + } else if (isNegInf()) { + return Integer.MIN_VALUE; + } else if (isNaN()) { + return 0; + } else { // finite + return mNumerator / mDenominator; + } + } + + /** + * Returns the value of the specified number as a {@code long}. + * + * <p>{@link #isInfinite Finite} rationals are converted to an {@code long} value + * by dividing the numerator by the denominator; conversion for non-finite values happens + * identically to casting a floating point value to a {@code long}, in particular: + * + * <p> + * <ul> + * <li>Positive infinity saturates to the largest maximum long + * {@link Long#MAX_VALUE}</li> + * <li>Negative infinity saturates to the smallest maximum long + * {@link Long#MIN_VALUE}</li> + * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li> + * </ul> + * </p> + * + * @return the divided value of the numerator and denominator as a {@code long}. + */ + @Override + public long longValue() { + // Mimic float to long conversion rules from JLS 5.1.3 + + if (isPosInf()) { + return Long.MAX_VALUE; + } else if (isNegInf()) { + return Long.MIN_VALUE; + } else if (isNaN()) { + return 0; + } else { // finite + return mNumerator / mDenominator; + } + } + + /** + * Returns the value of the specified number as a {@code short}. + * + * <p>{@link #isInfinite Finite} rationals are converted to a {@code short} value + * identically to {@link #intValue}; the {@code int} result is then truncated to a + * {@code short} before returning the value.</p> + * + * @return the divided value of the numerator and denominator as a {@code short}. + */ + @Override + public short shortValue() { + return (short) intValue(); + } + + /** + * Compare this rational to the specified rational to determine their natural order. + * + * <p>{@link #NaN} is considered to be equal to itself and greater than all other + * {@code Rational} values. Otherwise, if the objects are not {@link #equals equal}, then + * the following rules apply:</p> + * + * <ul> + * <li>Positive infinity is greater than any other finite number (or negative infinity) + * <li>Negative infinity is less than any other finite number (or positive infinity) + * <li>The finite number represented by this rational is checked numerically + * against the other finite number by converting both rationals to a common denominator multiple + * and comparing their numerators. + * </ul> + * + * @param another the rational to be compared + * + * @return a negative integer, zero, or a positive integer as this object is less than, + * equal to, or greater than the specified rational. + * + * @throws NullPointerException if {@code another} was {@code null} + */ + @Override + public int compareTo(Rational another) { + checkNotNull(another, "another must not be null"); + + if (equals(another)) { + return 0; + } else if (isNaN()) { // NaN is greater than the other non-NaN value + return 1; + } else if (another.isNaN()) { // the other NaN is greater than this non-NaN value + return -1; + } else if (isPosInf() || another.isNegInf()) { + return 1; // positive infinity is greater than any non-NaN/non-posInf value + } else if (isNegInf() || another.isPosInf()) { + return -1; // negative infinity is less than any non-NaN/non-negInf value + } + + // else both this and another are finite numbers + + // make the denominators the same, then compare numerators + long thisNumerator = ((long)mNumerator) * another.mDenominator; // long to avoid overflow + long otherNumerator = ((long)another.mNumerator) * mDenominator; // long to avoid overflow + + // avoid underflow from subtraction by doing comparisons + if (thisNumerator < otherNumerator) { + return -1; + } else if (thisNumerator > otherNumerator) { + return 1; + } else { + // This should be covered by #equals, but have this code path just in case + return 0; + } + } + + /* + * Serializable implementation. + * + * The following methods are omitted: + * >> writeObject - the default is sufficient (field by field serialization) + * >> readObjectNoData - the default is sufficient (0s for both fields is a NaN) + */ + + /** + * writeObject with default serialized form - guards against + * deserializing non-reduced forms of the rational. + * + * @throws InvalidObjectException if the invariants were violated + */ + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException { + in.defaultReadObject(); + + /* + * Guard against trying to deserialize illegal values (in this case, ones + * that don't have a standard reduced form). + * + * - Non-finite values must be one of [0, 1], [0, 0], [0, 1], [0, -1] + * - Finite values must always have their greatest common divisor as 1 + */ + + if (mNumerator == 0) { // either zero or NaN + if (mDenominator == 1 || mDenominator == 0) { + return; + } + throw new InvalidObjectException( + "Rational must be deserialized from a reduced form for zero values"); + } else if (mDenominator == 0) { // either positive or negative infinity + if (mNumerator == 1 || mNumerator == -1) { + return; + } + throw new InvalidObjectException( + "Rational must be deserialized from a reduced form for infinity values"); + } else { // finite value + if (gcd(mNumerator, mDenominator) > 1) { + throw new InvalidObjectException( + "Rational must be deserialized from a reduced form for finite values"); + } + } + } } diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 6acb134..b5b9199 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -217,8 +217,6 @@ final class HardwareLayer { private static native void nUpdateRenderLayer(long layerUpdater, long displayList, int left, int top, int right, int bottom); - private static native boolean nFlushChanges(long layerUpdater); - private static native long nGetLayer(long layerUpdater); private static native int nGetTexName(long layerUpdater); } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index d67c974..592dec8 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -363,8 +363,7 @@ public abstract class HardwareRenderer { * @param callbacks Callbacks invoked when drawing happens. * @param dirty The dirty rectangle to update, can be null. */ - abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, - Rect dirty); + abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks); /** * Creates a new hardware layer. A hardware layer built by calling this diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index a52ccdf..ae59bbc 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -30,6 +30,7 @@ import android.view.IApplicationToken; import android.view.IOnKeyguardExitResult; import android.view.IRotationWatcher; import android.view.IWindowSession; +import android.view.IWindowSessionCallback; import android.view.KeyEvent; import android.view.InputEvent; import android.view.MagnificationSpec; @@ -56,7 +57,7 @@ interface IWindowManager boolean stopViewServer(); // Transaction #2 boolean isViewServerRunning(); // Transaction #3 - IWindowSession openSession(in IInputMethodClient client, + IWindowSession openSession(in IWindowSessionCallback callback, in IInputMethodClient client, in IInputContext inputContext); boolean inputMethodClientHasFocus(IInputMethodClient client); @@ -130,6 +131,8 @@ interface IWindowManager void setAnimationScale(int which, float scale); void setAnimationScales(in float[] scales); + float getCurrentAnimatorScale(); + // For testing void setInTouchMode(boolean showFocus); diff --git a/core/java/android/view/IWindowSessionCallback.aidl b/core/java/android/view/IWindowSessionCallback.aidl new file mode 100644 index 0000000..88931ce --- /dev/null +++ b/core/java/android/view/IWindowSessionCallback.aidl @@ -0,0 +1,27 @@ +/* +** Copyright 2014, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package android.view; + +/** + * Callback to active sessions of the window manager + * + * {@hide} + */ +oneway interface IWindowSessionCallback +{ + void onAnimatorScaleChanged(float scale); +} diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index e63829e..4631b64 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -325,8 +325,8 @@ public class RenderNode { * * @hide */ - public void setCaching(boolean caching) { - nSetCaching(mNativeRenderNode, caching); + public boolean setCaching(boolean caching) { + return nSetCaching(mNativeRenderNode, caching); } /** @@ -335,8 +335,8 @@ public class RenderNode { * * @param clipToBounds true if the display list should clip to its bounds */ - public void setClipToBounds(boolean clipToBounds) { - nSetClipToBounds(mNativeRenderNode, clipToBounds); + public boolean setClipToBounds(boolean clipToBounds) { + return nSetClipToBounds(mNativeRenderNode, clipToBounds); } /** @@ -346,8 +346,8 @@ public class RenderNode { * @param shouldProject true if the display list should be projected onto a * containing volume. */ - public void setProjectBackwards(boolean shouldProject) { - nSetProjectBackwards(mNativeRenderNode, shouldProject); + public boolean setProjectBackwards(boolean shouldProject) { + return nSetProjectBackwards(mNativeRenderNode, shouldProject); } /** @@ -355,8 +355,8 @@ public class RenderNode { * DisplayList should draw any descendent DisplayLists with * ProjectBackwards=true directly on top of it. Default value is false. */ - public void setProjectionReceiver(boolean shouldRecieve) { - nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); + public boolean setProjectionReceiver(boolean shouldRecieve) { + return nSetProjectionReceiver(mNativeRenderNode, shouldRecieve); } /** @@ -365,15 +365,16 @@ public class RenderNode { * * Deep copies the data into native to simplify reference ownership. */ - public void setOutline(Outline outline) { + public boolean setOutline(Outline outline) { if (outline == null || outline.isEmpty()) { - nSetOutlineEmpty(mNativeRenderNode); + return nSetOutlineEmpty(mNativeRenderNode); } else if (outline.mRect != null) { - nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, + return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, outline.mRect.right, outline.mRect.bottom, outline.mRadius); } else if (outline.mPath != null) { - nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath); + return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath); } + throw new IllegalArgumentException("Unrecognized outline?"); } /** @@ -381,8 +382,8 @@ public class RenderNode { * * @param clipToOutline true if clipping to the outline. */ - public void setClipToOutline(boolean clipToOutline) { - nSetClipToOutline(mNativeRenderNode, clipToOutline); + public boolean setClipToOutline(boolean clipToOutline) { + return nSetClipToOutline(mNativeRenderNode, clipToOutline); } public boolean getClipToOutline() { @@ -392,9 +393,9 @@ public class RenderNode { /** * Controls the RenderNode's circular reveal clip. */ - public void setRevealClip(boolean shouldClip, boolean inverseClip, + public boolean setRevealClip(boolean shouldClip, boolean inverseClip, float x, float y, float radius) { - nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius); + return nSetRevealClip(mNativeRenderNode, shouldClip, inverseClip, x, y, radius); } /** @@ -403,8 +404,8 @@ public class RenderNode { * * @param matrix A transform matrix to apply to this display list */ - public void setStaticMatrix(Matrix matrix) { - nSetStaticMatrix(mNativeRenderNode, matrix.native_instance); + public boolean setStaticMatrix(Matrix matrix) { + return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance); } /** @@ -417,8 +418,8 @@ public class RenderNode { * * @hide */ - public void setAnimationMatrix(Matrix matrix) { - nSetAnimationMatrix(mNativeRenderNode, + public boolean setAnimationMatrix(Matrix matrix) { + return nSetAnimationMatrix(mNativeRenderNode, (matrix != null) ? matrix.native_instance : 0); } @@ -430,8 +431,8 @@ public class RenderNode { * @see View#setAlpha(float) * @see #getAlpha() */ - public void setAlpha(float alpha) { - nSetAlpha(mNativeRenderNode, alpha); + public boolean setAlpha(float alpha) { + return nSetAlpha(mNativeRenderNode, alpha); } /** @@ -456,8 +457,8 @@ public class RenderNode { * @see android.view.View#hasOverlappingRendering() * @see #hasOverlappingRendering() */ - public void setHasOverlappingRendering(boolean hasOverlappingRendering) { - nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering); + public boolean setHasOverlappingRendering(boolean hasOverlappingRendering) { + return nSetHasOverlappingRendering(mNativeRenderNode, hasOverlappingRendering); } /** @@ -472,8 +473,8 @@ public class RenderNode { return nHasOverlappingRendering(mNativeRenderNode); } - public void setElevation(float lift) { - nSetElevation(mNativeRenderNode, lift); + public boolean setElevation(float lift) { + return nSetElevation(mNativeRenderNode, lift); } public float getElevation() { @@ -488,8 +489,8 @@ public class RenderNode { * @see View#setTranslationX(float) * @see #getTranslationX() */ - public void setTranslationX(float translationX) { - nSetTranslationX(mNativeRenderNode, translationX); + public boolean setTranslationX(float translationX) { + return nSetTranslationX(mNativeRenderNode, translationX); } /** @@ -509,8 +510,8 @@ public class RenderNode { * @see View#setTranslationY(float) * @see #getTranslationY() */ - public void setTranslationY(float translationY) { - nSetTranslationY(mNativeRenderNode, translationY); + public boolean setTranslationY(float translationY) { + return nSetTranslationY(mNativeRenderNode, translationY); } /** @@ -528,8 +529,8 @@ public class RenderNode { * @see View#setTranslationZ(float) * @see #getTranslationZ() */ - public void setTranslationZ(float translationZ) { - nSetTranslationZ(mNativeRenderNode, translationZ); + public boolean setTranslationZ(float translationZ) { + return nSetTranslationZ(mNativeRenderNode, translationZ); } /** @@ -549,8 +550,8 @@ public class RenderNode { * @see View#setRotation(float) * @see #getRotation() */ - public void setRotation(float rotation) { - nSetRotation(mNativeRenderNode, rotation); + public boolean setRotation(float rotation) { + return nSetRotation(mNativeRenderNode, rotation); } /** @@ -570,8 +571,8 @@ public class RenderNode { * @see View#setRotationX(float) * @see #getRotationX() */ - public void setRotationX(float rotationX) { - nSetRotationX(mNativeRenderNode, rotationX); + public boolean setRotationX(float rotationX) { + return nSetRotationX(mNativeRenderNode, rotationX); } /** @@ -591,8 +592,8 @@ public class RenderNode { * @see View#setRotationY(float) * @see #getRotationY() */ - public void setRotationY(float rotationY) { - nSetRotationY(mNativeRenderNode, rotationY); + public boolean setRotationY(float rotationY) { + return nSetRotationY(mNativeRenderNode, rotationY); } /** @@ -612,8 +613,8 @@ public class RenderNode { * @see View#setScaleX(float) * @see #getScaleX() */ - public void setScaleX(float scaleX) { - nSetScaleX(mNativeRenderNode, scaleX); + public boolean setScaleX(float scaleX) { + return nSetScaleX(mNativeRenderNode, scaleX); } /** @@ -633,8 +634,8 @@ public class RenderNode { * @see View#setScaleY(float) * @see #getScaleY() */ - public void setScaleY(float scaleY) { - nSetScaleY(mNativeRenderNode, scaleY); + public boolean setScaleY(float scaleY) { + return nSetScaleY(mNativeRenderNode, scaleY); } /** @@ -654,8 +655,8 @@ public class RenderNode { * @see View#setPivotX(float) * @see #getPivotX() */ - public void setPivotX(float pivotX) { - nSetPivotX(mNativeRenderNode, pivotX); + public boolean setPivotX(float pivotX) { + return nSetPivotX(mNativeRenderNode, pivotX); } /** @@ -675,8 +676,8 @@ public class RenderNode { * @see View#setPivotY(float) * @see #getPivotY() */ - public void setPivotY(float pivotY) { - nSetPivotY(mNativeRenderNode, pivotY); + public boolean setPivotY(float pivotY) { + return nSetPivotY(mNativeRenderNode, pivotY); } /** @@ -702,8 +703,8 @@ public class RenderNode { * @see View#setCameraDistance(float) * @see #getCameraDistance() */ - public void setCameraDistance(float distance) { - nSetCameraDistance(mNativeRenderNode, distance); + public boolean setCameraDistance(float distance) { + return nSetCameraDistance(mNativeRenderNode, distance); } /** @@ -723,8 +724,8 @@ public class RenderNode { * @see View#setLeft(int) * @see #getLeft() */ - public void setLeft(int left) { - nSetLeft(mNativeRenderNode, left); + public boolean setLeft(int left) { + return nSetLeft(mNativeRenderNode, left); } /** @@ -744,8 +745,8 @@ public class RenderNode { * @see View#setTop(int) * @see #getTop() */ - public void setTop(int top) { - nSetTop(mNativeRenderNode, top); + public boolean setTop(int top) { + return nSetTop(mNativeRenderNode, top); } /** @@ -765,8 +766,8 @@ public class RenderNode { * @see View#setRight(int) * @see #getRight() */ - public void setRight(int right) { - nSetRight(mNativeRenderNode, right); + public boolean setRight(int right) { + return nSetRight(mNativeRenderNode, right); } /** @@ -786,8 +787,8 @@ public class RenderNode { * @see View#setBottom(int) * @see #getBottom() */ - public void setBottom(int bottom) { - nSetBottom(mNativeRenderNode, bottom); + public boolean setBottom(int bottom) { + return nSetBottom(mNativeRenderNode, bottom); } /** @@ -812,8 +813,8 @@ public class RenderNode { * @see View#setRight(int) * @see View#setBottom(int) */ - public void setLeftTopRightBottom(int left, int top, int right, int bottom) { - nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom); + public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) { + return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom); } /** @@ -824,8 +825,8 @@ public class RenderNode { * * @see View#offsetLeftAndRight(int) */ - public void offsetLeftAndRight(float offset) { - nOffsetLeftAndRight(mNativeRenderNode, offset); + public boolean offsetLeftAndRight(float offset) { + return nOffsetLeftAndRight(mNativeRenderNode, offset); } /** @@ -836,8 +837,15 @@ public class RenderNode { * * @see View#offsetTopAndBottom(int) */ - public void offsetTopAndBottom(float offset) { - nOffsetTopAndBottom(mNativeRenderNode, offset); + public boolean offsetTopAndBottom(float offset) { + return nOffsetTopAndBottom(mNativeRenderNode, offset); + } + + /** + * Sets the scroll position, this is used for damage calculations + */ + public void setScrollPosition(int x, int y) { + nSetScrollPosition(mNativeRenderNode, x, y); } /** @@ -890,42 +898,43 @@ public class RenderNode { // Properties - private static native void nOffsetTopAndBottom(long renderNode, float offset); - private static native void nOffsetLeftAndRight(long renderNode, float offset); - private static native void nSetLeftTopRightBottom(long renderNode, int left, int top, + private static native boolean nOffsetTopAndBottom(long renderNode, float offset); + private static native boolean nOffsetLeftAndRight(long renderNode, float offset); + private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top, int right, int bottom); - private static native void nSetBottom(long renderNode, int bottom); - private static native void nSetRight(long renderNode, int right); - private static native void nSetTop(long renderNode, int top); - private static native void nSetLeft(long renderNode, int left); - private static native void nSetCameraDistance(long renderNode, float distance); - private static native void nSetPivotY(long renderNode, float pivotY); - private static native void nSetPivotX(long renderNode, float pivotX); - private static native void nSetCaching(long renderNode, boolean caching); - private static native void nSetClipToBounds(long renderNode, boolean clipToBounds); - private static native void nSetProjectBackwards(long renderNode, boolean shouldProject); - private static native void nSetProjectionReceiver(long renderNode, boolean shouldRecieve); - private static native void nSetOutlineRoundRect(long renderNode, int left, int top, + private static native boolean nSetBottom(long renderNode, int bottom); + private static native boolean nSetRight(long renderNode, int right); + private static native boolean nSetTop(long renderNode, int top); + private static native boolean nSetLeft(long renderNode, int left); + private static native void nSetScrollPosition(long renderNode, int scrollX, int scrollY); + private static native boolean nSetCameraDistance(long renderNode, float distance); + private static native boolean nSetPivotY(long renderNode, float pivotY); + private static native boolean nSetPivotX(long renderNode, float pivotX); + private static native boolean nSetCaching(long renderNode, boolean caching); + private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds); + private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject); + private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve); + private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top, int right, int bottom, float radius); - private static native void nSetOutlineConvexPath(long renderNode, long nativePath); - private static native void nSetOutlineEmpty(long renderNode); - private static native void nSetClipToOutline(long renderNode, boolean clipToOutline); - private static native void nSetRevealClip(long renderNode, + private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath); + private static native boolean nSetOutlineEmpty(long renderNode); + private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline); + private static native boolean nSetRevealClip(long renderNode, boolean shouldClip, boolean inverseClip, float x, float y, float radius); - private static native void nSetAlpha(long renderNode, float alpha); - private static native void nSetHasOverlappingRendering(long renderNode, + private static native boolean nSetAlpha(long renderNode, float alpha); + private static native boolean nSetHasOverlappingRendering(long renderNode, boolean hasOverlappingRendering); - private static native void nSetElevation(long renderNode, float lift); - private static native void nSetTranslationX(long renderNode, float translationX); - private static native void nSetTranslationY(long renderNode, float translationY); - private static native void nSetTranslationZ(long renderNode, float translationZ); - private static native void nSetRotation(long renderNode, float rotation); - private static native void nSetRotationX(long renderNode, float rotationX); - private static native void nSetRotationY(long renderNode, float rotationY); - private static native void nSetScaleX(long renderNode, float scaleX); - private static native void nSetScaleY(long renderNode, float scaleY); - private static native void nSetStaticMatrix(long renderNode, long nativeMatrix); - private static native void nSetAnimationMatrix(long renderNode, long animationMatrix); + private static native boolean nSetElevation(long renderNode, float lift); + private static native boolean nSetTranslationX(long renderNode, float translationX); + private static native boolean nSetTranslationY(long renderNode, float translationY); + private static native boolean nSetTranslationZ(long renderNode, float translationZ); + private static native boolean nSetRotation(long renderNode, float rotation); + private static native boolean nSetRotationX(long renderNode, float rotationX); + private static native boolean nSetRotationY(long renderNode, float rotationY); + private static native boolean nSetScaleX(long renderNode, float scaleX); + private static native boolean nSetScaleY(long renderNode, float scaleY); + private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix); + private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix); private static native boolean nHasOverlappingRendering(long renderNode); private static native boolean nGetClipToOutline(long renderNode); diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 9b3ef7f..7bbe84e 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -54,8 +54,6 @@ import java.io.PrintWriter; public class ThreadedRenderer extends HardwareRenderer { private static final String LOGTAG = "ThreadedRenderer"; - private static final Rect NULL_RECT = new Rect(); - // Keep in sync with DrawFrameTask.h SYNC_* flags // Nothing interesting to report private static final int SYNC_OK = 0x0; @@ -228,7 +226,7 @@ public class ThreadedRenderer extends HardwareRenderer { } @Override - void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) { + void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) { attachInfo.mIgnoreDirtyState = true; long frameTimeNanos = mChoreographer.getFrameTimeNanos(); attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS; @@ -246,12 +244,8 @@ public class ThreadedRenderer extends HardwareRenderer { attachInfo.mIgnoreDirtyState = false; - if (dirty == null) { - dirty = NULL_RECT; - } int syncResult = nSyncAndDrawFrame(mNativeProxy, frameTimeNanos, - recordDuration, view.getResources().getDisplayMetrics().density, - dirty.left, dirty.top, dirty.right, dirty.bottom); + recordDuration, view.getResources().getDisplayMetrics().density); if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) { attachInfo.mViewRootImpl.invalidate(); } @@ -393,8 +387,7 @@ public class ThreadedRenderer extends HardwareRenderer { float lightX, float lightY, float lightZ, float lightRadius); private static native void nSetOpaque(long nativeProxy, boolean opaque); private static native int nSyncAndDrawFrame(long nativeProxy, - long frameTimeNanos, long recordDuration, float density, - int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom); + long frameTimeNanos, long recordDuration, float density); private static native void nRunWithGlContext(long nativeProxy, Runnable runnable); private static native void nDestroyCanvasAndSurface(long nativeProxy); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index e246c4f..65b1f8c 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -431,7 +431,7 @@ import java.util.concurrent.atomic.AtomicInteger; * child. The child must use this size, and guarantee that all of its * descendants will fit within this size. * <li>AT_MOST: This is used by the parent to impose a maximum size on the - * child. The child must gurantee that it and all of its descendants will fit + * child. The child must guarantee that it and all of its descendants will fit * within this size. * </ul> * </p> @@ -5377,8 +5377,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Gets the location of this view in screen coordintates. * * @param outRect The output location + * @hide */ - void getBoundsOnScreen(Rect outRect) { + public void getBoundsOnScreen(Rect outRect) { if (mAttachInfo == null) { return; } @@ -7648,7 +7649,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * notification is at at most once every * {@link ViewConfiguration#getSendRecurringAccessibilityEventsInterval()} * to avoid unnecessary load to the system. Also once a view has a pending - * notifucation this method is a NOP until the notification has been sent. + * notification this method is a NOP until the notification has been sent. * * @hide */ @@ -9670,7 +9671,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * The transform matrix of this view, which is calculated based on the current - * roation, scale, and pivot properties. + * rotation, scale, and pivot properties. * * @see #getRotation() * @see #getScaleX() @@ -10521,13 +10522,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, setTranslationZ(z - getElevation()); } + /** + * The base elevation of this view relative to its parent, in pixels. + * + * @return The base depth position of the view, in pixels. + */ @ViewDebug.ExportedProperty(category = "drawing") public float getElevation() { return mRenderNode.getElevation(); } /** - * Sets the base depth location of this view. + * Sets the base elevation of this view, in pixels. * * @attr ref android.R.styleable#View_elevation */ @@ -13732,6 +13738,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; } + renderNode.setScrollPosition(mScrollX, mScrollY); if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || !renderNode.isValid() || (!isLayer && mRecreateDisplayList)) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 0f40ee7..02011e0 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4530,6 +4530,28 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } /** + * Native-calculated damage path + * Returns false if this path was unable to complete successfully. This means + * it hit a ViewParent it doesn't recognize and needs to fall back to calculating + * damage area + * @hide + */ + public boolean damageChildDeferred(View child) { + ViewParent parent = getParent(); + while (parent != null) { + if (parent instanceof ViewGroup) { + parent = parent.getParent(); + } else if (parent instanceof ViewRootImpl) { + ((ViewRootImpl) parent).invalidate(); + return true; + } else { + parent = null; + } + } + return false; + } + + /** * Quick invalidation method called by View.invalidateViewProperty. This doesn't set the * DRAWN flags and doesn't handle the Animation logic that the default invalidation methods * do; all we want to do here is schedule a traversal with the appropriate dirty rect. @@ -4537,6 +4559,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * @hide */ public void damageChild(View child, final Rect dirty) { + if (damageChildDeferred(child)) { + return; + } + ViewParent parent = this; final AttachInfo attachInfo = mAttachInfo; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index f3d1e3c..76d5038 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -181,7 +181,6 @@ public final class ViewRootImpl implements ViewParent, int mWidth; int mHeight; Rect mDirty; - final Rect mCurrentDirty = new Rect(); boolean mIsAnimating; CompatibilityInfo.Translator mTranslator; @@ -861,7 +860,9 @@ public final class ViewRootImpl implements ViewParent, void invalidate() { mDirty.set(0, 0, mWidth, mHeight); - scheduleTraversals(); + if (!mWillDrawSoon) { + scheduleTraversals(); + } } void invalidateWorld(View view) { @@ -2436,12 +2437,10 @@ public final class ViewRootImpl implements ViewParent, mHardwareYOffset = yoff; mResizeAlpha = resizeAlpha; - mCurrentDirty.set(dirty); dirty.setEmpty(); mBlockResizeBuffer = false; - attachInfo.mHardwareRenderer.draw(mView, attachInfo, this, - animating ? null : mCurrentDirty); + attachInfo.mHardwareRenderer.draw(mView, attachInfo, this); } else { // If we get here with a disabled & requested hardware renderer, something went // wrong (an invalidate posted right before we destroyed the hardware surface diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index b4779f4..0ebf2e1 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -147,9 +147,14 @@ public final class WindowManagerGlobal { InputMethodManager imm = InputMethodManager.getInstance(); IWindowManager windowManager = getWindowManagerService(); sWindowSession = windowManager.openSession( + new IWindowSessionCallback.Stub() { + @Override + public void onAnimatorScaleChanged(float scale) { + ValueAnimator.setDurationScale(scale); + } + }, imm.getClient(), imm.getInputContext()); - float animatorScale = windowManager.getAnimationScale(2); - ValueAnimator.setDurationScale(animatorScale); + ValueAnimator.setDurationScale(windowManager.getCurrentAnimatorScale()); } catch (RemoteException e) { Log.e(TAG, "Failed to open window session", e); } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 0693617..ace8808 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -320,6 +320,25 @@ public final class InputMethodManager { int mCursorCandEnd; /** + * Represents an invalid action notification sequence number. {@link InputMethodManagerService} + * always issues a positive integer for action notification sequence numbers. Thus -1 is + * guaranteed to be different from any valid sequence number. + */ + private static final int NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER = -1; + /** + * The next sequence number that is to be sent to {@link InputMethodManagerService} via + * {@link IInputMethodManager#notifyUserAction(int)} at once when a user action is observed. + */ + private int mNextUserActionNotificationSequenceNumber = + NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; + + /** + * The last sequence number that is already sent to {@link InputMethodManagerService}. + */ + private int mLastSentUserActionNotificationSequenceNumber = + NOT_AN_ACTION_NOTIFICATION_SEQUENCE_NUMBER; + + /** * The instance that has previously been sent to the input method. */ private CursorAnchorInfo mCursorAnchorInfo = null; @@ -364,6 +383,7 @@ public final class InputMethodManager { static final int MSG_TIMEOUT_INPUT_EVENT = 6; static final int MSG_FLUSH_INPUT_EVENT = 7; static final int MSG_SET_CURSOR_ANCHOR_MONITOR_MODE = 8; + static final int MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER = 9; class H extends Handler { H(Looper looper) { @@ -503,6 +523,11 @@ public final class InputMethodManager { } return; } + case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER: { + synchronized (mH) { + mNextUserActionNotificationSequenceNumber = msg.arg1; + } + } } } } @@ -572,6 +597,12 @@ public final class InputMethodManager { public void setCursorAnchorMonitorMode(int monitorMode) { mH.sendMessage(mH.obtainMessage(MSG_SET_CURSOR_ANCHOR_MONITOR_MODE, monitorMode, 0)); } + + @Override + public void setUserActionNotificationSequenceNumber(int sequenceNumber) { + mH.sendMessage(mH.obtainMessage(MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER, + sequenceNumber, 0)); + } }; final InputConnection mDummyInputConnection = new BaseInputConnection(this, false); @@ -1214,6 +1245,8 @@ public final class InputMethodManager { mBindSequence = res.sequence; mCurMethod = res.method; mCurId = res.id; + mNextUserActionNotificationSequenceNumber = + res.userActionNotificationSequenceNumber; } else { if (res.channel != null && res.channel != mCurChannel) { res.channel.dispose(); @@ -1918,8 +1951,28 @@ public final class InputMethodManager { */ public void notifyUserAction() { synchronized (mH) { + if (mLastSentUserActionNotificationSequenceNumber == + mNextUserActionNotificationSequenceNumber) { + if (DEBUG) { + Log.w(TAG, "Ignoring notifyUserAction as it has already been sent." + + " mLastSentUserActionNotificationSequenceNumber: " + + mLastSentUserActionNotificationSequenceNumber + + " mNextUserActionNotificationSequenceNumber: " + + mNextUserActionNotificationSequenceNumber); + } + return; + } try { - mService.notifyUserAction(); + if (DEBUG) { + Log.w(TAG, "notifyUserAction: " + + " mLastSentUserActionNotificationSequenceNumber: " + + mLastSentUserActionNotificationSequenceNumber + + " mNextUserActionNotificationSequenceNumber: " + + mNextUserActionNotificationSequenceNumber); + } + mService.notifyUserAction(mNextUserActionNotificationSequenceNumber); + mLastSentUserActionNotificationSequenceNumber = + mNextUserActionNotificationSequenceNumber; } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId, e); } @@ -2103,6 +2156,10 @@ public final class InputMethodManager { + " mCursorSelEnd=" + mCursorSelEnd + " mCursorCandStart=" + mCursorCandStart + " mCursorCandEnd=" + mCursorCandEnd); + p.println(" mNextUserActionNotificationSequenceNumber=" + + mNextUserActionNotificationSequenceNumber + + " mLastSentUserActionNotificationSequenceNumber=" + + mLastSentUserActionNotificationSequenceNumber); } /** diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index bb74c44..883183e 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -317,13 +317,13 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { final Resources res = getResources(); mAmPmUnselectedColor = a.getColor(R.styleable.TimePicker_amPmUnselectedBackgroundColor, - res.getColor(R.color.timepicker_default_ampm_unselected_background_color_quantum)); + res.getColor(R.color.timepicker_default_ampm_unselected_background_color_material)); mAmPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor, - res.getColor(R.color.timepicker_default_ampm_selected_background_color_quantum)); + res.getColor(R.color.timepicker_default_ampm_selected_background_color_material)); mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor, - res.getColor(R.color.timepicker_default_text_color_quantum)); + res.getColor(R.color.timepicker_default_text_color_material)); mTypeface = Typeface.create("sans-serif", Typeface.NORMAL); @@ -338,7 +338,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { } final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor, - res.getColor(R.color.timepicker_default_text_color_quantum)); + res.getColor(R.color.timepicker_default_text_color_material)); mPaint[HOURS] = new Paint(); mPaint[HOURS].setAntiAlias(true); @@ -358,39 +358,39 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true); mColorSelector[HOURS][SELECTOR_CIRCLE] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintSelector[HOURS][SELECTOR_DOT] = new Paint(); mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true); mColorSelector[HOURS][SELECTOR_DOT] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintSelector[HOURS][SELECTOR_LINE] = new Paint(); mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2); mColorSelector[HOURS][SELECTOR_LINE] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true); mColorSelector[MINUTES][SELECTOR_CIRCLE] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint(); mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true); mColorSelector[MINUTES][SELECTOR_DOT] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2); mColorSelector[MINUTES][SELECTOR_LINE] = a.getColor( R.styleable.TimePicker_numbersSelectorColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); mPaintAmPmText.setColor(mAmPmTextColor); mPaintAmPmText.setTypeface(mTypeface); @@ -403,11 +403,11 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { mPaintAmPmCircle[PM].setAntiAlias(true); mPaintBackground.setColor(a.getColor(R.styleable.TimePicker_numbersBackgroundColor, - res.getColor(R.color.timepicker_default_numbers_background_color_quantum))); + res.getColor(R.color.timepicker_default_numbers_background_color_material))); mPaintBackground.setAntiAlias(true); mPaintDisabled.setColor(a.getColor(R.styleable.TimePicker_disabledColor, - res.getColor(R.color.timepicker_default_disabled_color_quantum))); + res.getColor(R.color.timepicker_default_disabled_color_material))); mPaintDisabled.setAntiAlias(true); if (DEBUG) { diff --git a/core/java/android/widget/TimePickerDelegate.java b/core/java/android/widget/TimePickerDelegate.java index ba93ee5..bf3971c 100644 --- a/core/java/android/widget/TimePickerDelegate.java +++ b/core/java/android/widget/TimePickerDelegate.java @@ -140,12 +140,12 @@ class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implement mSelectMinutes = res.getString(R.string.select_minutes); mHeaderSelectedColor = a.getColor(R.styleable.TimePicker_headerSelectedTextColor, - R.color.timepicker_default_selector_color_quantum); + R.color.timepicker_default_selector_color_material); - mHeaderUnSelectedColor = getUnselectedColor(R.color.timepicker_default_text_color_quantum); + mHeaderUnSelectedColor = getUnselectedColor(R.color.timepicker_default_text_color_material); if (mHeaderUnSelectedColor == -1) { mHeaderUnSelectedColor = a.getColor(R.styleable.TimePicker_headerUnselectedTextColor, - R.color.timepicker_default_text_color_quantum); + R.color.timepicker_default_text_color_material); } final int headerBackgroundColor = a.getColor( @@ -295,7 +295,7 @@ class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implement TypedArray a = mContext.obtainStyledAttributes(TEXT_APPEARANCE_TIME_LABEL_ATTR); final int textAppearanceResId = a.getResourceId(0, 0); tempView.setTextAppearance(mContext, (textAppearanceResId != 0) ? - textAppearanceResId : R.style.TextAppearance_Quantum_TimePicker_TimeLabel); + textAppearanceResId : R.style.TextAppearance_Material_TimePicker_TimeLabel); a.recycle(); ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java index 7edf4cc..c977997 100644 --- a/core/java/com/android/internal/os/SomeArgs.java +++ b/core/java/com/android/internal/os/SomeArgs.java @@ -45,6 +45,7 @@ public final class SomeArgs { public Object arg3; public Object arg4; public Object arg5; + public Object arg6; public int argi1; public int argi2; public int argi3; @@ -95,6 +96,7 @@ public final class SomeArgs { arg3 = null; arg4 = null; arg5 = null; + arg6 = null; argi1 = 0; argi2 = 0; argi3 = 0; diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java index f38cbde..665055c 100644 --- a/core/java/com/android/internal/util/NotificationColorUtil.java +++ b/core/java/com/android/internal/util/NotificationColorUtil.java @@ -35,7 +35,7 @@ import java.util.Arrays; import java.util.WeakHashMap; /** - * Helper class to process legacy (Holo) notifications to make them look like quantum notifications. + * Helper class to process legacy (Holo) notifications to make them look like material notifications. * * @hide */ diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl index 9e8d12b..b100d27 100644 --- a/core/java/com/android/internal/view/IInputMethodClient.aidl +++ b/core/java/com/android/internal/view/IInputMethodClient.aidl @@ -28,4 +28,5 @@ oneway interface IInputMethodClient { void onUnbindMethod(int sequence); void setActive(boolean active); void setCursorAnchorMonitorMode(int monitorMode); + void setUserActionNotificationSequenceNumber(int sequenceNumber); } diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl index 4590520..b84c359 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -77,6 +77,6 @@ interface IInputMethodManager { boolean setInputMethodEnabled(String id, boolean enabled); void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes); int getInputMethodWindowVisibleHeight(); - oneway void notifyUserAction(); + oneway void notifyUserAction(int sequenceNumber); void setCursorAnchorMonitorMode(in IBinder token, int monitorMode); } diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java index 14afe21..3a3e56d 100644 --- a/core/java/com/android/internal/view/InputBindResult.java +++ b/core/java/com/android/internal/view/InputBindResult.java @@ -47,13 +47,19 @@ public final class InputBindResult implements Parcelable { * Sequence number of this binding. */ public final int sequence; - + + /** + * Sequence number of user action notification. + */ + public final int userActionNotificationSequenceNumber; + public InputBindResult(IInputMethodSession _method, InputChannel _channel, - String _id, int _sequence) { + String _id, int _sequence, int _userActionNotificationSequenceNumber) { method = _method; channel = _channel; id = _id; sequence = _sequence; + userActionNotificationSequenceNumber = _userActionNotificationSequenceNumber; } InputBindResult(Parcel source) { @@ -65,12 +71,15 @@ public final class InputBindResult implements Parcelable { } id = source.readString(); sequence = source.readInt(); + userActionNotificationSequenceNumber = source.readInt(); } @Override public String toString() { return "InputBindResult{" + method + " " + id - + " #" + sequence + "}"; + + " sequence:" + sequence + + " userActionNotificationSequenceNumber:" + userActionNotificationSequenceNumber + + "}"; } /** @@ -90,6 +99,7 @@ public final class InputBindResult implements Parcelable { } dest.writeString(id); dest.writeInt(sequence); + dest.writeInt(userActionNotificationSequenceNumber); } /** diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 7fe03f5..60e649b 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -291,14 +291,14 @@ public class LockPatternView extends View { mPathPaint.setStrokeCap(Paint.Cap.ROUND); // lot's of bitmaps! - // TODO: those bitmaps are hardcoded to the Quantum Theme which should not be the case! - mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default_qntm_alpha); - mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched_qntm_alpha); + // TODO: those bitmaps are hardcoded to the Material Theme which should not be the case! + mBitmapBtnDefault = getBitmapFor(R.drawable.btn_code_lock_default_mtrl_alpha); + mBitmapBtnTouched = getBitmapFor(R.drawable.btn_code_lock_touched_mtrl_alpha); mBitmapCircleDefault = getBitmapFor( - R.drawable.indicator_code_lock_point_area_default_qntm_alpha); - mBitmapCircleAlpha = getBitmapFor(R.drawable.indicator_code_lock_point_area_qntm_alpha); + R.drawable.indicator_code_lock_point_area_default_mtrl_alpha); + mBitmapCircleAlpha = getBitmapFor(R.drawable.indicator_code_lock_point_area_mtrl_alpha); mBitmapArrowAlphaUp = getBitmapFor( - R.drawable.indicator_code_lock_drag_direction_up_qntm_alpha); + R.drawable.indicator_code_lock_drag_direction_up_mtrl_alpha); // bitmaps have the size of the largest bitmap in this group final Bitmap bitmaps[] = { mBitmapBtnDefault, mBitmapBtnTouched, mBitmapCircleDefault, |
