diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
deleted file mode 100644
index 4648f39..0000000
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.widget.multiwaveview;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.media.AudioManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.Vibrator;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.internal.R;
-
-import java.util.ArrayList;
-
-/**
- * A special widget containing a center and outer ring. Moving the center ring to the outer ring
- * causes an event that can be caught by implementing OnTriggerListener.
- */
-public class MultiWaveView extends View {
-    private static final String TAG = "MultiWaveView";
-    private static final boolean DEBUG = false;
-
-    // Wave state machine
-    private static final int STATE_IDLE = 0;
-    private static final int STATE_START = 1;
-    private static final int STATE_FIRST_TOUCH = 2;
-    private static final int STATE_TRACKING = 3;
-    private static final int STATE_SNAP = 4;
-    private static final int STATE_FINISH = 5;
-
-    // Animation properties.
-    private static final float SNAP_MARGIN_DEFAULT = 20.0f; // distance to ring before we snap to it
-
-    public interface OnTriggerListener {
-        int NO_HANDLE = 0;
-        int CENTER_HANDLE = 1;
-        public void onGrabbed(View v, int handle);
-        public void onReleased(View v, int handle);
-        public void onTrigger(View v, int target);
-        public void onGrabbedStateChange(View v, int handle);
-        public void onFinishFinalAnimation();
-    }
-
-    // Tuneable parameters for animation
-    private static final int CHEVRON_INCREMENTAL_DELAY = 160;
-    private static final int CHEVRON_ANIMATION_DURATION = 850;
-    private static final int RETURN_TO_HOME_DELAY = 1200;
-    private static final int RETURN_TO_HOME_DURATION = 200;
-    private static final int HIDE_ANIMATION_DELAY = 200;
-    private static final int HIDE_ANIMATION_DURATION = 200;
-    private static final int SHOW_ANIMATION_DURATION = 200;
-    private static final int SHOW_ANIMATION_DELAY = 50;
-    private static final int INITIAL_SHOW_HANDLE_DURATION = 200;
-
-    private static final float TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.3f;
-    private static final float TARGET_SCALE_EXPANDED = 1.0f;
-    private static final float TARGET_SCALE_COLLAPSED = 0.8f;
-    private static final float RING_SCALE_EXPANDED = 1.0f;
-    private static final float RING_SCALE_COLLAPSED = 0.5f;
-
-    private TimeInterpolator mChevronAnimationInterpolator = Ease.Quad.easeOut;
-
-    private ArrayList<TargetDrawable> mTargetDrawables = new ArrayList<TargetDrawable>();
-    private ArrayList<TargetDrawable> mChevronDrawables = new ArrayList<TargetDrawable>();
-    private AnimationBundle mChevronAnimations = new AnimationBundle();
-    private AnimationBundle mTargetAnimations = new AnimationBundle();
-    private AnimationBundle mHandleAnimations = new AnimationBundle();
-    private ArrayList<String> mTargetDescriptions;
-    private ArrayList<String> mDirectionDescriptions;
-    private OnTriggerListener mOnTriggerListener;
-    private TargetDrawable mHandleDrawable;
-    private TargetDrawable mOuterRing;
-    private Vibrator mVibrator;
-
-    private int mFeedbackCount = 3;
-    private int mVibrationDuration = 0;
-    private int mGrabbedState;
-    private int mActiveTarget = -1;
-    private float mTapRadius;
-    private float mWaveCenterX;
-    private float mWaveCenterY;
-    private int mMaxTargetHeight;
-    private int mMaxTargetWidth;
-
-    private float mOuterRadius = 0.0f;
-    private float mSnapMargin = 0.0f;
-    private boolean mDragging;
-    private int mNewTargetResources;
-
-    private class AnimationBundle extends ArrayList<Tweener> {
-        private static final long serialVersionUID = 0xA84D78726F127468L;
-        private boolean mSuspended;
-
-        public void start() {
-            if (mSuspended) return; // ignore attempts to start animations
-            final int count = size();
-            for (int i = 0; i < count; i++) {
-                Tweener anim = get(i);
-                anim.animator.start();
-            }
-        }
-
-        public void cancel() {
-            final int count = size();
-            for (int i = 0; i < count; i++) {
-                Tweener anim = get(i);
-                anim.animator.cancel();
-            }
-            clear();
-        }
-
-        public void stop() {
-            final int count = size();
-            for (int i = 0; i < count; i++) {
-                Tweener anim = get(i);
-                anim.animator.end();
-            }
-            clear();
-        }
-
-        public void setSuspended(boolean suspend) {
-            mSuspended = suspend;
-        }
-    };
-
-    private AnimatorListener mResetListener = new AnimatorListenerAdapter() {
-        public void onAnimationEnd(Animator animator) {
-            switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY);
-            dispatchOnFinishFinalAnimation();
-        }
-    };
-
-    private AnimatorListener mResetListenerWithPing = new AnimatorListenerAdapter() {
-        public void onAnimationEnd(Animator animator) {
-            ping();
-            switchToState(STATE_IDLE, mWaveCenterX, mWaveCenterY);
-            dispatchOnFinishFinalAnimation();
-        }
-    };
-
-    private AnimatorUpdateListener mUpdateListener = new AnimatorUpdateListener() {
-        public void onAnimationUpdate(ValueAnimator animation) {
-            invalidateGlobalRegion(mHandleDrawable);
-            invalidate();
-        }
-    };
-
-    private boolean mAnimatingTargets;
-    private AnimatorListener mTargetUpdateListener = new AnimatorListenerAdapter() {
-        public void onAnimationEnd(Animator animator) {
-            if (mNewTargetResources != 0) {
-                internalSetTargetResources(mNewTargetResources);
-                mNewTargetResources = 0;
-                hideTargets(false, false);
-            }
-            mAnimatingTargets = false;
-        }
-    };
-    private int mTargetResourceId;
-    private int mTargetDescriptionsResourceId;
-    private int mDirectionDescriptionsResourceId;
-    private boolean mAlwaysTrackFinger;
-    private int mHorizontalInset;
-    private int mVerticalInset;
-    private int mGravity = Gravity.TOP;
-    private boolean mInitialLayout = true;
-    private Tweener mBackgroundAnimator;
-
-    public MultiWaveView(Context context) {
-        this(context, null);
-    }
-
-    public MultiWaveView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        Resources res = context.getResources();
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiWaveView);
-        mOuterRadius = a.getDimension(R.styleable.MultiWaveView_outerRadius, mOuterRadius);
-        mSnapMargin = a.getDimension(R.styleable.MultiWaveView_snapMargin, mSnapMargin);
-        mVibrationDuration = a.getInt(R.styleable.MultiWaveView_vibrationDuration,
-                mVibrationDuration);
-        mFeedbackCount = a.getInt(R.styleable.MultiWaveView_feedbackCount,
-                mFeedbackCount);
-        mHandleDrawable = new TargetDrawable(res,
-                a.peekValue(R.styleable.MultiWaveView_handleDrawable).resourceId);
-        mTapRadius = mHandleDrawable.getWidth()/2;
-        mOuterRing = new TargetDrawable(res,
-                a.peekValue(R.styleable.MultiWaveView_waveDrawable).resourceId);
-        mAlwaysTrackFinger = a.getBoolean(R.styleable.MultiWaveView_alwaysTrackFinger, false);
-
-        // Read array of chevron drawables
-        TypedValue outValue = new TypedValue();
-        if (a.getValue(R.styleable.MultiWaveView_chevronDrawables, outValue)) {
-            ArrayList<TargetDrawable> chevrons = loadDrawableArray(outValue.resourceId);
-            for (int i = 0; i < chevrons.size(); i++) {
-                final TargetDrawable chevron = chevrons.get(i);
-                for (int k = 0; k < mFeedbackCount; k++) {
-                    mChevronDrawables.add(chevron == null ? null : new TargetDrawable(chevron));
-                }
-            }
-        }
-
-        // Read array of target drawables
-        if (a.getValue(R.styleable.MultiWaveView_targetDrawables, outValue)) {
-            internalSetTargetResources(outValue.resourceId);
-        }
-        if (mTargetDrawables == null || mTargetDrawables.size() == 0) {
-            throw new IllegalStateException("Must specify at least one target drawable");
-        }
-
-        // Read array of target descriptions
-        if (a.getValue(R.styleable.MultiWaveView_targetDescriptions, outValue)) {
-            final int resourceId = outValue.resourceId;
-            if (resourceId == 0) {
-                throw new IllegalStateException("Must specify target descriptions");
-            }
-            setTargetDescriptionsResourceId(resourceId);
-        }
-
-        // Read array of direction descriptions
-        if (a.getValue(R.styleable.MultiWaveView_directionDescriptions, outValue)) {
-            final int resourceId = outValue.resourceId;
-            if (resourceId == 0) {
-                throw new IllegalStateException("Must specify direction descriptions");
-            }
-            setDirectionDescriptionsResourceId(resourceId);
-        }
-
-        a.recycle();
-
-        // Use gravity attribute from LinearLayout
-        a = context.obtainStyledAttributes(attrs, android.R.styleable.LinearLayout);
-        mGravity = a.getInt(android.R.styleable.LinearLayout_gravity, Gravity.TOP);
-        a.recycle();
-
-        setVibrateEnabled(mVibrationDuration > 0);
-        assignDefaultsIfNeeded();
-    }
-
-    private void dump() {
-        Log.v(TAG, "Outer Radius = " + mOuterRadius);
-        Log.v(TAG, "SnapMargin = " + mSnapMargin);
-        Log.v(TAG, "FeedbackCount = " + mFeedbackCount);
-        Log.v(TAG, "VibrationDuration = " + mVibrationDuration);
-        Log.v(TAG, "TapRadius = " + mTapRadius);
-        Log.v(TAG, "WaveCenterX = " + mWaveCenterX);
-        Log.v(TAG, "WaveCenterY = " + mWaveCenterY);
-    }
-
-    public void suspendAnimations() {
-        mChevronAnimations.setSuspended(true);
-        mTargetAnimations.setSuspended(true);
-        mHandleAnimations.setSuspended(true);
-    }
-
-    public void resumeAnimations() {
-        mChevronAnimations.setSuspended(false);
-        mTargetAnimations.setSuspended(false);
-        mHandleAnimations.setSuspended(false);
-        mChevronAnimations.start();
-        mTargetAnimations.start();
-        mHandleAnimations.start();
-    }
-
-    @Override
-    protected int getSuggestedMinimumWidth() {
-        // View should be large enough to contain the background + handle and
-        // target drawable on either edge.
-        return (int) (Math.max(mOuterRing.getWidth(), 2 * mOuterRadius) + mMaxTargetWidth);
-    }
-
-    @Override
-    protected int getSuggestedMinimumHeight() {
-        // View should be large enough to contain the unlock ring + target and
-        // target drawable on either edge
-        return (int) (Math.max(mOuterRing.getHeight(), 2 * mOuterRadius) + mMaxTargetHeight);
-    }
-
-    private int resolveMeasured(int measureSpec, int desired)
-    {
-        int result = 0;
-        int specSize = MeasureSpec.getSize(measureSpec);
-        switch (MeasureSpec.getMode(measureSpec)) {
-            case MeasureSpec.UNSPECIFIED:
-                result = desired;
-                break;
-            case MeasureSpec.AT_MOST:
-                result = Math.min(specSize, desired);
-                break;
-            case MeasureSpec.EXACTLY:
-            default:
-                result = specSize;
-        }
-        return result;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        final int minimumWidth = getSuggestedMinimumWidth();
-        final int minimumHeight = getSuggestedMinimumHeight();
-        int computedWidth = resolveMeasured(widthMeasureSpec, minimumWidth);
-        int computedHeight = resolveMeasured(heightMeasureSpec, minimumHeight);
-        computeInsets((computedWidth - minimumWidth), (computedHeight - minimumHeight));
-        setMeasuredDimension(computedWidth, computedHeight);
-    }
-
-    private void switchToState(int state, float x, float y) {
-        switch (state) {
-            case STATE_IDLE:
-                deactivateTargets();
-                hideTargets(true, false);
-                startBackgroundAnimation(0, 0.0f);
-                mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
-                break;
-
-            case STATE_START:
-                deactivateHandle(0, 0, 1.0f, null);
-                startBackgroundAnimation(0, 0.0f);
-                break;
-
-            case STATE_FIRST_TOUCH:
-                deactivateTargets();
-                showTargets(true);
-                mHandleDrawable.setState(TargetDrawable.STATE_ACTIVE);
-                startBackgroundAnimation(INITIAL_SHOW_HANDLE_DURATION, 1.0f);
-                setGrabbedState(OnTriggerListener.CENTER_HANDLE);
-                if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                    announceTargets();
-                }
-                break;
-
-            case STATE_TRACKING:
-                break;
-
-            case STATE_SNAP:
-                break;
-
-            case STATE_FINISH:
-                doFinish();
-                break;
-        }
-    }
-
-    private void activateHandle(int duration, int delay, float finalAlpha,
-            AnimatorListener finishListener) {
-        mHandleAnimations.cancel();
-        mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
-                "ease", Ease.Cubic.easeIn,
-                "delay", delay,
-                "alpha", finalAlpha,
-                "onUpdate", mUpdateListener,
-                "onComplete", finishListener));
-        mHandleAnimations.start();
-    }
-
-    private void deactivateHandle(int duration, int delay, float finalAlpha,
-            AnimatorListener finishListener) {
-        mHandleAnimations.cancel();
-        mHandleAnimations.add(Tweener.to(mHandleDrawable, duration,
-            "ease", Ease.Quart.easeOut,
-            "delay", delay,
-            "alpha", finalAlpha,
-            "x", 0,
-            "y", 0,
-            "onUpdate", mUpdateListener,
-            "onComplete", finishListener));
-        mHandleAnimations.start();
-    }
-
-    /**
-     * Animation used to attract user's attention to the target button.
-     * Assumes mChevronDrawables is an a list with an even number of chevrons filled with
-     * mFeedbackCount items in the order: left, right, top, bottom.
-     */
-    private void startChevronAnimation() {
-        final float chevronStartDistance = mHandleDrawable.getWidth() * 0.8f;
-        final float chevronStopDistance = mOuterRadius * 0.9f / 2.0f;
-        final float startScale = 0.5f;
-        final float endScale = 2.0f;
-        final int directionCount = mFeedbackCount > 0 ? mChevronDrawables.size()/mFeedbackCount : 0;
-
-        mChevronAnimations.stop();
-
-        // Add an animation for all chevron drawables.  There are mFeedbackCount drawables
-        // in each direction and directionCount directions.
-        for (int direction = 0; direction < directionCount; direction++) {
-            double angle = 2.0 * Math.PI * direction / directionCount;
-            final float sx = (float) Math.cos(angle);
-            final float sy = 0.0f - (float) Math.sin(angle);
-            final float[] xrange = new float[]
-                 {sx * chevronStartDistance, sx * chevronStopDistance};
-            final float[] yrange = new float[]
-                 {sy * chevronStartDistance, sy * chevronStopDistance};
-            for (int count = 0; count < mFeedbackCount; count++) {
-                int delay = count * CHEVRON_INCREMENTAL_DELAY;
-                final TargetDrawable icon = mChevronDrawables.get(direction*mFeedbackCount + count);
-                if (icon == null) {
-                    continue;
-                }
-                mChevronAnimations.add(Tweener.to(icon, CHEVRON_ANIMATION_DURATION,
-                        "ease", mChevronAnimationInterpolator,
-                        "delay", delay,
-                        "x", xrange,
-                        "y", yrange,
-                        "alpha", new float[] {1.0f, 0.0f},
-                        "scaleX", new float[] {startScale, endScale},
-                        "scaleY", new float[] {startScale, endScale},
-                        "onUpdate", mUpdateListener));
-            }
-        }
-        mChevronAnimations.start();
-    }
-
-    private void deactivateTargets() {
-        final int count = mTargetDrawables.size();
-        for (int i = 0; i < count; i++) {
-            TargetDrawable target = mTargetDrawables.get(i);
-            target.setState(TargetDrawable.STATE_INACTIVE);
-        }
-        mActiveTarget = -1;
-    }
-
-    void invalidateGlobalRegion(TargetDrawable drawable) {
-        int width = drawable.getWidth();
-        int height = drawable.getHeight();
-        RectF childBounds = new RectF(0, 0, width, height);
-        childBounds.offset(drawable.getX() - width/2, drawable.getY() - height/2);
-        View view = this;
-        while (view.getParent() != null && view.getParent() instanceof View) {
-            view = (View) view.getParent();
-            view.getMatrix().mapRect(childBounds);
-            view.invalidate((int) Math.floor(childBounds.left),
-                    (int) Math.floor(childBounds.top),
-                    (int) Math.ceil(childBounds.right),
-                    (int) Math.ceil(childBounds.bottom));
-        }
-    }
-
-    /**
-     * Dispatches a trigger event to listener. Ignored if a listener is not set.
-     * @param whichTarget the target that was triggered.
-     */
-    private void dispatchTriggerEvent(int whichTarget) {
-        vibrate();
-        if (mOnTriggerListener != null) {
-            mOnTriggerListener.onTrigger(this, whichTarget);
-        }
-    }
-
-    private void dispatchOnFinishFinalAnimation() {
-        if (mOnTriggerListener != null) {
-            mOnTriggerListener.onFinishFinalAnimation();
-        }
-    }
-
-    private void doFinish() {
-        final int activeTarget = mActiveTarget;
-        final boolean targetHit =  activeTarget != -1;
-
-        if (targetHit) {
-            if (DEBUG) Log.v(TAG, "Finish with target hit = " + targetHit);
-
-            highlightSelected(activeTarget);
-
-            // Inform listener of any active targets.  Typically only one will be active.
-            deactivateHandle(RETURN_TO_HOME_DURATION, RETURN_TO_HOME_DELAY, 0.0f, mResetListener);
-            dispatchTriggerEvent(activeTarget);
-            if (!mAlwaysTrackFinger) {
-                // Force ring and targets to finish animation to final expanded state
-                mTargetAnimations.stop();
-            }
-        } else {
-            // Animate handle back to the center based on current state.
-            deactivateHandle(HIDE_ANIMATION_DURATION, HIDE_ANIMATION_DELAY, 1.0f,
-                    mResetListenerWithPing);
-            hideTargets(true, false);
-        }
-
-        setGrabbedState(OnTriggerListener.NO_HANDLE);
-    }
-
-    private void highlightSelected(int activeTarget) {
-        // Highlight the given target and fade others
-        mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
-        hideUnselected(activeTarget);
-    }
-
-    private void hideUnselected(int active) {
-        for (int i = 0; i < mTargetDrawables.size(); i++) {
-            if (i != active) {
-                mTargetDrawables.get(i).setAlpha(0.0f);
-            }
-        }
-    }
-
-    private void hideTargets(boolean animate, boolean expanded) {
-        mTargetAnimations.cancel();
-        // Note: these animations should complete at the same time so that we can swap out
-        // the target assets asynchronously from the setTargetResources() call.
-        mAnimatingTargets = animate;
-        final int duration = animate ? HIDE_ANIMATION_DURATION : 0;
-        final int delay = animate ? HIDE_ANIMATION_DELAY : 0;
-
-        final float targetScale = expanded ? TARGET_SCALE_EXPANDED : TARGET_SCALE_COLLAPSED;
-        final int length = mTargetDrawables.size();
-        for (int i = 0; i < length; i++) {
-            TargetDrawable target = mTargetDrawables.get(i);
-            target.setState(TargetDrawable.STATE_INACTIVE);
-            mTargetAnimations.add(Tweener.to(target, duration,
-                    "ease", Ease.Cubic.easeOut,
-                    "alpha", 0.0f,
-                    "scaleX", targetScale,
-                    "scaleY", targetScale,
-                    "delay", delay,
-                    "onUpdate", mUpdateListener));
-        }
-
-        final float ringScaleTarget = expanded ? RING_SCALE_EXPANDED : RING_SCALE_COLLAPSED;
-        mTargetAnimations.add(Tweener.to(mOuterRing, duration,
-                "ease", Ease.Cubic.easeOut,
-                "alpha", 0.0f,
-                "scaleX", ringScaleTarget,
-                "scaleY", ringScaleTarget,
-                "delay", delay,
-                "onUpdate", mUpdateListener,
-                "onComplete", mTargetUpdateListener));
-
-        mTargetAnimations.start();
-    }
-
-    private void showTargets(boolean animate) {
-        mTargetAnimations.stop();
-        mAnimatingTargets = animate;
-        final int delay = animate ? SHOW_ANIMATION_DELAY : 0;
-        final int duration = animate ? SHOW_ANIMATION_DURATION : 0;
-        final int length = mTargetDrawables.size();
-        for (int i = 0; i < length; i++) {
-            TargetDrawable target = mTargetDrawables.get(i);
-            target.setState(TargetDrawable.STATE_INACTIVE);
-            mTargetAnimations.add(Tweener.to(target, duration,
-                    "ease", Ease.Cubic.easeOut,
-                    "alpha", 1.0f,
-                    "scaleX", 1.0f,
-                    "scaleY", 1.0f,
-                    "delay", delay,
-                    "onUpdate", mUpdateListener));
-        }
-        mTargetAnimations.add(Tweener.to(mOuterRing, duration,
-                "ease", Ease.Cubic.easeOut,
-                "alpha", 1.0f,
-                "scaleX", 1.0f,
-                "scaleY", 1.0f,
-                "delay", delay,
-                "onUpdate", mUpdateListener,
-                "onComplete", mTargetUpdateListener));
-
-        mTargetAnimations.start();
-    }
-
-    private void vibrate() {
-        final boolean hapticEnabled = Settings.System.getIntForUser(
-                mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
-                UserHandle.USER_CURRENT) != 0;
-        if (mVibrator != null && hapticEnabled) {
-            mVibrator.vibrate(mVibrationDuration, AudioManager.STREAM_SYSTEM);
-        }
-    }
-
-    private ArrayList<TargetDrawable> loadDrawableArray(int resourceId) {
-        Resources res = getContext().getResources();
-        TypedArray array = res.obtainTypedArray(resourceId);
-        final int count = array.length();
-        ArrayList<TargetDrawable> drawables = new ArrayList<TargetDrawable>(count);
-        for (int i = 0; i < count; i++) {
-            TypedValue value = array.peekValue(i);
-            TargetDrawable target = new TargetDrawable(res, value != null ? value.resourceId : 0);
-            drawables.add(target);
-        }
-        array.recycle();
-        return drawables;
-    }
-
-    private void internalSetTargetResources(int resourceId) {
-        mTargetDrawables = loadDrawableArray(resourceId);
-        mTargetResourceId = resourceId;
-        final int count = mTargetDrawables.size();
-        int maxWidth = mHandleDrawable.getWidth();
-        int maxHeight = mHandleDrawable.getHeight();
-        for (int i = 0; i < count; i++) {
-            TargetDrawable target = mTargetDrawables.get(i);
-            maxWidth = Math.max(maxWidth, target.getWidth());
-            maxHeight = Math.max(maxHeight, target.getHeight());
-        }
-        if (mMaxTargetWidth != maxWidth || mMaxTargetHeight != maxHeight) {
-            mMaxTargetWidth = maxWidth;
-            mMaxTargetHeight = maxHeight;
-            requestLayout(); // required to resize layout and call updateTargetPositions()
-        } else {
-            updateTargetPositions(mWaveCenterX, mWaveCenterY);
-            updateChevronPositions(mWaveCenterX, mWaveCenterY);
-        }
-    }
-
-    /**
-     * Loads an array of drawables from the given resourceId.
-     *
-     * @param resourceId
-     */
-    public void setTargetResources(int resourceId) {
-        if (mAnimatingTargets) {
-            // postpone this change until we return to the initial state
-            mNewTargetResources = resourceId;
-        } else {
-            internalSetTargetResources(resourceId);
-        }
-    }
-
-    public int getTargetResourceId() {
-        return mTargetResourceId;
-    }
-
-    /**
-     * Sets the resource id specifying the target descriptions for accessibility.
-     *
-     * @param resourceId The resource id.
-     */
-    public void setTargetDescriptionsResourceId(int resourceId) {
-        mTargetDescriptionsResourceId = resourceId;
-        if (mTargetDescriptions != null) {
-            mTargetDescriptions.clear();
-        }
-    }
-
-    /**
-     * Gets the resource id specifying the target descriptions for accessibility.
-     *
-     * @return The resource id.
-     */
-    public int getTargetDescriptionsResourceId() {
-        return mTargetDescriptionsResourceId;
-    }
-
-    /**
-     * Sets the resource id specifying the target direction descriptions for accessibility.
-     *
-     * @param resourceId The resource id.
-     */
-    public void setDirectionDescriptionsResourceId(int resourceId) {
-        mDirectionDescriptionsResourceId = resourceId;
-        if (mDirectionDescriptions != null) {
-            mDirectionDescriptions.clear();
-        }
-    }
-
-    /**
-     * Gets the resource id specifying the target direction descriptions.
-     *
-     * @return The resource id.
-     */
-    public int getDirectionDescriptionsResourceId() {
-        return mDirectionDescriptionsResourceId;
-    }
-
-    /**
-     * Enable or disable vibrate on touch.
-     *
-     * @param enabled
-     */
-    public void setVibrateEnabled(boolean enabled) {
-        if (enabled && mVibrator == null) {
-            mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
-        } else {
-            mVibrator = null;
-        }
-    }
-
-    /**
-     * Starts chevron animation. Example use case: show chevron animation whenever the phone rings
-     * or the user touches the screen.
-     *
-     */
-    public void ping() {
-        startChevronAnimation();
-    }
-
-    /**
-     * Resets the widget to default state and cancels all animation. If animate is 'true', will
-     * animate objects into place. Otherwise, objects will snap back to place.
-     *
-     * @param animate
-     */
-    public void reset(boolean animate) {
-        mChevronAnimations.stop();
-        mHandleAnimations.stop();
-        mTargetAnimations.stop();
-        startBackgroundAnimation(0, 0.0f);
-        hideChevrons();
-        hideTargets(animate, false);
-        deactivateHandle(0, 0, 1.0f, null);
-        Tweener.reset();
-    }
-
-    private void startBackgroundAnimation(int duration, float alpha) {
-        Drawable background = getBackground();
-        if (mAlwaysTrackFinger && background != null) {
-            if (mBackgroundAnimator != null) {
-                mBackgroundAnimator.animator.end();
-            }
-            mBackgroundAnimator = Tweener.to(background, duration,
-                    "ease", Ease.Cubic.easeIn,
-                    "alpha", new int[] {0, (int)(255.0f * alpha)},
-                    "delay", SHOW_ANIMATION_DELAY);
-            mBackgroundAnimator.animator.start();
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        final int action = event.getAction();
-        boolean handled = false;
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                if (DEBUG) Log.v(TAG, "*** DOWN ***");
-                handleDown(event);
-                handled = true;
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                if (DEBUG) Log.v(TAG, "*** MOVE ***");
-                handleMove(event);
-                handled = true;
-                break;
-
-            case MotionEvent.ACTION_UP:
-                if (DEBUG) Log.v(TAG, "*** UP ***");
-                handleMove(event);
-                handleUp(event);
-                handled = true;
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-                if (DEBUG) Log.v(TAG, "*** CANCEL ***");
-                handleMove(event);
-                handleCancel(event);
-                handled = true;
-                break;
-        }
-        invalidate();
-        return handled ? true : super.onTouchEvent(event);
-    }
-
-    private void moveHandleTo(float x, float y, boolean animate) {
-        mHandleDrawable.setX(x);
-        mHandleDrawable.setY(y);
-    }
-
-    private void handleDown(MotionEvent event) {
-        float eventX = event.getX();
-        float eventY = event.getY();
-        switchToState(STATE_START, eventX, eventY);
-        if (!trySwitchToFirstTouchState(eventX, eventY)) {
-            mDragging = false;
-            ping();
-        }
-    }
-
-    private void handleUp(MotionEvent event) {
-        if (DEBUG && mDragging) Log.v(TAG, "** Handle RELEASE");
-        switchToState(STATE_FINISH, event.getX(), event.getY());
-    }
-
-    private void handleCancel(MotionEvent event) {
-        if (DEBUG && mDragging) Log.v(TAG, "** Handle CANCEL");
-
-        // We should drop the active target here but it interferes with
-        // moving off the screen in the direction of the navigation bar. At some point we may
-        // want to revisit how we handle this. For now we'll allow a canceled event to
-        // activate the current target.
-
-        // mActiveTarget = -1; // Drop the active target if canceled.
-
-        switchToState(STATE_FINISH, event.getX(), event.getY());
-    }
-
-    private void handleMove(MotionEvent event) {
-        int activeTarget = -1;
-        final int historySize = event.getHistorySize();
-        ArrayList<TargetDrawable> targets = mTargetDrawables;
-        int ntargets = targets.size();
-        float x = 0.0f;
-        float y = 0.0f;
-        for (int k = 0; k < historySize + 1; k++) {
-            float eventX = k < historySize ? event.getHistoricalX(k) : event.getX();
-            float eventY = k < historySize ? event.getHistoricalY(k) : event.getY();
-            // tx and ty are relative to wave center
-            float tx = eventX - mWaveCenterX;
-            float ty = eventY - mWaveCenterY;
-            float touchRadius = (float) Math.sqrt(dist2(tx, ty));
-            final float scale = touchRadius > mOuterRadius ? mOuterRadius / touchRadius : 1.0f;
-            float limitX = tx * scale;
-            float limitY = ty * scale;
-            double angleRad = Math.atan2(-ty, tx);
-
-            if (!mDragging) {
-                trySwitchToFirstTouchState(eventX, eventY);
-            }
-
-            if (mDragging) {
-                // For multiple targets, snap to the one that matches
-                final float snapRadius = mOuterRadius - mSnapMargin;
-                final float snapDistance2 = snapRadius * snapRadius;
-                // Find first target in range
-                for (int i = 0; i < ntargets; i++) {
-                    TargetDrawable target = targets.get(i);
-
-                    double targetMinRad = (i - 0.5) * 2 * Math.PI / ntargets;
-                    double targetMaxRad = (i + 0.5) * 2 * Math.PI / ntargets;
-                    if (target.isEnabled()) {
-                        boolean angleMatches =
-                            (angleRad > targetMinRad && angleRad <= targetMaxRad) ||
-                            (angleRad + 2 * Math.PI > targetMinRad &&
-                             angleRad + 2 * Math.PI <= targetMaxRad);
-                        if (angleMatches && (dist2(tx, ty) > snapDistance2)) {
-                            activeTarget = i;
-                        }
-                    }
-                }
-            }
-            x = limitX;
-            y = limitY;
-        }
-
-        if (!mDragging) {
-            return;
-        }
-
-        if (activeTarget != -1) {
-            switchToState(STATE_SNAP, x,y);
-            moveHandleTo(x, y, false);
-        } else {
-            switchToState(STATE_TRACKING, x, y);
-            moveHandleTo(x, y, false);
-        }
-
-        // Draw handle outside parent's bounds
-        invalidateGlobalRegion(mHandleDrawable);
-
-        if (mActiveTarget != activeTarget) {
-            // Defocus the old target
-            if (mActiveTarget != -1) {
-                TargetDrawable target = targets.get(mActiveTarget);
-                if (target.hasState(TargetDrawable.STATE_FOCUSED)) {
-                    target.setState(TargetDrawable.STATE_INACTIVE);
-                }
-            }
-            // Focus the new target
-            if (activeTarget != -1) {
-                TargetDrawable target = targets.get(activeTarget);
-                if (target.hasState(TargetDrawable.STATE_FOCUSED)) {
-                    target.setState(TargetDrawable.STATE_FOCUSED);
-                }
-                if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-                    String targetContentDescription = getTargetDescription(activeTarget);
-                    announceText(targetContentDescription);
-                }
-                activateHandle(0, 0, 0.0f, null);
-            } else {
-                activateHandle(0, 0, 1.0f, null);
-            }
-        }
-        mActiveTarget = activeTarget;
-    }
-
-    @Override
-    public boolean onHoverEvent(MotionEvent event) {
-        if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) {
-            final int action = event.getAction();
-            switch (action) {
-                case MotionEvent.ACTION_HOVER_ENTER:
-                    event.setAction(MotionEvent.ACTION_DOWN);
-                    break;
-                case MotionEvent.ACTION_HOVER_MOVE:
-                    event.setAction(MotionEvent.ACTION_MOVE);
-                    break;
-                case MotionEvent.ACTION_HOVER_EXIT:
-                    event.setAction(MotionEvent.ACTION_UP);
-                    break;
-            }
-            onTouchEvent(event);
-            event.setAction(action);
-        }
-        return super.onHoverEvent(event);
-    }
-
-    /**
-     * Sets the current grabbed state, and dispatches a grabbed state change
-     * event to our listener.
-     */
-    private void setGrabbedState(int newState) {
-        if (newState != mGrabbedState) {
-            if (newState != OnTriggerListener.NO_HANDLE) {
-                vibrate();
-            }
-            mGrabbedState = newState;
-            if (mOnTriggerListener != null) {
-                if (newState == OnTriggerListener.NO_HANDLE) {
-                    mOnTriggerListener.onReleased(this, OnTriggerListener.CENTER_HANDLE);
-                } else {
-                    mOnTriggerListener.onGrabbed(this, OnTriggerListener.CENTER_HANDLE);
-                }
-                mOnTriggerListener.onGrabbedStateChange(this, newState);
-            }
-        }
-    }
-
-    private boolean trySwitchToFirstTouchState(float x, float y) {
-        final float tx = x - mWaveCenterX;
-        final float ty = y - mWaveCenterY;
-        if (mAlwaysTrackFinger || dist2(tx,ty) <= getScaledTapRadiusSquared()) {
-            if (DEBUG) Log.v(TAG, "** Handle HIT");
-            switchToState(STATE_FIRST_TOUCH, x, y);
-            moveHandleTo(tx, ty, false);
-            mDragging = true;
-            return true;
-        }
-        return false;
-    }
-
-    private void assignDefaultsIfNeeded() {
-        if (mOuterRadius == 0.0f) {
-            mOuterRadius = Math.max(mOuterRing.getWidth(), mOuterRing.getHeight())/2.0f;
-        }
-        if (mSnapMargin == 0.0f) {
-            mSnapMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                    SNAP_MARGIN_DEFAULT, getContext().getResources().getDisplayMetrics());
-        }
-    }
-
-    private void computeInsets(int dx, int dy) {
-        final int layoutDirection = getLayoutDirection();
-        final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection);
-
-        switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
-            case Gravity.LEFT:
-                mHorizontalInset = 0;
-                break;
-            case Gravity.RIGHT:
-                mHorizontalInset = dx;
-                break;
-            case Gravity.CENTER_HORIZONTAL:
-            default:
-                mHorizontalInset = dx / 2;
-                break;
-        }
-        switch (absoluteGravity & Gravity.VERTICAL_GRAVITY_MASK) {
-            case Gravity.TOP:
-                mVerticalInset = 0;
-                break;
-            case Gravity.BOTTOM:
-                mVerticalInset = dy;
-                break;
-            case Gravity.CENTER_VERTICAL:
-            default:
-                mVerticalInset = dy / 2;
-                break;
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        final int width = right - left;
-        final int height = bottom - top;
-
-        // Target placement width/height. This puts the targets on the greater of the ring
-        // width or the specified outer radius.
-        final float placementWidth = Math.max(mOuterRing.getWidth(), 2 * mOuterRadius);
-        final float placementHeight = Math.max(mOuterRing.getHeight(), 2 * mOuterRadius);
-        float newWaveCenterX = mHorizontalInset
-                + Math.max(width, mMaxTargetWidth + placementWidth) / 2;
-        float newWaveCenterY = mVerticalInset
-                + Math.max(height, + mMaxTargetHeight + placementHeight) / 2;
-
-        if (mInitialLayout) {
-            hideChevrons();
-            hideTargets(false, false);
-            moveHandleTo(0, 0, false);
-            mInitialLayout = false;
-        }
-
-        mOuterRing.setPositionX(newWaveCenterX);
-        mOuterRing.setPositionY(newWaveCenterY);
-
-        mHandleDrawable.setPositionX(newWaveCenterX);
-        mHandleDrawable.setPositionY(newWaveCenterY);
-
-        updateTargetPositions(newWaveCenterX, newWaveCenterY);
-        updateChevronPositions(newWaveCenterX, newWaveCenterY);
-
-        mWaveCenterX = newWaveCenterX;
-        mWaveCenterY = newWaveCenterY;
-
-        if (DEBUG) dump();
-    }
-
-    private void updateTargetPositions(float centerX, float centerY) {
-        // Reposition the target drawables if the view changed.
-        ArrayList<TargetDrawable> targets = mTargetDrawables;
-        final int size = targets.size();
-        final float alpha = (float) (-2.0f * Math.PI / size);
-        for (int i = 0; i < size; i++) {
-            final TargetDrawable targetIcon = targets.get(i);
-            final float angle = alpha * i;
-            targetIcon.setPositionX(centerX);
-            targetIcon.setPositionY(centerY);
-            targetIcon.setX(mOuterRadius * (float) Math.cos(angle));
-            targetIcon.setY(mOuterRadius * (float) Math.sin(angle));
-        }
-    }
-
-    private void updateChevronPositions(float centerX, float centerY) {
-        ArrayList<TargetDrawable> chevrons = mChevronDrawables;
-        final int size = chevrons.size();
-        for (int i = 0; i < size; i++) {
-            TargetDrawable target = chevrons.get(i);
-            if (target != null) {
-                target.setPositionX(centerX);
-                target.setPositionY(centerY);
-            }
-        }
-    }
-
-    private void hideChevrons() {
-        ArrayList<TargetDrawable> chevrons = mChevronDrawables;
-        final int size = chevrons.size();
-        for (int i = 0; i < size; i++) {
-            TargetDrawable chevron = chevrons.get(i);
-            if (chevron != null) {
-                chevron.setAlpha(0.0f);
-            }
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        mOuterRing.draw(canvas);
-        final int ntargets = mTargetDrawables.size();
-        for (int i = 0; i < ntargets; i++) {
-            TargetDrawable target = mTargetDrawables.get(i);
-            if (target != null) {
-                target.draw(canvas);
-            }
-        }
-        final int nchevrons = mChevronDrawables.size();
-        for (int i = 0; i < nchevrons; i++) {
-            TargetDrawable chevron = mChevronDrawables.get(i);
-            if (chevron != null) {
-                chevron.draw(canvas);
-            }
-        }
-        mHandleDrawable.draw(canvas);
-    }
-
-    public void setOnTriggerListener(OnTriggerListener listener) {
-        mOnTriggerListener = listener;
-    }
-
-    private float square(float d) {
-        return d * d;
-    }
-
-    private float dist2(float dx, float dy) {
-        return dx*dx + dy*dy;
-    }
-
-    private float getScaledTapRadiusSquared() {
-        final float scaledTapRadius;
-        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
-            scaledTapRadius = TAP_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mTapRadius;
-        } else {
-            scaledTapRadius = mTapRadius;
-        }
-        return square(scaledTapRadius);
-    }
-
-    private void announceTargets() {
-        StringBuilder utterance = new StringBuilder();
-        final int targetCount = mTargetDrawables.size();
-        for (int i = 0; i < targetCount; i++) {
-            String targetDescription = getTargetDescription(i);
-            String directionDescription = getDirectionDescription(i);
-            if (!TextUtils.isEmpty(targetDescription)
-                    && !TextUtils.isEmpty(directionDescription)) {
-                String text = String.format(directionDescription, targetDescription);
-                utterance.append(text);
-            }
-            if (utterance.length() > 0) {
-                announceText(utterance.toString());
-            }
-        }
-    }
-
-    private void announceText(String text) {
-        setContentDescription(text);
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-        setContentDescription(null);
-    }
-
-    private String getTargetDescription(int index) {
-        if (mTargetDescriptions == null || mTargetDescriptions.isEmpty()) {
-            mTargetDescriptions = loadDescriptions(mTargetDescriptionsResourceId);
-            if (mTargetDrawables.size() != mTargetDescriptions.size()) {
-                Log.w(TAG, "The number of target drawables must be"
-                        + " euqal to the number of target descriptions.");
-                return null;
-            }
-        }
-        return mTargetDescriptions.get(index);
-    }
-
-    private String getDirectionDescription(int index) {
-        if (mDirectionDescriptions == null || mDirectionDescriptions.isEmpty()) {
-            mDirectionDescriptions = loadDescriptions(mDirectionDescriptionsResourceId);
-            if (mTargetDrawables.size() != mDirectionDescriptions.size()) {
-                Log.w(TAG, "The number of target drawables must be"
-                        + " euqal to the number of direction descriptions.");
-                return null;
-            }
-        }
-        return mDirectionDescriptions.get(index);
-    }
-
-    private ArrayList<String> loadDescriptions(int resourceId) {
-        TypedArray array = getContext().getResources().obtainTypedArray(resourceId);
-        final int count = array.length();
-        ArrayList<String> targetContentDescriptions = new ArrayList<String>(count);
-        for (int i = 0; i < count; i++) {
-            String contentDescription = array.getString(i);
-            targetContentDescriptions.add(contentDescription);
-        }
-        array.recycle();
-        return targetContentDescriptions;
-    }
-
-    public int getResourceIdForTarget(int index) {
-        final TargetDrawable drawable = mTargetDrawables.get(index);
-        return drawable == null ? 0 : drawable.getResourceId();
-    }
-
-    public void setEnableTarget(int resourceId, boolean enabled) {
-        for (int i = 0; i < mTargetDrawables.size(); i++) {
-            final TargetDrawable target = mTargetDrawables.get(i);
-            if (target.getResourceId() == resourceId) {
-                target.setEnabled(enabled);
-                break; // should never be more than one match
-            }
-        }
-    }
-
-    /**
-     * Gets the position of a target in the array that matches the given resource.
-     * @param resourceId
-     * @return the index or -1 if not found
-     */
-    public int getTargetPosition(int resourceId) {
-        for (int i = 0; i < mTargetDrawables.size(); i++) {
-            final TargetDrawable target = mTargetDrawables.get(i);
-            if (target.getResourceId() == resourceId) {
-                return i; // should never be more than one match
-            }
-        }
-        return -1;
-    }
-
-    private boolean replaceTargetDrawables(Resources res, int existingResourceId,
-            int newResourceId) {
-        if (existingResourceId == 0 || newResourceId == 0) {
-            return false;
-        }
-
-        boolean result = false;
-        final ArrayList<TargetDrawable> drawables = mTargetDrawables;
-        final int size = drawables.size();
-        for (int i = 0; i < size; i++) {
-            final TargetDrawable target = drawables.get(i);
-            if (target != null && target.getResourceId() == existingResourceId) {
-                target.setDrawable(res, newResourceId);
-                result = true;
-            }
-        }
-
-        if (result) {
-            requestLayout(); // in case any given drawable's size changes
-        }
-
-        return result;
-    }
-
-    /**
-     * Searches the given package for a resource to use to replace the Drawable on the
-     * target with the given resource id
-     * @param component of the .apk that contains the resource
-     * @param name of the metadata in the .apk
-     * @param existingResId the resource id of the target to search for
-     * @return true if found in the given package and replaced at least one target Drawables
-     */
-    public boolean replaceTargetDrawablesIfPresent(ComponentName component, String name,
-                int existingResId) {
-        if (existingResId == 0) return false;
-
-        try {
-            PackageManager packageManager = mContext.getPackageManager();
-            // Look for the search icon specified in the activity meta-data
-            Bundle metaData = packageManager.getActivityInfo(
-                    component, PackageManager.GET_META_DATA).metaData;
-            if (metaData != null) {
-                int iconResId = metaData.getInt(name);
-                if (iconResId != 0) {
-                    Resources res = packageManager.getResourcesForActivity(component);
-                    return replaceTargetDrawables(res, existingResId, iconResId);
-                }
-            }
-        } catch (NameNotFoundException e) {
-            Log.w(TAG, "Failed to swap drawable; "
-                    + component.flattenToShortString() + " not found", e);
-        } catch (Resources.NotFoundException nfe) {
-            Log.w(TAG, "Failed to swap drawable from "
-                    + component.flattenToShortString(), nfe);
-        }
-        return false;
-    }
-}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index df7cde7..999bc57 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -6033,16 +6033,16 @@
     <eat-comment />
     <declare-styleable name="GlowPadView">
         <!-- Reference to an array resource that be shown as targets around a circle. -->
