diff options
Diffstat (limited to 'core/java/android')
32 files changed, 854 insertions, 488 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 2620c44..cbc8150 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -462,7 +462,9 @@ public abstract class AccessibilityService extends Service { * anything behind it, then only the modal window will be reported * (assuming it is the top one). For convenience the returned windows * are ordered in a descending layer order, which is the windows that - * are higher in the Z-order are reported first. + * are higher in the Z-order are reported first. Since the user can always + * interact with the window that has input focus by typing, the focused + * window is always returned (even if covered by a modal window). * <p> * <strong>Note:</strong> In order to access the windows your service has * to declare the capability to retrieve window content by setting the diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 4f9ba59..4edb0c6 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -286,8 +286,8 @@ public class AccessibilityServiceInfo implements Parcelable { /** * This flag indicates to the system that the accessibility service wants * to access content of all interactive windows. An interactive window is a - * window that can be touched by a sighted user when explore by touch is not - * enabled. If this flag is not set your service will not receive + * window that has input focus or can be touched by a sighted user when explore + * by touch is not enabled. If this flag is not set your service will not receive * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED} * events, calling AccessibilityService{@link AccessibilityService#getWindows() * AccessibilityService.getWindows()} will return an empty list, and {@link diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index 933135d..06f5aca 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -17,6 +17,7 @@ package android.animation; import android.content.Context; import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.content.res.Resources.NotFoundException; @@ -25,6 +26,9 @@ import android.util.StateSet; import android.util.TypedValue; import android.util.Xml; import android.view.animation.AnimationUtils; + +import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -66,11 +70,26 @@ public class AnimatorInflater { */ public static Animator loadAnimator(Context context, int id) throws NotFoundException { + return loadAnimator(context.getResources(), context.getTheme(), id); + } + + /** + * Loads an {@link Animator} object from a resource + * + * @param resources The resources + * @param theme The theme + * @param id The resource id of the animation to load + * @return The animator object reference by the specified id + * @throws android.content.res.Resources.NotFoundException when the animation cannot be loaded + * @hide + */ + public static Animator loadAnimator(Resources resources, Theme theme, int id) + throws NotFoundException { XmlResourceParser parser = null; try { - parser = context.getResources().getAnimation(id); - return createAnimatorFromXml(context, parser); + parser = resources.getAnimation(id); + return createAnimatorFromXml(resources, theme, parser); } catch (XmlPullParserException ex) { Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + @@ -150,7 +169,8 @@ public class AnimatorInflater { } if (animator == null) { - animator = createAnimatorFromXml(context, parser); + animator = createAnimatorFromXml(context.getResources(), + context.getTheme(), parser); } if (animator == null) { @@ -166,103 +186,8 @@ public class AnimatorInflater { } } - private static Animator createAnimatorFromXml(Context c, XmlPullParser parser) - throws XmlPullParserException, IOException { - return createAnimatorFromXml(c, parser, Xml.asAttributeSet(parser), null, 0); - } - - private static Animator createAnimatorFromXml(Context c, XmlPullParser parser, - AttributeSet attrs, AnimatorSet parent, int sequenceOrdering) - throws XmlPullParserException, IOException { - - Animator anim = null; - ArrayList<Animator> childAnims = null; - - // Make sure we are on a start tag. - int type; - int depth = parser.getDepth(); - - while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) - && type != XmlPullParser.END_DOCUMENT) { - - if (type != XmlPullParser.START_TAG) { - continue; - } - - String name = parser.getName(); - - if (name.equals("objectAnimator")) { - anim = loadObjectAnimator(c, attrs); - } else if (name.equals("animator")) { - anim = loadAnimator(c, attrs, null); - } else if (name.equals("set")) { - anim = new AnimatorSet(); - TypedArray a = c.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.AnimatorSet); - int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering, - TOGETHER); - createAnimatorFromXml(c, parser, attrs, (AnimatorSet) anim, ordering); - a.recycle(); - } else { - throw new RuntimeException("Unknown animator name: " + parser.getName()); - } - - if (parent != null) { - if (childAnims == null) { - childAnims = new ArrayList<Animator>(); - } - childAnims.add(anim); - } - } - if (parent != null && childAnims != null) { - Animator[] animsArray = new Animator[childAnims.size()]; - int index = 0; - for (Animator a : childAnims) { - animsArray[index++] = a; - } - if (sequenceOrdering == TOGETHER) { - parent.playTogether(animsArray); - } else { - parent.playSequentially(animsArray); - } - } - - return anim; - - } - - private static ObjectAnimator loadObjectAnimator(Context context, AttributeSet attrs) - throws NotFoundException { - - ObjectAnimator anim = new ObjectAnimator(); - - loadAnimator(context, attrs, anim); - - TypedArray a = - context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.PropertyAnimator); - - String propertyName = a.getString(com.android.internal.R.styleable.PropertyAnimator_propertyName); - - anim.setPropertyName(propertyName); - - a.recycle(); - - return anim; - } - - /** - * Creates a new animation whose parameters come from the specified context and - * attributes set. - * - * @param context the application environment - * @param attrs the set of attributes holding the animation parameters - */ - private static ValueAnimator loadAnimator(Context context, AttributeSet attrs, ValueAnimator anim) - throws NotFoundException { - - TypedArray a = - context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Animator); + private static void parseAnimatorFromTypeArray(ValueAnimator anim, TypedArray a) { long duration = a.getInt(com.android.internal.R.styleable.Animator_duration, 300); long startDelay = a.getInt(com.android.internal.R.styleable.Animator_startOffset, 0); @@ -378,11 +303,123 @@ public class AnimatorInflater { if (evaluator != null) { anim.setEvaluator(evaluator); } + } + + private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser) + throws XmlPullParserException, IOException { + return createAnimatorFromXml(res, theme, parser, Xml.asAttributeSet(parser), null, 0); + } + + private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, + AttributeSet attrs, AnimatorSet parent, int sequenceOrdering) + throws XmlPullParserException, IOException { + + Animator anim = null; + ArrayList<Animator> childAnims = null; + + // Make sure we are on a start tag. + int type; + int depth = parser.getDepth(); + + while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { + + if (type != XmlPullParser.START_TAG) { + continue; + } + + String name = parser.getName(); + + if (name.equals("objectAnimator")) { + anim = loadObjectAnimator(res, theme, attrs); + } else if (name.equals("animator")) { + anim = loadAnimator(res, theme, attrs, null); + } else if (name.equals("set")) { + anim = new AnimatorSet(); + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AnimatorSet, 0, 0); + } else { + a = res.obtainAttributes(attrs, com.android.internal.R.styleable.AnimatorSet); + } + int ordering = a.getInt(com.android.internal.R.styleable.AnimatorSet_ordering, + TOGETHER); + createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering); + a.recycle(); + } else { + throw new RuntimeException("Unknown animator name: " + parser.getName()); + } + + if (parent != null) { + if (childAnims == null) { + childAnims = new ArrayList<Animator>(); + } + childAnims.add(anim); + } + } + if (parent != null && childAnims != null) { + Animator[] animsArray = new Animator[childAnims.size()]; + int index = 0; + for (Animator a : childAnims) { + animsArray[index++] = a; + } + if (sequenceOrdering == TOGETHER) { + parent.playTogether(animsArray); + } else { + parent.playSequentially(animsArray); + } + } + + return anim; + + } + + private static ObjectAnimator loadObjectAnimator(Resources res, Theme theme, AttributeSet attrs) + throws NotFoundException { + ObjectAnimator anim = new ObjectAnimator(); + + loadAnimator(res, theme, attrs, anim); + + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.PropertyAnimator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.PropertyAnimator); + } + + String propertyName = a.getString(R.styleable.PropertyAnimator_propertyName); + + anim.setPropertyName(propertyName); + + a.recycle(); + + return anim; + } + + /** + * Creates a new animation whose parameters come from the specified context + * and attributes set. + * + * @param res The resources + * @param attrs The set of attributes holding the animation parameters + */ + private static ValueAnimator loadAnimator(Resources res, Theme theme, + AttributeSet attrs, ValueAnimator anim) + throws NotFoundException { + + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.Animator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.Animator); + } + + parseAnimatorFromTypeArray(anim, a); final int resID = a.getResourceId(com.android.internal.R.styleable.Animator_interpolator, 0); if (resID > 0) { - anim.setInterpolator(AnimationUtils.loadInterpolator(context, resID)); + anim.setInterpolator(AnimationUtils.loadInterpolator(res, theme, resID)); } a.recycle(); diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 1015514..45a2625 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -222,6 +222,12 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * Called after the administrator is first enabled, as a result of * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}. At this point you * can use {@link DevicePolicyManager} to set your desired policies. + * + * <p> If the admin is activated by a device owner, then the intent + * may contain private extras that are relevant to user setup. + * {@see DevicePolicyManager#createAndInitializeUser(ComponentName, String, String, + * ComponentName, Intent)} + * * @param context The running context as per {@link #onReceive}. * @param intent The received intent as per {@link #onReceive}. */ diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 04be028..e80c761 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2111,6 +2111,41 @@ public class DevicePolicyManager { } /** + * Called by a device owner to create a user with the specified name. The UserHandle returned + * by this method should not be persisted as user handles are recycled as users are removed and + * created. If you need to persist an identifier for this user, use + * {@link UserManager#getSerialNumberForUser}. The new user will be started in the background + * immediately. + * + * <p> profileOwnerComponent is the {@link DeviceAdminReceiver} to be the profile owner as well + * as registered as an active admin on the new user. The profile owner package will be + * installed on the new user if it already is installed on the device. + * + * <p>If the optionalInitializeData is not null, then the extras will be passed to the + * profileOwnerComponent when onEnable is called. + * + * @param admin Which {@link DeviceAdminReceiver} this request is associated with. + * @param name the user's name + * @param ownerName the human readable name of the organisation associated with this DPM. + * @param profileOwnerComponent The {@link DeviceAdminReceiver} that will be an active admin on + * the user. + * @param adminExtras Extras that will be passed to onEnable of the admin receiver + * on the new user. + * @see UserHandle + * @return the UserHandle object for the created user, or null if the user could not be created. + */ + public UserHandle createAndInitializeUser(ComponentName admin, String name, String ownerName, + ComponentName profileOwnerComponent, Bundle adminExtras) { + try { + return mService.createAndInitializeUser(admin, name, ownerName, profileOwnerComponent, + adminExtras); + } catch (RemoteException re) { + Log.w(TAG, "Could not create a user", re); + } + return null; + } + + /** * Called by a device owner to remove a user and all associated data. The primary user can * not be removed. * diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index f8df780..a1caa21 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -136,6 +136,7 @@ interface IDevicePolicyManager { boolean isApplicationBlocked(in ComponentName admin, in String packageName); UserHandle createUser(in ComponentName who, in String name); + UserHandle createAndInitializeUser(in ComponentName who, in String name, in String profileOwnerName, in ComponentName profileOwnerComponent, in Bundle adminExtras); boolean removeUser(in ComponentName who, in UserHandle userHandle); void setAccountManagementDisabled(in ComponentName who, in String accountType, in boolean disabled); diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 04c0b9f..69fa408 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -67,7 +67,6 @@ public class LauncherApps { * * @param user The UserHandle of the profile that generated the change. * @param packageName The name of the package that was removed. - * @hide remove before ship */ void onPackageRemoved(UserHandle user, String packageName); @@ -76,7 +75,6 @@ public class LauncherApps { * * @param user The UserHandle of the profile that generated the change. * @param packageName The name of the package that was added. - * @hide remove before ship */ void onPackageAdded(UserHandle user, String packageName); @@ -85,7 +83,6 @@ public class LauncherApps { * * @param user The UserHandle of the profile that generated the change. * @param packageName The name of the package that has changed. - * @hide remove before ship */ void onPackageChanged(UserHandle user, String packageName); @@ -99,7 +96,6 @@ public class LauncherApps { * available. * @param replacing Indicates whether these packages are replacing * existing ones. - * @hide remove before ship */ void onPackagesAvailable(UserHandle user, String[] packageNames, boolean replacing); @@ -113,59 +109,9 @@ public class LauncherApps { * unavailable. * @param replacing Indicates whether the packages are about to be * replaced with new versions. - * @hide remove before ship */ void onPackagesUnavailable(UserHandle user, String[] packageNames, boolean replacing); - /** - * Indicates that a package was removed from the specified profile. - * - * @param packageName The name of the package that was removed. - * @param user The UserHandle of the profile that generated the change. - */ - void onPackageRemoved(String packageName, UserHandle user); - - /** - * Indicates that a package was added to the specified profile. - * - * @param packageName The name of the package that was added. - * @param user The UserHandle of the profile that generated the change. - */ - void onPackageAdded(String packageName, UserHandle user); - - /** - * Indicates that a package was modified in the specified profile. - * - * @param packageName The name of the package that has changed. - * @param user The UserHandle of the profile that generated the change. - */ - void onPackageChanged(String packageName, UserHandle user); - - /** - * Indicates that one or more packages have become available. For - * example, this can happen when a removable storage card has - * reappeared. - * - * @param packageNames The names of the packages that have become - * available. - * @param user The UserHandle of the profile that generated the change. - * @param replacing Indicates whether these packages are replacing - * existing ones. - */ - void onPackagesAvailable(String [] packageNames, UserHandle user, boolean replacing); - - /** - * Indicates that one or more packages have become unavailable. For - * example, this can happen when a removable storage card has been - * removed. - * - * @param packageNames The names of the packages that have become - * unavailable. - * @param user The UserHandle of the profile that generated the change. - * @param replacing Indicates whether the packages are about to be - * replaced with new versions. - */ - void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing); } /** @hide */ @@ -361,8 +307,7 @@ public class LauncherApps { } synchronized (LauncherApps.this) { for (OnAppsChangedListener listener : mListeners) { - listener.onPackageRemoved(user, packageName); // TODO: Remove before ship - listener.onPackageRemoved(packageName, user); + listener.onPackageRemoved(user, packageName); } } } @@ -374,8 +319,7 @@ public class LauncherApps { } synchronized (LauncherApps.this) { for (OnAppsChangedListener listener : mListeners) { - listener.onPackageChanged(user, packageName); // TODO: Remove before ship - listener.onPackageChanged(packageName, user); + listener.onPackageChanged(user, packageName); } } } @@ -387,8 +331,7 @@ public class LauncherApps { } synchronized (LauncherApps.this) { for (OnAppsChangedListener listener : mListeners) { - listener.onPackageAdded(user, packageName); // TODO: Remove before ship - listener.onPackageAdded(packageName, user); + listener.onPackageAdded(user, packageName); } } } @@ -401,8 +344,7 @@ public class LauncherApps { } synchronized (LauncherApps.this) { for (OnAppsChangedListener listener : mListeners) { - listener.onPackagesAvailable(user, packageNames, replacing); // TODO: Remove - listener.onPackagesAvailable(packageNames, user, replacing); + listener.onPackagesAvailable(user, packageNames, replacing); } } } @@ -415,8 +357,7 @@ public class LauncherApps { } synchronized (LauncherApps.this) { for (OnAppsChangedListener listener : mListeners) { - listener.onPackagesUnavailable(user, packageNames, replacing); // TODO: Remove - listener.onPackagesUnavailable(packageNames, user, replacing); + listener.onPackagesUnavailable(user, packageNames, replacing); } } } diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index 68f4d64..77d0c41 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -190,22 +190,18 @@ public abstract class CameraDevice implements AutoCloseable { * Then obtain the Surface with * {@link android.renderscript.Allocation#getSurface}.</li> * - * <li>For access to raw, uncompressed or JPEG data in the application: Create a - * {@link android.media.ImageReader} object with the one of the supported - * {@link StreamConfigurationMap#getOutputFormats() output image formats}, and a - * size from the supported - * {@link StreamConfigurationMap#getOutputSizes(int) sizes for that format}. Then obtain - * a Surface from it with {@link android.media.ImageReader#getSurface}.</li> + * <li>For access to raw, uncompressed JPEG data in the application: Create an + * {@link android.media.ImageReader} object with one of the supported output formats given by + * {@link StreamConfigurationMap#getOutputFormats()}, setting its size to one of the + * corresponding supported sizes by passing the chosen output format into + * {@link StreamConfigurationMap#getOutputSizes(int)}. Then obtain a + * {@link android.view.Surface} from it with {@link android.media.ImageReader#getSurface()}. + * </li> * * </ul> * - * </p> - * * <p>The camera device will query each Surface's size and formats upon this - * call, so they must be set to a valid setting at this time (in particular: - * if the format is user-visible, it must be one of - * {@link StreamConfigurationMap#getOutputFormats}; and the size must be one of - * {@link StreamConfigurationMap#getOutputSizes(int)}).</p> + * call, so they must be set to a valid setting at this time.</p> * * <p>It can take several hundred milliseconds for the session's configuration to complete, * since camera hardware may need to be powered on or reconfigured. Once the configuration is diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.aidl b/core/java/android/hardware/hdmi/HdmiPortInfo.aidl new file mode 100644 index 0000000..157b5b3 --- /dev/null +++ b/core/java/android/hardware/hdmi/HdmiPortInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.hardware.hdmi; + +parcelable HdmiPortInfo; diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.java b/core/java/android/hardware/hdmi/HdmiPortInfo.java new file mode 100644 index 0000000..7b25f8a --- /dev/null +++ b/core/java/android/hardware/hdmi/HdmiPortInfo.java @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.hardware.hdmi; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A class to encapsulate HDMI port information. Contains the capability of the ports such as + * HDMI-CEC, MHL, ARC(Audio Return Channel), and physical address assigned to each port. + * + * @hide + */ +@SystemApi +public final class HdmiPortInfo implements Parcelable { + /** HDMI port type: Input */ + public static final int PORT_INPUT = 0; + + /** HDMI port type: Output */ + public static final int PORT_OUTPUT = 1; + + private final int mId; + private final int mType; + private final int mAddress; + private final boolean mCecSupported; + private final boolean mArcSupported; + private final boolean mMhlSupported; + + /** + * Constructor. + * + * @param id identifier assigned to each port. 1 for HDMI port 1 + * @param type HDMI port input/output type + * @param address physical address of the port + * @param cec {@code true} if HDMI-CEC is supported on the port + * @param mhl {@code true} if MHL is supported on the port + * @param arc {@code true} if audio return channel is supported on the port + */ + public HdmiPortInfo(int id, int type, int address, boolean cec, boolean mhl, boolean arc) { + mId = id; + mType = type; + mAddress = address; + mCecSupported = cec; + mArcSupported = arc; + mMhlSupported = mhl; + } + + /** + * Returns the port id. + * + * @return port id + */ + public int getId() { + return mId; + } + + /** + * Returns the port type. + * + * @return port type + */ + public int getType() { + return mType; + } + + /** + * Returns the port address. + * + * @return port address + */ + public int getAddress() { + return mAddress; + } + + /** + * Returns {@code true} if the port supports HDMI-CEC signaling. + * + * @return {@code true} if the port supports HDMI-CEC signaling. + */ + public boolean isCecSupported() { + return mCecSupported; + } + + /** + * Returns {@code true} if the port supports MHL signaling. + * + * @return {@code true} if the port supports MHL signaling. + */ + public boolean isMhlSupported() { + return mMhlSupported; + } + + /** + * Returns {@code true} if the port supports audio return channel. + * + * @return {@code true} if the port supports audio return channel + */ + public boolean isArcSupported() { + return mArcSupported; + } + + /** + * Describe the kinds of special objects contained in this Parcelable's + * marshalled representation. + */ + @Override + public int describeContents() { + return 0; + } + + + /** + * A helper class to deserialize {@link HdmiPortInfo} for a parcel. + */ + public static final Parcelable.Creator<HdmiPortInfo> CREATOR = + new Parcelable.Creator<HdmiPortInfo>() { + @Override + public HdmiPortInfo createFromParcel(Parcel source) { + int id = source.readInt(); + int type = source.readInt(); + int address = source.readInt(); + boolean cec = (source.readInt() == 1); + boolean arc = (source.readInt() == 1); + boolean mhl = (source.readInt() == 1); + return new HdmiPortInfo(id, type, address, cec, arc, mhl); + } + + @Override + public HdmiPortInfo[] newArray(int size) { + return new HdmiPortInfo[size]; + } + }; + + /** + * Serialize this object into a {@link Parcel}. + * + * @param dest The Parcel in which the object should be written. + * @param flags Additional flags about how the object should be written. + * May be 0 or {@link Parcelable#PARCELABLE_WRITE_RETURN_VALUE}. + */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mId); + dest.writeInt(mType); + dest.writeInt(mAddress); + dest.writeInt(mCecSupported ? 1 : 0); + dest.writeInt(mArcSupported ? 1 : 0); + dest.writeInt(mMhlSupported ? 1 : 0); + } +} diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java index 6dc4a4f..85af3d1 100644 --- a/core/java/android/hardware/hdmi/HdmiTvClient.java +++ b/core/java/android/hardware/hdmi/HdmiTvClient.java @@ -16,6 +16,8 @@ package android.hardware.hdmi; import android.annotation.SystemApi; +import android.os.RemoteException; +import android.util.Log; /** * HdmiTvClient represents HDMI-CEC logical device of type TV in the Android system @@ -33,4 +35,46 @@ public final class HdmiTvClient { HdmiTvClient(IHdmiControlService service) { mService = service; } + + // Factory method for HdmiTvClient. + // Declared package-private. Accessed by HdmiControlManager only. + static HdmiTvClient create(IHdmiControlService service) { + return new HdmiTvClient(service); + } + + /** + * Callback interface used to get the result of {@link #deviceSelect}. + */ + public interface SelectCallback { + /** + * Called when the operation is finished. + * + * @param result the result value of {@link #deviceSelect} + */ + void onComplete(int result); + } + + /** + * Select a CEC logical device to be a new active source. + * + * @param logicalAddress + * @param callback + */ + public void deviceSelect(int logicalAddress, SelectCallback callback) { + // TODO: Replace SelectCallback with PartialResult. + try { + mService.deviceSelect(logicalAddress, getCallbackWrapper(callback)); + } catch (RemoteException e) { + Log.e(TAG, "failed to select device: ", e); + } + } + + private static IHdmiControlCallback getCallbackWrapper(final SelectCallback callback) { + return new IHdmiControlCallback.Stub() { + @Override + public void onComplete(int result) { + callback.onComplete(result); + } + }; + } } diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index 8da38e1..8d7c638 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -33,4 +33,5 @@ interface IHdmiControlService { void queryDisplayStatus(IHdmiControlCallback callback); void addHotplugEventListener(IHdmiHotplugEventListener listener); void removeHotplugEventListener(IHdmiHotplugEventListener listener); + void deviceSelect(int logicalAddress, IHdmiControlCallback callback); } diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index ff90e78..ba31243 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -868,10 +868,10 @@ public class ConnectivityManager { return -1; } - NetworkRequest request = removeRequestForFeature(netCap); - if (request != null) { + NetworkCallback networkCallback = removeRequestForFeature(netCap); + if (networkCallback != null) { Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature); - releaseNetworkRequest(request); + unregisterNetworkCallback(networkCallback); } return 1; } @@ -982,15 +982,15 @@ public class ConnectivityManager { int expireSequenceNumber; Network currentNetwork; int delay = -1; - NetworkCallbackListener networkCallbackListener = new NetworkCallbackListener() { + NetworkCallback networkCallback = new NetworkCallback() { @Override - public void onAvailable(NetworkRequest request, Network network) { + public void onAvailable(Network network) { currentNetwork = network; Log.d(TAG, "startUsingNetworkFeature got Network:" + network); setProcessDefaultNetworkForHostResolution(network); } @Override - public void onLost(NetworkRequest request, Network network) { + public void onLost(Network network) { if (network.equals(currentNetwork)) { currentNetwork = null; setProcessDefaultNetworkForHostResolution(null); @@ -1024,7 +1024,7 @@ public class ConnectivityManager { if (l == null) return; ourSeqNum = l.expireSequenceNumber; if (l.expireSequenceNumber == sequenceNum) { - releaseNetworkRequest(l.networkRequest); + unregisterNetworkCallback(l.networkCallback); sLegacyRequests.remove(netCap); } } @@ -1041,7 +1041,7 @@ public class ConnectivityManager { l.networkCapabilities = netCap; l.delay = delay; l.expireSequenceNumber = 0; - l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0, + l.networkRequest = sendRequestForNetwork(netCap, l.networkCallback, 0, REQUEST, type); if (l.networkRequest == null) return null; sLegacyRequests.put(netCap, l); @@ -1057,11 +1057,11 @@ public class ConnectivityManager { } } - private NetworkRequest removeRequestForFeature(NetworkCapabilities netCap) { + private NetworkCallback removeRequestForFeature(NetworkCapabilities netCap) { synchronized (sLegacyRequests) { LegacyRequest l = sLegacyRequests.remove(netCap); if (l == null) return null; - return l.networkRequest; + return l.networkCallback; } } @@ -1184,8 +1184,8 @@ public class ConnectivityManager { } /** - * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to - * find out when the current network has gone in to a high power state. + * Callback for use with {@link ConnectivityManager#registerDefaultNetworkActiveListener} + * to find out when the system default network has gone in to a high power state. */ public interface OnNetworkActiveListener { /** @@ -1194,7 +1194,7 @@ public class ConnectivityManager { * operations. Note that this listener only tells you when the network becomes * active; if at any other time you want to know whether it is active (and thus okay * to initiate network traffic), you can retrieve its instantaneous state with - * {@link ConnectivityManager#isNetworkActive}. + * {@link ConnectivityManager#isDefaultNetworkActive}. */ public void onNetworkActive(); } @@ -1215,13 +1215,18 @@ public class ConnectivityManager { = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>(); /** - * Start listening to reports when the data network is active, meaning it is - * a good time to perform network traffic. Use {@link #isNetworkActive()} - * to determine the current state of the network after registering the listener. + * Start listening to reports when the system's default data network is active, meaning it is + * a good time to perform network traffic. Use {@link #isDefaultNetworkActive()} + * to determine the current state of the system's default network after registering the + * listener. + * <p> + * If the process default network has been set with + * {@link ConnectivityManager#setProcessDefaultNetwork} this function will not + * reflect the process's default, but the system default. * * @param l The listener to be told when the network is active. */ - public void registerNetworkActiveListener(final OnNetworkActiveListener l) { + public void registerDefaultNetworkActiveListener(final OnNetworkActiveListener l) { INetworkActivityListener rl = new INetworkActivityListener.Stub() { @Override public void onNetworkActive() throws RemoteException { @@ -1238,11 +1243,11 @@ public class ConnectivityManager { /** * Remove network active listener previously registered with - * {@link #registerNetworkActiveListener}. + * {@link #registerDefaultNetworkActiveListener}. * * @param l Previously registered listener. */ - public void unregisterNetworkActiveListener(OnNetworkActiveListener l) { + public void unregisterDefaultNetworkActiveListener(OnNetworkActiveListener l) { INetworkActivityListener rl = mNetworkActivityListeners.get(l); if (rl == null) { throw new IllegalArgumentException("Listener not registered: " + l); @@ -1261,7 +1266,7 @@ public class ConnectivityManager { * this state. This method tells you whether right now is currently a good time to * initiate network traffic, as the network is already active. */ - public boolean isNetworkActive() { + public boolean isDefaultNetworkActive() { try { return getNetworkManagementService().isNetworkActive(); } catch (RemoteException e) { @@ -1893,7 +1898,7 @@ public class ConnectivityManager { * Base class for NetworkRequest callbacks. Used for notifications about network * changes. Should be extended by applications wanting notifications. */ - public static class NetworkCallbackListener { + public static class NetworkCallback { /** @hide */ public static final int PRECHECK = 1; /** @hide */ @@ -1916,78 +1921,68 @@ public class ConnectivityManager { * Called whenever the framework connects to a network that it may use to * satisfy this request */ - public void onPreCheck(NetworkRequest networkRequest, Network network) {} + public void onPreCheck(Network network) {} /** * Called when the framework connects and has declared new network ready for use. + * This callback may be called more than once if the {@link Network} that is + * satisfying the request changes. * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. * @param network The {@link Network} of the satisfying network. */ - public void onAvailable(NetworkRequest networkRequest, Network network) {} + public void onAvailable(Network network) {} /** * Called when the network is about to be disconnected. Often paired with an - * {@link NetworkCallbackListener#onAvailable} call with the new replacement network + * {@link NetworkCallback#onAvailable} call with the new replacement network * for graceful handover. This may not be called if we have a hard loss * (loss without warning). This may be followed by either a - * {@link NetworkCallbackListener#onLost} call or a - * {@link NetworkCallbackListener#onAvailable} call for this network depending + * {@link NetworkCallback#onLost} call or a + * {@link NetworkCallback#onAvailable} call for this network depending * on whether we lose or regain it. * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. - * @param network The {@link Network} of the failing network. - * @param maxSecToLive The time in seconds the framework will attempt to keep the - * network connected. Note that the network may suffers a + * @param network The {@link Network} that is about to be disconnected. + * @param maxMsToLive The time in ms the framework will attempt to keep the + * network connected. Note that the network may suffer a * hard loss at any time. */ - public void onLosing(NetworkRequest networkRequest, Network network, int maxSecToLive) {} + public void onLosing(Network network, int maxMsToLive) {} /** * Called when the framework has a hard loss of the network or when the * graceful failure ends. * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. * @param network The {@link Network} lost. */ - public void onLost(NetworkRequest networkRequest, Network network) {} + public void onLost(Network network) {} /** * Called if no network is found in the given timeout time. If no timeout is given, * this will not be called. * @hide */ - public void onUnavailable(NetworkRequest networkRequest) {} + public void onUnavailable() {} /** * Called when the network the framework connected to for this request * changes capabilities but still satisfies the stated need. * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. * @param network The {@link Network} whose capabilities have changed. * @param networkCapabilities The new {@link NetworkCapabilities} for this network. */ - public void onNetworkCapabilitiesChanged(NetworkRequest networkRequest, Network network, + public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {} /** * Called when the network the framework connected to for this request * changes {@link LinkProperties}. * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. * @param network The {@link Network} whose link properties have changed. * @param linkProperties The new {@link LinkProperties} for this network. */ - public void onLinkPropertiesChanged(NetworkRequest networkRequest, Network network, - LinkProperties linkProperties) {} + public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {} - /** - * Called when a {@link #releaseNetworkRequest} call concludes and the registered - * callbacks will no longer be used. - * - * @param networkRequest The {@link NetworkRequest} used to initiate the request. - */ - public void onReleased(NetworkRequest networkRequest) {} + private NetworkRequest networkRequest; } private static final int BASE = Protocol.BASE_CONNECTIVITY_MANAGER; @@ -2013,12 +2008,12 @@ public class ConnectivityManager { private static final int EXPIRE_LEGACY_REQUEST = BASE + 10; private class CallbackHandler extends Handler { - private final HashMap<NetworkRequest, NetworkCallbackListener>mCallbackMap; + private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap; private final AtomicInteger mRefCount; private static final String TAG = "ConnectivityManager.CallbackHandler"; private final ConnectivityManager mCm; - CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallbackListener>callbackMap, + CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap, AtomicInteger refCount, ConnectivityManager cm) { super(looper); mCallbackMap = callbackMap; @@ -2032,9 +2027,9 @@ public class ConnectivityManager { switch (message.what) { case CALLBACK_PRECHECK: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { - callbacks.onPreCheck(request, getNetwork(message)); + callbacks.onPreCheck(getNetwork(message)); } else { Log.e(TAG, "callback not found for PRECHECK message"); } @@ -2042,9 +2037,9 @@ public class ConnectivityManager { } case CALLBACK_AVAILABLE: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { - callbacks.onAvailable(request, getNetwork(message)); + callbacks.onAvailable(getNetwork(message)); } else { Log.e(TAG, "callback not found for AVAILABLE message"); } @@ -2052,9 +2047,9 @@ public class ConnectivityManager { } case CALLBACK_LOSING: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { - callbacks.onLosing(request, getNetwork(message), message.arg1); + callbacks.onLosing(getNetwork(message), message.arg1); } else { Log.e(TAG, "callback not found for LOSING message"); } @@ -2062,9 +2057,9 @@ public class ConnectivityManager { } case CALLBACK_LOST: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { - callbacks.onLost(request, getNetwork(message)); + callbacks.onLost(getNetwork(message)); } else { Log.e(TAG, "callback not found for LOST message"); } @@ -2072,12 +2067,12 @@ public class ConnectivityManager { } case CALLBACK_UNAVAIL: { NetworkRequest req = (NetworkRequest)message.obj; - NetworkCallbackListener callbacks = null; + NetworkCallback callbacks = null; synchronized(mCallbackMap) { callbacks = mCallbackMap.get(req); } if (callbacks != null) { - callbacks.onUnavailable(req); + callbacks.onUnavailable(); } else { Log.e(TAG, "callback not found for UNAVAIL message"); } @@ -2085,12 +2080,12 @@ public class ConnectivityManager { } case CALLBACK_CAP_CHANGED: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { Network network = getNetwork(message); NetworkCapabilities cap = mCm.getNetworkCapabilities(network); - callbacks.onNetworkCapabilitiesChanged(request, network, cap); + callbacks.onCapabilitiesChanged(network, cap); } else { Log.e(TAG, "callback not found for CHANGED message"); } @@ -2098,12 +2093,12 @@ public class ConnectivityManager { } case CALLBACK_IP_CHANGED: { NetworkRequest request = getNetworkRequest(message); - NetworkCallbackListener callbacks = getCallbacks(request); + NetworkCallback callbacks = getCallbacks(request); if (callbacks != null) { Network network = getNetwork(message); LinkProperties lp = mCm.getLinkProperties(network); - callbacks.onLinkPropertiesChanged(request, network, lp); + callbacks.onLinkPropertiesChanged(network, lp); } else { Log.e(TAG, "callback not found for CHANGED message"); } @@ -2111,20 +2106,19 @@ public class ConnectivityManager { } case CALLBACK_RELEASED: { NetworkRequest req = (NetworkRequest)message.obj; - NetworkCallbackListener callbacks = null; + NetworkCallback callbacks = null; synchronized(mCallbackMap) { callbacks = mCallbackMap.remove(req); } if (callbacks != null) { - callbacks.onReleased(req); + synchronized(mRefCount) { + if (mRefCount.decrementAndGet() == 0) { + getLooper().quit(); + } + } } else { Log.e(TAG, "callback not found for CANCELED message"); } - synchronized(mRefCount) { - if (mRefCount.decrementAndGet() == 0) { - getLooper().quit(); - } - } break; } case CALLBACK_EXIT: { @@ -2142,7 +2136,7 @@ public class ConnectivityManager { private NetworkRequest getNetworkRequest(Message msg) { return (NetworkRequest)(msg.obj); } - private NetworkCallbackListener getCallbacks(NetworkRequest req) { + private NetworkCallback getCallbacks(NetworkRequest req) { synchronized(mCallbackMap) { return mCallbackMap.get(req); } @@ -2150,7 +2144,7 @@ public class ConnectivityManager { private Network getNetwork(Message msg) { return new Network(msg.arg2); } - private NetworkCallbackListener removeCallbacks(Message msg) { + private NetworkCallback removeCallbacks(Message msg) { NetworkRequest req = (NetworkRequest)msg.obj; synchronized(mCallbackMap) { return mCallbackMap.remove(req); @@ -2158,19 +2152,19 @@ public class ConnectivityManager { } } - private void addCallbackListener() { + private void incCallbackHandlerRefCount() { synchronized(sCallbackRefCount) { if (sCallbackRefCount.incrementAndGet() == 1) { // TODO - switch this over to a ManagerThread or expire it when done HandlerThread callbackThread = new HandlerThread("ConnectivityManager"); callbackThread.start(); sCallbackHandler = new CallbackHandler(callbackThread.getLooper(), - sNetworkCallbackListener, sCallbackRefCount, this); + sNetworkCallback, sCallbackRefCount, this); } } } - private void removeCallbackListener() { + private void decCallbackHandlerRefCount() { synchronized(sCallbackRefCount) { if (sCallbackRefCount.decrementAndGet() == 0) { sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget(); @@ -2179,8 +2173,8 @@ public class ConnectivityManager { } } - static final HashMap<NetworkRequest, NetworkCallbackListener> sNetworkCallbackListener = - new HashMap<NetworkRequest, NetworkCallbackListener>(); + static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback = + new HashMap<NetworkRequest, NetworkCallback>(); static final AtomicInteger sCallbackRefCount = new AtomicInteger(0); static CallbackHandler sCallbackHandler = null; @@ -2188,51 +2182,48 @@ public class ConnectivityManager { private final static int REQUEST = 2; private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, - NetworkCallbackListener networkCallbackListener, int timeoutSec, int action, + NetworkCallback networkCallback, int timeoutSec, int action, int legacyType) { - NetworkRequest networkRequest = null; - if (networkCallbackListener == null) { - throw new IllegalArgumentException("null NetworkCallbackListener"); + if (networkCallback == null) { + throw new IllegalArgumentException("null NetworkCallback"); } if (need == null) throw new IllegalArgumentException("null NetworkCapabilities"); try { - addCallbackListener(); + incCallbackHandlerRefCount(); if (action == LISTEN) { - networkRequest = mService.listenForNetwork(need, new Messenger(sCallbackHandler), - new Binder()); + networkCallback.networkRequest = mService.listenForNetwork(need, + new Messenger(sCallbackHandler), new Binder()); } else { - networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler), - timeoutSec, new Binder(), legacyType); + networkCallback.networkRequest = mService.requestNetwork(need, + new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType); } - if (networkRequest != null) { - synchronized(sNetworkCallbackListener) { - sNetworkCallbackListener.put(networkRequest, networkCallbackListener); + if (networkCallback.networkRequest != null) { + synchronized(sNetworkCallback) { + sNetworkCallback.put(networkCallback.networkRequest, networkCallback); } } } catch (RemoteException e) {} - if (networkRequest == null) removeCallbackListener(); - return networkRequest; + if (networkCallback.networkRequest == null) decCallbackHandlerRefCount(); + return networkCallback.networkRequest; } /** * Request a network to satisfy a set of {@link NetworkCapabilities}. * * This {@link NetworkRequest} will live until released via - * {@link #releaseNetworkRequest} or the calling application exits. + * {@link #unregisterNetworkCallback} or the calling application exits. * Status of the request can be followed by listening to the various - * callbacks described in {@link NetworkCallbackListener}. The {@link Network} + * callbacks described in {@link NetworkCallback}. The {@link Network} * can be used to direct traffic to the network. * - * @param need {@link NetworkCapabilities} required by this request. - * @param networkCallbackListener The {@link NetworkCallbackListener} to be utilized for this - * request. Note the callbacks can be shared by multiple - * requests and the NetworkRequest token utilized to - * determine to which request the callback relates. - * @return A {@link NetworkRequest} object identifying the request. + * @param request {@link NetworkRequest} describing this request. + * @param networkCallback The {@link NetworkCallback} to be utilized for this + * request. Note the callback must not be shared - they + * uniquely specify this request. */ - public NetworkRequest requestNetwork(NetworkCapabilities need, - NetworkCallbackListener networkCallbackListener) { - return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE); + public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback) { + sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, + REQUEST, TYPE_NONE); } /** @@ -2240,53 +2231,53 @@ public class ConnectivityManager { * by a timeout. * * This function behaves identically to the non-timedout version, but if a suitable - * network is not found within the given time (in Seconds) the - * {@link NetworkCallbackListener#unavailable} callback is called. The request must + * network is not found within the given time (in milliseconds) the + * {@link NetworkCallback#unavailable} callback is called. The request must * still be released normally by calling {@link releaseNetworkRequest}. - * @param need {@link NetworkCapabilities} required by this request. - * @param networkCallbackListener The callbacks to be utilized for this request. Note - * the callbacks can be shared by multiple requests and - * the NetworkRequest token utilized to determine to which - * request the callback relates. - * @param timeoutSec The time in seconds to attempt looking for a suitable network - * before {@link NetworkCallbackListener#unavailable} is called. - * @return A {@link NetworkRequest} object identifying the request. + * @param request {@link NetworkRequest} describing this request. + * @param networkCallback The callbacks to be utilized for this request. Note + * the callbacks must not be shared - they uniquely specify + * this request. + * @param timeoutMs The time in milliseconds to attempt looking for a suitable network + * before {@link NetworkCallback#unavailable} is called. * @hide */ - public NetworkRequest requestNetwork(NetworkCapabilities need, - NetworkCallbackListener networkCallbackListener, int timeoutSec) { - return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST, - TYPE_NONE); + public void requestNetwork(NetworkRequest request, NetworkCallback networkCallback, + int timeoutMs) { + sendRequestForNetwork(request.networkCapabilities, networkCallback, timeoutMs, + REQUEST, TYPE_NONE); } /** - * The maximum number of seconds the framework will look for a suitable network + * The maximum number of milliseconds the framework will look for a suitable network * during a timeout-equiped call to {@link requestNetwork}. * {@hide} */ - public final static int MAX_NETWORK_REQUEST_TIMEOUT_SEC = 100 * 60; + public final static int MAX_NETWORK_REQUEST_TIMEOUT_MS = 100 * 60 * 1000; /** * The lookup key for a {@link Network} object included with the intent after * succesfully finding a network for the applications request. Retrieve it with * {@link android.content.Intent#getParcelableExtra(String)}. + * @hide */ public static final String EXTRA_NETWORK_REQUEST_NETWORK = "networkRequestNetwork"; /** - * The lookup key for a {@link NetworkCapabilities} object included with the intent after + * The lookup key for a {@link NetworkRequest} object included with the intent after * succesfully finding a network for the applications request. Retrieve it with * {@link android.content.Intent#getParcelableExtra(String)}. + * @hide */ - public static final String EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES = - "networkRequestNetworkCapabilities"; + public static final String EXTRA_NETWORK_REQUEST_NETWORK_REQUEST = + "networkRequestNetworkRequest"; /** * Request a network to satisfy a set of {@link NetworkCapabilities}. * - * This function behavies identically to the callback-equiped version, but instead - * of {@link NetworkCallbackListener} a {@link PendingIntent} is used. This means + * This function behavies identically to the version that takes a NetworkCallback, but instead + * of {@link NetworkCallback} a {@link PendingIntent} is used. This means * the request may outlive the calling application and get called back when a suitable * network is found. * <p> @@ -2295,10 +2286,10 @@ public class ConnectivityManager { * <receiver> tag in an AndroidManifest.xml file * <p> * The operation Intent is delivered with two extras, a {@link Network} typed - * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkCapabilities} - * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_CAPABILITIES} containing + * extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK} and a {@link NetworkRequest} + * typed extra called {@link #EXTRA_NETWORK_REQUEST_NETWORK_REQUEST} containing * the original requests parameters. It is important to create a new, - * {@link NetworkCallbackListener} based request before completing the processing of the + * {@link NetworkCallback} based request before completing the processing of the * Intent to reserve the network or it will be released shortly after the Intent * is processed. * <p> @@ -2306,51 +2297,49 @@ public class ConnectivityManager { * two Intents defined by {@link Intent#filterEquals}), then it will be removed and * replaced by this one, effectively releasing the previous {@link NetworkRequest}. * <p> - * The request may be released normally by calling {@link #releaseNetworkRequest}. + * The request may be released normally by calling {@link #unregisterNetworkCallback}. * - * @param need {@link NetworkCapabilities} required by this request. + * @param request {@link NetworkRequest} describing this request. * @param operation Action to perform when the network is available (corresponds - * to the {@link NetworkCallbackListener#onAvailable} call. Typically + * to the {@link NetworkCallback#onAvailable} call. Typically * comes from {@link PendingIntent#getBroadcast}. - * @return A {@link NetworkRequest} object identifying the request. + * @hide */ - public NetworkRequest requestNetwork(NetworkCapabilities need, PendingIntent operation) { + public void requestNetwork(NetworkRequest request, PendingIntent operation) { try { - return mService.pendingRequestForNetwork(need, operation); + mService.pendingRequestForNetwork(request.networkCapabilities, operation); } catch (RemoteException e) {} - return null; } /** * Registers to receive notifications about all networks which satisfy the given - * {@link NetworkCapabilities}. The callbacks will continue to be called until - * either the application exits or the request is released using - * {@link #releaseNetworkRequest}. + * {@link NetworkRequest}. The callbacks will continue to be called until + * either the application exits or {@link #unregisterNetworkCallback} is called * - * @param need {@link NetworkCapabilities} required by this request. - * @param networkCallbackListener The {@link NetworkCallbackListener} to be called as suitable - * networks change state. - * @return A {@link NetworkRequest} object identifying the request. + * @param request {@link NetworkRequest} describing this request. + * @param networkCallback The {@link NetworkCallback} that the system will call as suitable + * networks change state. */ - public NetworkRequest listenForNetwork(NetworkCapabilities need, - NetworkCallbackListener networkCallbackListener) { - return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE); + public void registerNetworkCallback(NetworkRequest request, NetworkCallback networkCallback) { + sendRequestForNetwork(request.networkCapabilities, networkCallback, 0, LISTEN, TYPE_NONE); } /** - * Releases a {@link NetworkRequest} generated either through a {@link #requestNetwork} - * or a {@link #listenForNetwork} call. The {@link NetworkCallbackListener} given in the - * earlier call may continue receiving calls until the - * {@link NetworkCallbackListener#onReleased} function is called, signifying the end - * of the request. + * Unregisters callbacks about and possibly releases networks originating from + * {@link #requestNetwork} and {@link #registerNetworkCallback} calls. If the + * given {@code NetworkCallback} had previosuly been used with {@code #requestNetwork}, + * any networks that had been connected to only to satisfy that request will be + * disconnected. * - * @param networkRequest The {@link NetworkRequest} generated by an earlier call to - * {@link #requestNetwork} or {@link #listenForNetwork}. + * @param networkCallback The {@link NetworkCallback} used when making the request. */ - public void releaseNetworkRequest(NetworkRequest networkRequest) { - if (networkRequest == null) throw new IllegalArgumentException("null NetworkRequest"); + public void unregisterNetworkCallback(NetworkCallback networkCallback) { + if (networkCallback == null || networkCallback.networkRequest == null || + networkCallback.networkRequest.requestId == REQUEST_ID_UNSET) { + throw new IllegalArgumentException("Invalid NetworkCallback"); + } try { - mService.releaseNetworkRequest(networkRequest); + mService.releaseNetworkRequest(networkCallback.networkRequest); } catch (RemoteException e) {} } diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index d933f26..318aabe 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -29,8 +29,9 @@ import javax.net.SocketFactory; /** * Identifies a {@code Network}. This is supplied to applications via - * {@link ConnectivityManager.NetworkCallbackListener} in response to - * {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}. + * {@link ConnectivityManager.NetworkCallback} in response to the active + * {@link ConnectivityManager#requestNetwork} or passive + * {@link ConnectivityManager#registerNetworkCallback} calls. * 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 ConnectivityManager#setProcessDefaultNetwork}. diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index 7911c72..36dc573 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Defines a request for a network, made through {@link NetworkRequest.Builder} and used * to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes - * via {@link ConnectivityManager#listenForNetwork}. + * via {@link ConnectivityManager#registerNetworkCallback}. */ public class NetworkRequest implements Parcelable { /** diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index cd47099..e77ef95 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -39,9 +39,6 @@ interface IUserManager { UserInfo getProfileParent(int userHandle); UserInfo getUserInfo(int userHandle); boolean isRestricted(); - void setGuestEnabled(boolean enable); - boolean isGuestEnabled(); - void wipeUser(int userHandle); int getUserSerialNumber(int userHandle); int getUserHandle(int userSerialNumber); Bundle getUserRestrictions(int userHandle); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 91fbb9d..eb3c748 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -25,6 +25,7 @@ import android.graphics.Bitmap.Config; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.provider.Settings; import android.util.Log; import com.android.internal.R; @@ -361,6 +362,16 @@ public class UserManager { } /** + * Checks if the calling app is running as a guest user. + * @return whether the caller is a guest user. + * @hide + */ + public boolean isGuestUser() { + UserInfo user = getUserInfo(UserHandle.myUserId()); + return user != null ? user.isGuest() : false; + } + + /** * Return whether the given user is actively running. This means that * the user is in the "started" state, not "stopped" -- it is currently * allowed to run code through scheduled alarms, receiving broadcasts, @@ -550,6 +561,21 @@ public class UserManager { } /** + * Creates a guest user and configures it. + * @param context an application context + * @param name the name to set for the user + * @hide + */ + public UserInfo createGuest(Context context, String name) { + UserInfo guest = createUser(name, UserInfo.FLAG_GUEST); + if (guest != null) { + Settings.Secure.putStringForUser(context.getContentResolver(), + Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id); + } + return guest; + } + + /** * Creates a user with the specified name and options as a profile of another user. * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. * @@ -827,50 +853,6 @@ public class UserManager { } /** - * Enable or disable the use of a guest account. If disabled, the existing guest account - * will be wiped. - * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. - * @param enable whether to enable a guest account. - * @hide - */ - public void setGuestEnabled(boolean enable) { - try { - mService.setGuestEnabled(enable); - } catch (RemoteException re) { - Log.w(TAG, "Could not change guest account availability to " + enable); - } - } - - /** - * Checks if a guest user is enabled for this device. - * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. - * @return whether a guest user is enabled - * @hide - */ - public boolean isGuestEnabled() { - try { - return mService.isGuestEnabled(); - } catch (RemoteException re) { - Log.w(TAG, "Could not retrieve guest enabled state"); - return false; - } - } - - /** - * Wipes all the data for a user, but doesn't remove the user. - * Requires {@link android.Manifest.permission#MANAGE_USERS} permission. - * @param userHandle - * @hide - */ - public void wipeUser(int userHandle) { - try { - mService.wipeUser(userHandle); - } catch (RemoteException re) { - Log.w(TAG, "Could not wipe user " + userHandle); - } - } - - /** * Returns the maximum number of users that can be created on this device. A return value * of 1 means that it is a single user device. * @hide diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 1001677..3fe0fb8 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4576,6 +4576,16 @@ public final class Settings { public static final String DISPLAY_INTERCEPTED_NOTIFICATIONS = "display_intercepted_notifications"; /** + * If enabled, apps should try to skip any introductory hints on first launch. This might + * apply to users that are already familiar with the environment or temporary users, like + * guests. + * <p> + * Type : int (0 to show hints, 1 to skip showing hints) + * @hide + */ + public static final String SKIP_FIRST_USE_HINTS = "skip_first_use_hints"; + + /** * This are the settings to be backed up. * * NOTE: Settings are backed up and restored in the order they appear @@ -6216,6 +6226,14 @@ public final class Settings { public static final String DEVICE_NAME = "device_name"; /** + * Whether it should be possible to create a guest user on the device. + * <p> + * Type: int (0 for disabled, 1 for enabled) + * @hide + */ + public static final String GUEST_USER_ENABLED = "guest_user_enabled"; + + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. * diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index c32a2c9..fa5bd88 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -46,7 +46,7 @@ interface IWindowSession { int addToDisplayWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs, in int viewVisibility, in int layerStackId, out Rect outContentInsets); void remove(IWindow window); - + /** * Change the parameters of a window. You supply the * new parameters, it returns the new frame of the window on screen (the @@ -109,7 +109,7 @@ interface IWindowSession { * to optimize compositing of this part of the window. */ void setTransparentRegion(IWindow window, in Region region); - + /** * Tell the window manager about the content and visible insets of the * given window, which can be used to adjust the <var>outContentInsets</var> @@ -122,20 +122,20 @@ interface IWindowSession { */ void setInsets(IWindow window, int touchableInsets, in Rect contentInsets, in Rect visibleInsets, in Region touchableRegion); - + /** * Return the current display size in which the window is being laid out, * accounting for screen decorations around it. */ void getDisplayFrame(IWindow window, out Rect outDisplayFrame); - + void finishDrawing(IWindow window); - + void setInTouchMode(boolean showFocus); boolean getInTouchMode(); - + boolean performHapticFeedback(IWindow window, int effectId, boolean always); - + /** * Allocate the drag's thumbnail surface. Also assigns a token that identifies * the drag to the OS and passes that as the return value. A return value of @@ -150,11 +150,11 @@ interface IWindowSession { boolean performDrag(IWindow window, IBinder dragToken, float touchX, float touchY, float thumbCenterX, float thumbCenterY, in ClipData data); - /** - * Report the result of a drop action targeted to the given window. - * consumed is 'true' when the drop was accepted by a valid recipient, - * 'false' otherwise. - */ + /** + * Report the result of a drop action targeted to the given window. + * consumed is 'true' when the drop was accepted by a valid recipient, + * 'false' otherwise. + */ void reportDropResult(IWindow window, boolean consumed); /** @@ -174,12 +174,12 @@ interface IWindowSession { * how big the increment is from one screen to another. */ void setWallpaperPosition(IBinder windowToken, float x, float y, float xstep, float ystep); - + void wallpaperOffsetsComplete(IBinder window); - + Bundle sendWallpaperCommand(IBinder window, String action, int x, int y, int z, in Bundle extras, boolean sync); - + void wallpaperCommandComplete(IBinder window, in Bundle result); void setUniverseTransform(IBinder window, float alpha, float offx, float offy, @@ -188,7 +188,7 @@ interface IWindowSession { /** * Notifies that a rectangle on the screen has been requested. */ - void onRectangleOnScreenRequested(IBinder token, in Rect rectangle, boolean immediate); + void onRectangleOnScreenRequested(IBinder token, in Rect rectangle); IWindowId getWindowId(IBinder window); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1871176..21bae23 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2775,6 +2775,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide * + * Whether Recents is visible or not. + */ + public static final int RECENT_APPS_VISIBLE = 0x00004000; + + /** + * @hide + * * Makes system ui transparent. */ public static final int SYSTEM_UI_TRANSPARENT = 0x00008000; @@ -2782,7 +2789,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide */ - public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00007FFF; + public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x00003FFF; /** * These are the system UI flags that can be cleared by events outside diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 76d5038..1be0d4e 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6215,7 +6215,7 @@ public final class ViewRootImpl implements ViewParent, mTempRect.offset(0, -mCurScrollY); mTempRect.offset(mAttachInfo.mWindowLeft, mAttachInfo.mWindowTop); try { - mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect, immediate); + mWindowSession.onRectangleOnScreenRequested(mWindow, mTempRect); } catch (RemoteException re) { /* ignore */ } diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java index 7f89044..b721074 100644 --- a/core/java/android/view/WindowInfo.java +++ b/core/java/android/view/WindowInfo.java @@ -111,6 +111,7 @@ public class WindowInfo implements Parcelable { builder.append("type=").append(type); builder.append(", layer=").append(layer); builder.append(", token=").append(token); + builder.append(", bounds=").append(boundsInScreen); builder.append(", parent=").append(parentToken); builder.append(", focused=").append(focused); builder.append(", children=").append(childTokens); diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 7b3dc84..1d2f1bf 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -46,7 +46,13 @@ public final class WindowInsets { * since it would allow them to inadvertently consume unknown insets by returning it. * @hide */ - public static final WindowInsets EMPTY = new WindowInsets(EMPTY_RECT, EMPTY_RECT); + public static final WindowInsets CONSUMED; + + static { + CONSUMED = new WindowInsets(EMPTY_RECT, EMPTY_RECT); + CONSUMED.mSystemWindowInsetsConsumed = true; + CONSUMED.mWindowDecorInsetsConsumed = true; + } /** @hide */ public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) { diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 2b4677c..d426edc 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -605,21 +605,21 @@ public interface WindowManagerPolicy { public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation); /** - * Return whether the given window should forcibly hide everything - * behind it. Typically returns true for the keyguard. + * Return whether the given window is forcibly hiding all windows except windows with + * FLAG_SHOW_WHEN_LOCKED set. Typically returns true for the keyguard. */ - public boolean doesForceHide(WindowManager.LayoutParams attrs); + public boolean isForceHiding(WindowManager.LayoutParams attrs); /** - * Return whether the given window can become one that passes doesForceHide() test. + * Return whether the given window can become one that passes isForceHiding() test. * Typically returns true for the StatusBar. */ public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs); /** * Determine if a window that is behind one that is force hiding - * (as determined by {@link #doesForceHide}) should actually be hidden. + * (as determined by {@link #isForceHiding}) should actually be hidden. * For example, typically returns false for the status bar. Be careful * to return false for any window that you may hide yourself, since this * will conflict with what you set. @@ -830,13 +830,11 @@ public interface WindowManagerPolicy { * setting the window's frame, either here or in finishLayout(). * * @param win The window being positioned. - * @param attrs The LayoutParams of the window. * @param attached For sub-windows, the window it is attached to; this * window will already have had layoutWindow() called on it * so you can use its Rect. Otherwise null. */ - public void layoutWindowLw(WindowState win, - WindowManager.LayoutParams attrs, WindowState attached); + public void layoutWindowLw(WindowState win, WindowState attached); /** diff --git a/core/java/android/view/animation/AccelerateInterpolator.java b/core/java/android/view/animation/AccelerateInterpolator.java index c08f348..1c75f16 100644 --- a/core/java/android/view/animation/AccelerateInterpolator.java +++ b/core/java/android/view/animation/AccelerateInterpolator.java @@ -17,15 +17,18 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.util.AttributeSet; +import com.android.internal.R; import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; /** - * An interpolator where the rate of change starts out slowly and + * An interpolator where the rate of change starts out slowly and * and then accelerates. * */ @@ -38,10 +41,10 @@ public class AccelerateInterpolator implements Interpolator, NativeInterpolatorF mFactor = 1.0f; mDoubleFactor = 2.0; } - + /** * Constructor - * + * * @param factor Degree to which the animation should be eased. Seting * factor to 1.0f produces a y=x^2 parabola. Increasing factor above * 1.0f exaggerates the ease-in effect (i.e., it starts even @@ -51,17 +54,26 @@ public class AccelerateInterpolator implements Interpolator, NativeInterpolatorF mFactor = factor; mDoubleFactor = 2 * mFactor; } - + public AccelerateInterpolator(Context context, AttributeSet attrs) { - TypedArray a = - context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator); - - mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f); + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public AccelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.AccelerateInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.AccelerateInterpolator); + } + + mFactor = a.getFloat(R.styleable.AccelerateInterpolator_factor, 1.0f); mDoubleFactor = 2 * mFactor; a.recycle(); } - + public float getInterpolation(float input) { if (mFactor == 1.0f) { return input * input; diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index 1d1fa1e..af4e04f 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -20,6 +20,8 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.XmlResourceParser; import android.content.res.Resources.NotFoundException; import android.util.AttributeSet; @@ -143,7 +145,7 @@ public class AnimationUtils { */ public static LayoutAnimationController loadLayoutAnimation(Context context, int id) throws NotFoundException { - + XmlResourceParser parser = null; try { parser = context.getResources().getAnimation(id); @@ -201,7 +203,7 @@ public class AnimationUtils { /** * Make an animation for objects becoming visible. Uses a slide and fade * effect. - * + * * @param c Context for loading resources * @param fromLeft is the object to be animated coming from the left * @return The new animation @@ -218,11 +220,11 @@ public class AnimationUtils { a.setStartTime(currentAnimationTimeMillis()); return a; } - + /** * Make an animation for objects becoming invisible. Uses a slide and fade * effect. - * + * * @param c Context for loading resources * @param toRight is the object to be animated exiting to the right * @return The new animation @@ -234,17 +236,17 @@ public class AnimationUtils { } else { a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_left); } - + a.setInterpolator(new AccelerateInterpolator()); a.setStartTime(currentAnimationTimeMillis()); return a; } - + /** * Make an animation for objects becoming visible. Uses a slide up and fade * effect. - * + * * @param c Context for loading resources * @return The new animation */ @@ -255,10 +257,10 @@ public class AnimationUtils { a.setStartTime(currentAnimationTimeMillis()); return a; } - + /** * Loads an {@link Interpolator} object from a resource - * + * * @param context Application context used to access resources * @param id The resource id of the animation to load * @return The animation object reference by the specified id @@ -268,7 +270,7 @@ public class AnimationUtils { XmlResourceParser parser = null; try { parser = context.getResources().getAnimation(id); - return createInterpolatorFromXml(context, parser); + return createInterpolatorFromXml(context.getResources(), context.getTheme(), parser); } catch (XmlPullParserException ex) { NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" + Integer.toHexString(id)); @@ -284,54 +286,84 @@ public class AnimationUtils { } } - - private static Interpolator createInterpolatorFromXml(Context c, XmlPullParser parser) + + /** + * Loads an {@link Interpolator} object from a resource + * + * @param res The resources + * @param id The resource id of the animation to load + * @return The interpolator object reference by the specified id + * @throws NotFoundException + * @hide + */ + public static Interpolator loadInterpolator(Resources res, Theme theme, int id) throws NotFoundException { + XmlResourceParser parser = null; + try { + parser = res.getAnimation(id); + return createInterpolatorFromXml(res, theme, parser); + } catch (XmlPullParserException ex) { + NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" + + Integer.toHexString(id)); + rnf.initCause(ex); + throw rnf; + } catch (IOException ex) { + NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" + + Integer.toHexString(id)); + rnf.initCause(ex); + throw rnf; + } finally { + if (parser != null) + parser.close(); + } + + } + + private static Interpolator createInterpolatorFromXml(Resources res, Theme theme, XmlPullParser parser) throws XmlPullParserException, IOException { - + Interpolator interpolator = null; - + // Make sure we are on a start tag. int type; int depth = parser.getDepth(); - while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) - && type != XmlPullParser.END_DOCUMENT) { + while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) + && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } AttributeSet attrs = Xml.asAttributeSet(parser); - - String name = parser.getName(); - - + + String name = parser.getName(); + if (name.equals("linearInterpolator")) { - interpolator = new LinearInterpolator(c, attrs); + interpolator = new LinearInterpolator(); } else if (name.equals("accelerateInterpolator")) { - interpolator = new AccelerateInterpolator(c, attrs); + interpolator = new AccelerateInterpolator(res, theme, attrs); } else if (name.equals("decelerateInterpolator")) { - interpolator = new DecelerateInterpolator(c, attrs); - } else if (name.equals("accelerateDecelerateInterpolator")) { - interpolator = new AccelerateDecelerateInterpolator(c, attrs); - } else if (name.equals("cycleInterpolator")) { - interpolator = new CycleInterpolator(c, attrs); + interpolator = new DecelerateInterpolator(res, theme, attrs); + } else if (name.equals("accelerateDecelerateInterpolator")) { + interpolator = new AccelerateDecelerateInterpolator(); + } else if (name.equals("cycleInterpolator")) { + interpolator = new CycleInterpolator(res, theme, attrs); } else if (name.equals("anticipateInterpolator")) { - interpolator = new AnticipateInterpolator(c, attrs); + interpolator = new AnticipateInterpolator(res, theme, attrs); } else if (name.equals("overshootInterpolator")) { - interpolator = new OvershootInterpolator(c, attrs); + interpolator = new OvershootInterpolator(res, theme, attrs); } else if (name.equals("anticipateOvershootInterpolator")) { - interpolator = new AnticipateOvershootInterpolator(c, attrs); + interpolator = new AnticipateOvershootInterpolator(res, theme, attrs); } else if (name.equals("bounceInterpolator")) { - interpolator = new BounceInterpolator(c, attrs); + interpolator = new BounceInterpolator(); } else if (name.equals("pathInterpolator")) { - interpolator = new PathInterpolator(c, attrs); + interpolator = new PathInterpolator(res, theme, attrs); } else { throw new RuntimeException("Unknown interpolator name: " + parser.getName()); } } - + return interpolator; } diff --git a/core/java/android/view/animation/AnticipateInterpolator.java b/core/java/android/view/animation/AnticipateInterpolator.java index 83a8007..fe756bd 100644 --- a/core/java/android/view/animation/AnticipateInterpolator.java +++ b/core/java/android/view/animation/AnticipateInterpolator.java @@ -17,9 +17,12 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; +import android.content.res.Resources.Theme; import android.util.AttributeSet; +import com.android.internal.R; import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; @@ -45,11 +48,20 @@ public class AnticipateInterpolator implements Interpolator, NativeInterpolatorF } public AnticipateInterpolator(Context context, AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.AnticipateInterpolator); + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public AnticipateInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.AnticipateInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.AnticipateInterpolator); + } mTension = - a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f); + a.getFloat(R.styleable.AnticipateInterpolator_tension, 2.0f); a.recycle(); } diff --git a/core/java/android/view/animation/AnticipateOvershootInterpolator.java b/core/java/android/view/animation/AnticipateOvershootInterpolator.java index 1a8adfd..78e5acf 100644 --- a/core/java/android/view/animation/AnticipateOvershootInterpolator.java +++ b/core/java/android/view/animation/AnticipateOvershootInterpolator.java @@ -17,6 +17,8 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.util.AttributeSet; @@ -62,7 +64,17 @@ public class AnticipateOvershootInterpolator implements Interpolator, NativeInte } public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator); + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public AnticipateOvershootInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, AnticipateOvershootInterpolator); + } mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) * a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f); diff --git a/core/java/android/view/animation/CycleInterpolator.java b/core/java/android/view/animation/CycleInterpolator.java index d1ebf05..3114aa3 100644 --- a/core/java/android/view/animation/CycleInterpolator.java +++ b/core/java/android/view/animation/CycleInterpolator.java @@ -17,9 +17,12 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; +import android.content.res.Resources.Theme; import android.util.AttributeSet; +import com.android.internal.R; import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; @@ -34,20 +37,29 @@ public class CycleInterpolator implements Interpolator, NativeInterpolatorFactor public CycleInterpolator(float cycles) { mCycles = cycles; } - + public CycleInterpolator(Context context, AttributeSet attrs) { - TypedArray a = - context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator); - - mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f); - + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.CycleInterpolator, 0, 0); + } else { + a = resources.obtainAttributes(attrs, R.styleable.CycleInterpolator); + } + + mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f); + a.recycle(); } - + public float getInterpolation(float input) { return (float)(Math.sin(2 * mCycles * Math.PI * input)); } - + private float mCycles; /** @hide */ diff --git a/core/java/android/view/animation/DecelerateInterpolator.java b/core/java/android/view/animation/DecelerateInterpolator.java index 0789a0e..674207c 100644 --- a/core/java/android/view/animation/DecelerateInterpolator.java +++ b/core/java/android/view/animation/DecelerateInterpolator.java @@ -17,15 +17,18 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; +import android.content.res.Resources.Theme; import android.util.AttributeSet; +import com.android.internal.R; import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; /** - * An interpolator where the rate of change starts out quickly and + * An interpolator where the rate of change starts out quickly and * and then decelerates. * */ @@ -36,7 +39,7 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF /** * Constructor - * + * * @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces * an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the * ease-out effect (i.e., it starts even faster and ends evens slower) @@ -44,16 +47,25 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF public DecelerateInterpolator(float factor) { mFactor = factor; } - + public DecelerateInterpolator(Context context, AttributeSet attrs) { - TypedArray a = - context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator); - - mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f); - + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public DecelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.DecelerateInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.DecelerateInterpolator); + } + + mFactor = a.getFloat(R.styleable.DecelerateInterpolator_factor, 1.0f); + a.recycle(); } - + public float getInterpolation(float input) { float result; if (mFactor == 1.0f) { @@ -63,7 +75,7 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF } return result; } - + private float mFactor = 1.0f; /** @hide */ diff --git a/core/java/android/view/animation/OvershootInterpolator.java b/core/java/android/view/animation/OvershootInterpolator.java index a2466f1..d6c2808 100644 --- a/core/java/android/view/animation/OvershootInterpolator.java +++ b/core/java/android/view/animation/OvershootInterpolator.java @@ -17,9 +17,12 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.util.AttributeSet; +import com.android.internal.R; import com.android.internal.view.animation.HasNativeInterpolator; import com.android.internal.view.animation.NativeInterpolatorFactory; import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; @@ -46,11 +49,20 @@ public class OvershootInterpolator implements Interpolator, NativeInterpolatorFa } public OvershootInterpolator(Context context, AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.OvershootInterpolator); + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public OvershootInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.OvershootInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.OvershootInterpolator); + } mTension = - a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f); + a.getFloat(R.styleable.OvershootInterpolator_tension, 2.0f); a.recycle(); } diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java index a369509..da12ffb 100644 --- a/core/java/android/view/animation/PathInterpolator.java +++ b/core/java/android/view/animation/PathInterpolator.java @@ -16,11 +16,15 @@ package android.view.animation; import android.content.Context; +import android.content.res.Resources; +import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.graphics.Path; import android.util.AttributeSet; import android.view.InflateException; +import com.android.internal.R; + /** * An interpolator that can traverse a Path that extends from <code>Point</code> * <code>(0, 0)</code> to <code>(1, 1)</code>. The x coordinate along the <code>Path</code> @@ -81,18 +85,33 @@ public class PathInterpolator implements Interpolator { } public PathInterpolator(Context context, AttributeSet attrs) { - TypedArray a = context.obtainStyledAttributes(attrs, - com.android.internal.R.styleable.PathInterpolator); - if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX1)) { + this(context.getResources(), context.getTheme(), attrs); + } + + /** @hide */ + public PathInterpolator(Resources res, Theme theme, AttributeSet attrs) { + TypedArray a; + if (theme != null) { + a = theme.obtainStyledAttributes(attrs, R.styleable.PathInterpolator, 0, 0); + } else { + a = res.obtainAttributes(attrs, R.styleable.PathInterpolator); + } + parseInterpolatorFromTypeArray(a); + + a.recycle(); + } + + private void parseInterpolatorFromTypeArray(TypedArray a) { + if (!a.hasValue(R.styleable.PathInterpolator_controlX1)) { throw new InflateException("pathInterpolator requires the controlX1 attribute"); - } else if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY1)) { + } else if (!a.hasValue(R.styleable.PathInterpolator_controlY1)) { throw new InflateException("pathInterpolator requires the controlY1 attribute"); } - float x1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX1, 0); - float y1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY1, 0); + float x1 = a.getFloat(R.styleable.PathInterpolator_controlX1, 0); + float y1 = a.getFloat(R.styleable.PathInterpolator_controlY1, 0); - boolean hasX2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX2); - boolean hasY2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY2); + boolean hasX2 = a.hasValue(R.styleable.PathInterpolator_controlX2); + boolean hasY2 = a.hasValue(R.styleable.PathInterpolator_controlY2); if (hasX2 != hasY2) { throw new InflateException( @@ -102,12 +121,10 @@ public class PathInterpolator implements Interpolator { if (!hasX2) { initQuad(x1, y1); } else { - float x2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX2, 0); - float y2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY2, 0); + float x2 = a.getFloat(R.styleable.PathInterpolator_controlX2, 0); + float y2 = a.getFloat(R.styleable.PathInterpolator_controlY2, 0); initCubic(x1, y1, x2, y2); } - - a.recycle(); } private void initQuad(float controlX, float controlY) { |