-        <attr name="targetDrawables"/>
+        <attr name="targetDrawables" format="reference" />
 
         <!-- Reference to an array resource that be used as description for the targets around the circle. -->
-        <attr name="targetDescriptions"/>
+        <attr name="targetDescriptions" format="reference" />
 
         <!-- Reference to an array resource that be used to announce the directions with targets around the circle. -->
-        <attr name="directionDescriptions"/>
+        <attr name="directionDescriptions" format="reference" />
 
         <!-- Sets a drawable as the center. -->
-        <attr name="handleDrawable"/>
+        <attr name="handleDrawable" format="reference" />
 
         <!-- Drawable to use for wave ripple animation. -->
         <attr name="outerRingDrawable" format="reference"/>
@@ -6054,22 +6054,22 @@
         <attr name="innerRadius"/>
 
         <!-- Outer radius of glow area. Target icons will be drawn on this circle. -->
-        <attr name="outerRadius"/>
+        <attr name="outerRadius" format="dimension" />
 
         <!-- Radius of glow under finger. -->
         <attr name="glowRadius" format="dimension" />
 
         <!-- Tactile feedback duration for actions. Set to '0' for no vibration. -->
-        <attr name="vibrationDuration"/>
+        <attr name="vibrationDuration" format="integer" />
 
         <!-- How close we need to be before snapping to a target. -->
-        <attr name="snapMargin"/>
+        <attr name="snapMargin" format="dimension" />
 
         <!-- Number of waves/chevrons to show in animation. -->
-        <attr name="feedbackCount"/>
+        <attr name="feedbackCount" format="integer" />
 
         <!-- Used when the handle shouldn't wait to be hit before following the finger -->
-        <attr name="alwaysTrackFinger"/>
+        <attr name="alwaysTrackFinger" format="boolean" />
 
         <!-- Location along the circle of the first item, in degrees.-->
         <attr name="firstItemOffset" format="float" />
@@ -6086,45 +6086,6 @@
     </declare-styleable>
 
     <!-- =============================== -->
-    <!-- MultiWaveView class attributes -->
-    <!-- =============================== -->
-    <eat-comment />
-    <declare-styleable name="MultiWaveView">
-        <!-- Reference to an array resource that be shown as targets around a circle. -->
-        <attr name="targetDrawables" format="reference"/>
-
-        <!-- Reference to an array resource that be used as description for the targets around the circle. -->
-        <attr name="targetDescriptions" format="reference"/>
-
-        <!-- Reference to an array resource that be used to announce the directions with targets around the circle. -->
-        <attr name="directionDescriptions" format="reference"/>
-
-        <!-- Sets a drawable as the drag center. -->
-        <attr name="handleDrawable" format="reference" />
-
-        <!-- Drawables to use for chevron animations. May be null. -->
-        <attr name="chevronDrawables" format="reference"/>
-
-        <!-- Drawable to use for wave ripple animation. -->
-        <attr name="waveDrawable" format="reference" />
-
-        <!-- Outer radius of target circle. Icons will be drawn on this circle. -->
-        <attr name="outerRadius" format="dimension" />
-
-        <!-- Tactile feedback duration for actions. Set to '0' for no vibration. -->
-        <attr name="vibrationDuration" format="integer"/>
-
-        <!-- How close we need to be before snapping to a target. -->
-        <attr name="snapMargin" format="dimension" />
-
-        <!-- Number of waves/chevrons to show in animation. -->
-        <attr name="feedbackCount" format="integer" />
-
-        <!-- Used when the handle shouldn't wait to be hit before following the finger -->
-        <attr name="alwaysTrackFinger" format="boolean" />
-    </declare-styleable>
-
-    <!-- =============================== -->
     <!-- SizeAdaptiveLayout class attributes -->
     <!-- =============================== -->
     <eat-comment />
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 1dd9300..77ab17b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -56,10 +56,10 @@
     <!-- Amount of time to hold off before showing the search panel when the user presses home -->
     <integer name="config_show_search_delay">200</integer>
 
-    <!-- Vibration duration for MultiWaveView used in SearchPanelView -->
+    <!-- Vibration duration for GlowPadView used in SearchPanelView -->
     <integer translatable="false" name="config_vibration_duration">0</integer>
 
-    <!-- Vibration duration for MultiWaveView used in SearchPanelView -->
+    <!-- Vibration duration for GlowPadView used in SearchPanelView -->
     <integer translatable="false" name="config_search_panel_view_vibration_duration">20</integer>
 
     <!-- The length of the vibration when the notification pops open. -->
