13060421045d4d9e411797f91bb509824b03e33fbJim Miller/* 23060421045d4d9e411797f91bb509824b03e33fbJim Miller * Copyright (C) 2010 The Android Open Source Project 33060421045d4d9e411797f91bb509824b03e33fbJim Miller * 43060421045d4d9e411797f91bb509824b03e33fbJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 53060421045d4d9e411797f91bb509824b03e33fbJim Miller * you may not use this file except in compliance with the License. 63060421045d4d9e411797f91bb509824b03e33fbJim Miller * You may obtain a copy of the License at 73060421045d4d9e411797f91bb509824b03e33fbJim Miller * 83060421045d4d9e411797f91bb509824b03e33fbJim Miller * http://www.apache.org/licenses/LICENSE-2.0 93060421045d4d9e411797f91bb509824b03e33fbJim Miller * 103060421045d4d9e411797f91bb509824b03e33fbJim Miller * Unless required by applicable law or agreed to in writing, software 113060421045d4d9e411797f91bb509824b03e33fbJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 123060421045d4d9e411797f91bb509824b03e33fbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133060421045d4d9e411797f91bb509824b03e33fbJim Miller * See the License for the specific language governing permissions and 143060421045d4d9e411797f91bb509824b03e33fbJim Miller * limitations under the License. 153060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 163060421045d4d9e411797f91bb509824b03e33fbJim Miller 173060421045d4d9e411797f91bb509824b03e33fbJim Millerpackage com.android.internal.widget; 183060421045d4d9e411797f91bb509824b03e33fbJim Miller 193060421045d4d9e411797f91bb509824b03e33fbJim Millerimport java.util.ArrayList; 203060421045d4d9e411797f91bb509824b03e33fbJim Miller 213060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.animation.ValueAnimator; 223060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.content.Context; 233060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.content.res.Resources; 243060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.Bitmap; 253060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.BitmapFactory; 263060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.Canvas; 273060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.graphics.drawable.BitmapDrawable; 287b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlockimport android.media.AudioAttributes; 29723a725e790d269f32980116e775d3d7f0037865Jeff Sharkeyimport android.os.UserHandle; 303060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.os.Vibrator; 31723a725e790d269f32980116e775d3d7f0037865Jeff Sharkeyimport android.provider.Settings; 323060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.util.AttributeSet; 333060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.util.Log; 343060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.view.MotionEvent; 353060421045d4d9e411797f91bb509824b03e33fbJim Millerimport android.view.View; 366033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 376033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganovimport android.view.accessibility.AccessibilityManager; 383060421045d4d9e411797f91bb509824b03e33fbJim Miller 393060421045d4d9e411797f91bb509824b03e33fbJim Millerimport com.android.internal.R; 403060421045d4d9e411797f91bb509824b03e33fbJim Miller 413060421045d4d9e411797f91bb509824b03e33fbJim Miller/** 423060421045d4d9e411797f91bb509824b03e33fbJim Miller * A special widget containing a center and outer ring. Moving the center ring to the outer ring 433060421045d4d9e411797f91bb509824b03e33fbJim Miller * causes an event that can be caught by implementing OnTriggerListener. 443060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 453060421045d4d9e411797f91bb509824b03e33fbJim Millerpublic class WaveView extends View implements ValueAnimator.AnimatorUpdateListener { 463060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final String TAG = "WaveView"; 473060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final boolean DBG = false; 483fa8a454f61c772036f5f38661d1a077fd3d8388Jim Miller private static final int WAVE_COUNT = 20; // default wave count 493060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long VIBRATE_SHORT = 20; // msec 503060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long VIBRATE_LONG = 20; // msec 513060421045d4d9e411797f91bb509824b03e33fbJim Miller 523060421045d4d9e411797f91bb509824b03e33fbJim Miller // Lock state machine states 533060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_RESET_LOCK = 0; 543060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_READY = 1; 553060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_START_ATTEMPT = 2; 563060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_ATTEMPTING = 3; 573060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_UNLOCK_ATTEMPT = 4; 583060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final int STATE_UNLOCK_SUCCESS = 5; 593060421045d4d9e411797f91bb509824b03e33fbJim Miller 603060421045d4d9e411797f91bb509824b03e33fbJim Miller // Animation properties. 610c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller private static final long DURATION = 300; // duration of transitional animations 620c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller private static final long FINAL_DURATION = 200; // duration of final animations when unlocking 630c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller private static final long RING_DELAY = 1300; // when to start fading animated rings 640c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller private static final long FINAL_DELAY = 200; // delay for unlock success animation 653060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long SHORT_DELAY = 100; // for starting one animation after another. 663060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long WAVE_DURATION = 2000; // amount of time for way to expand/decay 673060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long RESET_TIMEOUT = 3000; // elapsed time of inactivity before we reset 683060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long DELAY_INCREMENT = 15; // increment per wave while tracking motion 693060421045d4d9e411797f91bb509824b03e33fbJim Miller private static final long DELAY_INCREMENT2 = 12; // increment per wave while not tracking 703262a51a91655659741b3b02071ccaed258fc01fJim Miller private static final long WAVE_DELAY = WAVE_DURATION / WAVE_COUNT; // initial propagation delay 713060421045d4d9e411797f91bb509824b03e33fbJim Miller 726033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov /** 736033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * The scale by which to multiply the unlock handle width to compute the radius 746033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * in which it can be grabbed when accessibility is disabled. 756033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov */ 766033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED = 0.5f; 776033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 786033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov /** 796033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * The scale by which to multiply the unlock handle width to compute the radius 806033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * in which it can be grabbed when accessibility is enabled (more generous). 816033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov */ 826033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov private static final float GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED = 1.0f; 836033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 847b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder() 857b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 867b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) 877b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock .build(); 887b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock 893060421045d4d9e411797f91bb509824b03e33fbJim Miller private Vibrator mVibrator; 903060421045d4d9e411797f91bb509824b03e33fbJim Miller private OnTriggerListener mOnTriggerListener; 913060421045d4d9e411797f91bb509824b03e33fbJim Miller private ArrayList<DrawableHolder> mDrawables = new ArrayList<DrawableHolder>(3); 923060421045d4d9e411797f91bb509824b03e33fbJim Miller private ArrayList<DrawableHolder> mLightWaves = new ArrayList<DrawableHolder>(WAVE_COUNT); 933060421045d4d9e411797f91bb509824b03e33fbJim Miller private boolean mFingerDown = false; 943060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mRingRadius = 182.0f; // Radius of bitmap ring. Used to snap halo to it 953060421045d4d9e411797f91bb509824b03e33fbJim Miller private int mSnapRadius = 136; // minimum threshold for drag unlock 963060421045d4d9e411797f91bb509824b03e33fbJim Miller private int mWaveCount = WAVE_COUNT; // number of waves 973262a51a91655659741b3b02071ccaed258fc01fJim Miller private long mWaveTimerDelay = WAVE_DELAY; 983060421045d4d9e411797f91bb509824b03e33fbJim Miller private int mCurrentWave = 0; 993060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mLockCenterX; // center of widget as dictated by widget size 1003060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mLockCenterY; 1013060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mMouseX; // current mouse position as of last touch event 1023060421045d4d9e411797f91bb509824b03e33fbJim Miller private float mMouseY; 1033060421045d4d9e411797f91bb509824b03e33fbJim Miller private DrawableHolder mUnlockRing; 1043060421045d4d9e411797f91bb509824b03e33fbJim Miller private DrawableHolder mUnlockDefault; 1053060421045d4d9e411797f91bb509824b03e33fbJim Miller private DrawableHolder mUnlockHalo; 1063060421045d4d9e411797f91bb509824b03e33fbJim Miller private int mLockState = STATE_RESET_LOCK; 1073060421045d4d9e411797f91bb509824b03e33fbJim Miller private int mGrabbedState = OnTriggerListener.NO_HANDLE; 1088996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller private boolean mWavesRunning; 1098996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller private boolean mFinishWaves; 1103060421045d4d9e411797f91bb509824b03e33fbJim Miller 1113060421045d4d9e411797f91bb509824b03e33fbJim Miller public WaveView(Context context) { 1123060421045d4d9e411797f91bb509824b03e33fbJim Miller this(context, null); 1133060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1143060421045d4d9e411797f91bb509824b03e33fbJim Miller 1153060421045d4d9e411797f91bb509824b03e33fbJim Miller public WaveView(Context context, AttributeSet attrs) { 1163060421045d4d9e411797f91bb509824b03e33fbJim Miller super(context, attrs); 1173060421045d4d9e411797f91bb509824b03e33fbJim Miller 1183060421045d4d9e411797f91bb509824b03e33fbJim Miller // TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WaveView); 1193060421045d4d9e411797f91bb509824b03e33fbJim Miller // mOrientation = a.getInt(R.styleable.WaveView_orientation, HORIZONTAL); 1203060421045d4d9e411797f91bb509824b03e33fbJim Miller // a.recycle(); 1213060421045d4d9e411797f91bb509824b03e33fbJim Miller 1223060421045d4d9e411797f91bb509824b03e33fbJim Miller initDrawables(); 1233060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1243060421045d4d9e411797f91bb509824b03e33fbJim Miller 1253060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 1263060421045d4d9e411797f91bb509824b03e33fbJim Miller protected void onSizeChanged(int w, int h, int oldw, int oldh) { 1273060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockCenterX = 0.5f * w; 1283060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockCenterY = 0.5f * h; 1293060421045d4d9e411797f91bb509824b03e33fbJim Miller super.onSizeChanged(w, h, oldw, oldh); 1303060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1313060421045d4d9e411797f91bb509824b03e33fbJim Miller 1323060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 1333060421045d4d9e411797f91bb509824b03e33fbJim Miller protected int getSuggestedMinimumWidth() { 1343060421045d4d9e411797f91bb509824b03e33fbJim Miller // View should be large enough to contain the unlock ring + halo 1353060421045d4d9e411797f91bb509824b03e33fbJim Miller return mUnlockRing.getWidth() + mUnlockHalo.getWidth(); 1363060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1373060421045d4d9e411797f91bb509824b03e33fbJim Miller 1383060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 1393060421045d4d9e411797f91bb509824b03e33fbJim Miller protected int getSuggestedMinimumHeight() { 1403060421045d4d9e411797f91bb509824b03e33fbJim Miller // View should be large enough to contain the unlock ring + halo 1413060421045d4d9e411797f91bb509824b03e33fbJim Miller return mUnlockRing.getHeight() + mUnlockHalo.getHeight(); 1423060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1433060421045d4d9e411797f91bb509824b03e33fbJim Miller 1443060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 1453060421045d4d9e411797f91bb509824b03e33fbJim Miller protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 1463060421045d4d9e411797f91bb509824b03e33fbJim Miller int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 1473060421045d4d9e411797f91bb509824b03e33fbJim Miller int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 1483060421045d4d9e411797f91bb509824b03e33fbJim Miller int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 1493060421045d4d9e411797f91bb509824b03e33fbJim Miller int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 1503060421045d4d9e411797f91bb509824b03e33fbJim Miller int width; 1513060421045d4d9e411797f91bb509824b03e33fbJim Miller int height; 1523060421045d4d9e411797f91bb509824b03e33fbJim Miller 1533060421045d4d9e411797f91bb509824b03e33fbJim Miller if (widthSpecMode == MeasureSpec.AT_MOST) { 1543060421045d4d9e411797f91bb509824b03e33fbJim Miller width = Math.min(widthSpecSize, getSuggestedMinimumWidth()); 1553060421045d4d9e411797f91bb509824b03e33fbJim Miller } else if (widthSpecMode == MeasureSpec.EXACTLY) { 1563060421045d4d9e411797f91bb509824b03e33fbJim Miller width = widthSpecSize; 1573060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 1583060421045d4d9e411797f91bb509824b03e33fbJim Miller width = getSuggestedMinimumWidth(); 1593060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1603060421045d4d9e411797f91bb509824b03e33fbJim Miller 1613060421045d4d9e411797f91bb509824b03e33fbJim Miller if (heightSpecMode == MeasureSpec.AT_MOST) { 1623060421045d4d9e411797f91bb509824b03e33fbJim Miller height = Math.min(heightSpecSize, getSuggestedMinimumWidth()); 1633060421045d4d9e411797f91bb509824b03e33fbJim Miller } else if (heightSpecMode == MeasureSpec.EXACTLY) { 1643060421045d4d9e411797f91bb509824b03e33fbJim Miller height = heightSpecSize; 1653060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 1663060421045d4d9e411797f91bb509824b03e33fbJim Miller height = getSuggestedMinimumHeight(); 1673060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1683060421045d4d9e411797f91bb509824b03e33fbJim Miller 1693060421045d4d9e411797f91bb509824b03e33fbJim Miller setMeasuredDimension(width, height); 1703060421045d4d9e411797f91bb509824b03e33fbJim Miller } 1713060421045d4d9e411797f91bb509824b03e33fbJim Miller 1723060421045d4d9e411797f91bb509824b03e33fbJim Miller private void initDrawables() { 173c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing = new DrawableHolder(createDrawable(R.drawable.unlock_ring)); 174c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing.setX(mLockCenterX); 175c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing.setY(mLockCenterY); 176c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing.setScaleX(0.1f); 177c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing.setScaleY(0.1f); 178c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockRing.setAlpha(0.0f); 1793060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawables.add(mUnlockRing); 1803060421045d4d9e411797f91bb509824b03e33fbJim Miller 181c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault = new DrawableHolder(createDrawable(R.drawable.unlock_default)); 182c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setX(mLockCenterX); 183c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setY(mLockCenterY); 184c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleX(0.1f); 185c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleY(0.1f); 186c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setAlpha(0.0f); 1873060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawables.add(mUnlockDefault); 1883060421045d4d9e411797f91bb509824b03e33fbJim Miller 189c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo = new DrawableHolder(createDrawable(R.drawable.unlock_halo)); 190c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setX(mLockCenterX); 191c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setY(mLockCenterY); 192c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setScaleX(0.1f); 193c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setScaleY(0.1f); 194c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setAlpha(0.0f); 1953060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawables.add(mUnlockHalo); 1963060421045d4d9e411797f91bb509824b03e33fbJim Miller 1973060421045d4d9e411797f91bb509824b03e33fbJim Miller BitmapDrawable wave = createDrawable(R.drawable.unlock_wave); 1983060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mWaveCount; i++) { 1993060421045d4d9e411797f91bb509824b03e33fbJim Miller DrawableHolder holder = new DrawableHolder(wave); 2003060421045d4d9e411797f91bb509824b03e33fbJim Miller mLightWaves.add(holder); 2013060421045d4d9e411797f91bb509824b03e33fbJim Miller holder.setAlpha(0.0f); 2023060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2033060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2043060421045d4d9e411797f91bb509824b03e33fbJim Miller 2053060421045d4d9e411797f91bb509824b03e33fbJim Miller private void waveUpdateFrame(float mouseX, float mouseY, boolean fingerDown) { 2063060421045d4d9e411797f91bb509824b03e33fbJim Miller double distX = mouseX - mLockCenterX; 2073060421045d4d9e411797f91bb509824b03e33fbJim Miller double distY = mouseY - mLockCenterY; 2083060421045d4d9e411797f91bb509824b03e33fbJim Miller int dragDistance = (int) Math.ceil(Math.hypot(distX, distY)); 2093060421045d4d9e411797f91bb509824b03e33fbJim Miller double touchA = Math.atan2(distX, distY); 2103060421045d4d9e411797f91bb509824b03e33fbJim Miller float ringX = (float) (mLockCenterX + mRingRadius * Math.sin(touchA)); 2113060421045d4d9e411797f91bb509824b03e33fbJim Miller float ringY = (float) (mLockCenterY + mRingRadius * Math.cos(touchA)); 2123060421045d4d9e411797f91bb509824b03e33fbJim Miller 2133060421045d4d9e411797f91bb509824b03e33fbJim Miller switch (mLockState) { 2143060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_RESET_LOCK: 2153060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "State RESET_LOCK"); 2163262a51a91655659741b3b02071ccaed258fc01fJim Miller mWaveTimerDelay = WAVE_DELAY; 2173060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mLightWaves.size(); i++) { 2183060421045d4d9e411797f91bb509824b03e33fbJim Miller DrawableHolder holder = mLightWaves.get(i); 2193060421045d4d9e411797f91bb509824b03e33fbJim Miller holder.addAnimTo(300, 0, "alpha", 0.0f, false); 2203060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2213060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mLightWaves.size(); i++) { 2223060421045d4d9e411797f91bb509824b03e33fbJim Miller mLightWaves.get(i).startAnimations(this); 2233060421045d4d9e411797f91bb509824b03e33fbJim Miller } 2243060421045d4d9e411797f91bb509824b03e33fbJim Miller 2253060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "x", mLockCenterX, true); 2263060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "y", mLockCenterY, true); 2273060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "scaleX", 0.1f, true); 2283060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "scaleY", 0.1f, true); 2293060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "alpha", 0.0f, true); 2303060421045d4d9e411797f91bb509824b03e33fbJim Miller 2313060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("x"); 2323060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("y"); 2333060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleX"); 2343060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleY"); 2353060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("alpha"); 236c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setX(mLockCenterX); 237c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setY(mLockCenterY); 238c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleX(0.1f); 239c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleY(0.1f); 240c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setAlpha(0.0f); 2413060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "scaleX", 1.0f, true); 2423060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "scaleY", 1.0f, true); 2433060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "alpha", 1.0f, true); 2443060421045d4d9e411797f91bb509824b03e33fbJim Miller 2453060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.removeAnimationFor("x"); 2463060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.removeAnimationFor("y"); 2473060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.removeAnimationFor("scaleX"); 2483060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.removeAnimationFor("scaleY"); 2493060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.removeAnimationFor("alpha"); 250c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setX(mLockCenterX); 251c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setY(mLockCenterY); 252c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setScaleX(0.1f); 253c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setScaleY(0.1f); 254c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockHalo.setAlpha(0.0f); 2553060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(DURATION, SHORT_DELAY, "x", mLockCenterX, true); 2563060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(DURATION, SHORT_DELAY, "y", mLockCenterY, true); 2573060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(DURATION, SHORT_DELAY, "scaleX", 1.0f, true); 2583060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(DURATION, SHORT_DELAY, "scaleY", 1.0f, true); 2593060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(DURATION, SHORT_DELAY, "alpha", 1.0f, true); 2603060421045d4d9e411797f91bb509824b03e33fbJim Miller 2613060421045d4d9e411797f91bb509824b03e33fbJim Miller removeCallbacks(mLockTimerActions); 2623060421045d4d9e411797f91bb509824b03e33fbJim Miller 2633060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_READY; 2643060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 2653060421045d4d9e411797f91bb509824b03e33fbJim Miller 2663060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_READY: 2673060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "State READY"); 2688996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller mWaveTimerDelay = WAVE_DELAY; 2693060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 2703060421045d4d9e411797f91bb509824b03e33fbJim Miller 2713060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_START_ATTEMPT: 2723060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "State START_ATTEMPT"); 2733060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("x"); 2743060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("y"); 2753060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleX"); 2763060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleY"); 2773060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("alpha"); 278c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setX(mLockCenterX + 182); 279c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setY(mLockCenterY); 280c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleX(0.1f); 281c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleY(0.1f); 282c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setAlpha(0.0f); 2833060421045d4d9e411797f91bb509824b03e33fbJim Miller 2843060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "scaleX", 1.0f, false); 2853060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "scaleY", 1.0f, false); 2863060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.addAnimTo(DURATION, SHORT_DELAY, "alpha", 1.0f, false); 2873060421045d4d9e411797f91bb509824b03e33fbJim Miller 2883060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "scaleX", 1.0f, true); 2893060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "scaleY", 1.0f, true); 2903060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.addAnimTo(DURATION, 0, "alpha", 1.0f, true); 2913060421045d4d9e411797f91bb509824b03e33fbJim Miller 2923060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_ATTEMPTING; 2933060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 2943060421045d4d9e411797f91bb509824b03e33fbJim Miller 2953060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_ATTEMPTING: 296ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller if (DBG) Log.v(TAG, "State ATTEMPTING (fingerDown = " + fingerDown + ")"); 2973060421045d4d9e411797f91bb509824b03e33fbJim Miller if (dragDistance > mSnapRadius) { 2988996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller mFinishWaves = true; // don't start any more waves. 2993060421045d4d9e411797f91bb509824b03e33fbJim Miller if (fingerDown) { 3003060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "x", ringX, true); 3013060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "y", ringY, true); 3023060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "scaleX", 1.0f, true); 3033060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "scaleY", 1.0f, true); 3043060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "alpha", 1.0f, true); 3053060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 306ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller if (DBG) Log.v(TAG, "up detected, moving to STATE_UNLOCK_ATTEMPT"); 3073060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_UNLOCK_ATTEMPT; 3083060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3093060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 3108996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller // If waves have stopped, we need to kick them off again... 3118996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller if (!mWavesRunning) { 3128996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller mWavesRunning = true; 3138996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller mFinishWaves = false; 3148996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller // mWaveTimerDelay = WAVE_DELAY; 3158996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller postDelayed(mAddWaveAction, mWaveTimerDelay); 3168996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller } 3173060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "x", mouseX, true); 3183060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "y", mouseY, true); 3193060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "scaleX", 1.0f, true); 3203060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "scaleY", 1.0f, true); 3213060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.addAnimTo(0, 0, "alpha", 1.0f, true); 3223060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3233060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 3243060421045d4d9e411797f91bb509824b03e33fbJim Miller 3253060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_UNLOCK_ATTEMPT: 3263060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "State UNLOCK_ATTEMPT"); 3273060421045d4d9e411797f91bb509824b03e33fbJim Miller if (dragDistance > mSnapRadius) { 3283060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int n = 0; n < mLightWaves.size(); n++) { 3293060421045d4d9e411797f91bb509824b03e33fbJim Miller DrawableHolder wave = mLightWaves.get(n); 3303060421045d4d9e411797f91bb509824b03e33fbJim Miller long delay = 1000L*(6 + n - mCurrentWave)/10L; 3310c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(FINAL_DURATION, delay, "x", ringX, true); 3320c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(FINAL_DURATION, delay, "y", ringY, true); 3330c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(FINAL_DURATION, delay, "scaleX", 0.1f, true); 3340c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(FINAL_DURATION, delay, "scaleY", 0.1f, true); 3350c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(FINAL_DURATION, delay, "alpha", 0.0f, true); 3363060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3373060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mLightWaves.size(); i++) { 3383060421045d4d9e411797f91bb509824b03e33fbJim Miller mLightWaves.get(i).startAnimations(this); 3393060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3403060421045d4d9e411797f91bb509824b03e33fbJim Miller 3410c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, 0, "x", ringX, false); 3420c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, 0, "y", ringY, false); 3430c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, 0, "scaleX", 0.1f, false); 3440c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, 0, "scaleY", 0.1f, false); 3450c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, 0, "alpha", 0.0f, false); 3463060421045d4d9e411797f91bb509824b03e33fbJim Miller 3470c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockRing.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false); 3483060421045d4d9e411797f91bb509824b03e33fbJim Miller 3493060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("x"); 3503060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("y"); 3513060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleX"); 3523060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("scaleY"); 3533060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.removeAnimationFor("alpha"); 354c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setX(ringX); 355c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setY(ringY); 356c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleX(0.1f); 357c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setScaleY(0.1f); 358c002fab06d5f6d3c83bb2b89c8ee9a14f6580af3Jim Miller mUnlockDefault.setAlpha(0.0f); 3593060421045d4d9e411797f91bb509824b03e33fbJim Miller 3600c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "x", ringX, true); 3610c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "y", ringY, true); 3620c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "scaleX", 1.0f, true); 3630c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "scaleY", 1.0f, true); 3640c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "alpha", 1.0f, true); 3653060421045d4d9e411797f91bb509824b03e33fbJim Miller 3660c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleX", 3.0f, false); 3670c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleY", 3.0f, false); 3680c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false); 3693060421045d4d9e411797f91bb509824b03e33fbJim Miller 3700c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockHalo.addAnimTo(FINAL_DURATION, 0, "x", ringX, false); 3710c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockHalo.addAnimTo(FINAL_DURATION, 0, "y", ringY, false); 3723060421045d4d9e411797f91bb509824b03e33fbJim Miller 3730c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleX", 3.0f, false); 3740c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleY", 3.0f, false); 3750c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false); 3763060421045d4d9e411797f91bb509824b03e33fbJim Miller 3773060421045d4d9e411797f91bb509824b03e33fbJim Miller removeCallbacks(mLockTimerActions); 3783060421045d4d9e411797f91bb509824b03e33fbJim Miller 3793060421045d4d9e411797f91bb509824b03e33fbJim Miller postDelayed(mLockTimerActions, RESET_TIMEOUT); 3803060421045d4d9e411797f91bb509824b03e33fbJim Miller 3813060421045d4d9e411797f91bb509824b03e33fbJim Miller dispatchTriggerEvent(OnTriggerListener.CENTER_HANDLE); 3823060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_UNLOCK_SUCCESS; 3833060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 3843060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_RESET_LOCK; 3853060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3863060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 3873060421045d4d9e411797f91bb509824b03e33fbJim Miller 3883060421045d4d9e411797f91bb509824b03e33fbJim Miller case STATE_UNLOCK_SUCCESS: 3893060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "State UNLOCK_SUCCESS"); 3903060421045d4d9e411797f91bb509824b03e33fbJim Miller removeCallbacks(mAddWaveAction); 3913060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 3923060421045d4d9e411797f91bb509824b03e33fbJim Miller 3933060421045d4d9e411797f91bb509824b03e33fbJim Miller default: 3943060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "Unknown state " + mLockState); 3953060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 3963060421045d4d9e411797f91bb509824b03e33fbJim Miller } 3973060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockDefault.startAnimations(this); 3983060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockHalo.startAnimations(this); 3993060421045d4d9e411797f91bb509824b03e33fbJim Miller mUnlockRing.startAnimations(this); 4003060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4013060421045d4d9e411797f91bb509824b03e33fbJim Miller 4023060421045d4d9e411797f91bb509824b03e33fbJim Miller BitmapDrawable createDrawable(int resId) { 4033060421045d4d9e411797f91bb509824b03e33fbJim Miller Resources res = getResources(); 4043060421045d4d9e411797f91bb509824b03e33fbJim Miller Bitmap bitmap = BitmapFactory.decodeResource(res, resId); 4053060421045d4d9e411797f91bb509824b03e33fbJim Miller return new BitmapDrawable(res, bitmap); 4063060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4073060421045d4d9e411797f91bb509824b03e33fbJim Miller 4083060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 4093060421045d4d9e411797f91bb509824b03e33fbJim Miller protected void onDraw(Canvas canvas) { 4103060421045d4d9e411797f91bb509824b03e33fbJim Miller waveUpdateFrame(mMouseX, mMouseY, mFingerDown); 4113060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mDrawables.size(); ++i) { 4123060421045d4d9e411797f91bb509824b03e33fbJim Miller mDrawables.get(i).draw(canvas); 4133060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4143060421045d4d9e411797f91bb509824b03e33fbJim Miller for (int i = 0; i < mLightWaves.size(); ++i) { 4153060421045d4d9e411797f91bb509824b03e33fbJim Miller mLightWaves.get(i).draw(canvas); 4163060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4173060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4183060421045d4d9e411797f91bb509824b03e33fbJim Miller 4193060421045d4d9e411797f91bb509824b03e33fbJim Miller private final Runnable mLockTimerActions = new Runnable() { 4203060421045d4d9e411797f91bb509824b03e33fbJim Miller public void run() { 4213060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "LockTimerActions"); 4223060421045d4d9e411797f91bb509824b03e33fbJim Miller // reset lock after inactivity 4233060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mLockState == STATE_ATTEMPTING) { 424607d320c9d18a57350bef72cc74017366ffd04ecJim Miller if (DBG) Log.v(TAG, "Timer resets to STATE_RESET_LOCK"); 4253060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_RESET_LOCK; 4263060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4273060421045d4d9e411797f91bb509824b03e33fbJim Miller // for prototype, reset after successful unlock 4283060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mLockState == STATE_UNLOCK_SUCCESS) { 429607d320c9d18a57350bef72cc74017366ffd04ecJim Miller if (DBG) Log.v(TAG, "Timer resets to STATE_RESET_LOCK after success"); 4303060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_RESET_LOCK; 4313060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4323060421045d4d9e411797f91bb509824b03e33fbJim Miller invalidate(); 4333060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4343060421045d4d9e411797f91bb509824b03e33fbJim Miller }; 4353060421045d4d9e411797f91bb509824b03e33fbJim Miller 4363060421045d4d9e411797f91bb509824b03e33fbJim Miller private final Runnable mAddWaveAction = new Runnable() { 4373060421045d4d9e411797f91bb509824b03e33fbJim Miller public void run() { 4383060421045d4d9e411797f91bb509824b03e33fbJim Miller double distX = mMouseX - mLockCenterX; 4393060421045d4d9e411797f91bb509824b03e33fbJim Miller double distY = mMouseY - mLockCenterY; 4403060421045d4d9e411797f91bb509824b03e33fbJim Miller int dragDistance = (int) Math.ceil(Math.hypot(distX, distY)); 4413060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mLockState == STATE_ATTEMPTING && dragDistance < mSnapRadius 4423262a51a91655659741b3b02071ccaed258fc01fJim Miller && mWaveTimerDelay >= WAVE_DELAY) { 4433060421045d4d9e411797f91bb509824b03e33fbJim Miller mWaveTimerDelay = Math.min(WAVE_DURATION, mWaveTimerDelay + DELAY_INCREMENT); 4443060421045d4d9e411797f91bb509824b03e33fbJim Miller 4453060421045d4d9e411797f91bb509824b03e33fbJim Miller DrawableHolder wave = mLightWaves.get(mCurrentWave); 4463060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.setAlpha(0.0f); 4473060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.setScaleX(0.2f); 4483060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.setScaleY(0.2f); 4493060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.setX(mMouseX); 4503060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.setY(mMouseY); 4513060421045d4d9e411797f91bb509824b03e33fbJim Miller 4523060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.addAnimTo(WAVE_DURATION, 0, "x", mLockCenterX, true); 4533060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.addAnimTo(WAVE_DURATION, 0, "y", mLockCenterY, true); 4543060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.addAnimTo(WAVE_DURATION*2/3, 0, "alpha", 1.0f, true); 4553060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.addAnimTo(WAVE_DURATION, 0, "scaleX", 1.0f, true); 4563060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.addAnimTo(WAVE_DURATION, 0, "scaleY", 1.0f, true); 4573060421045d4d9e411797f91bb509824b03e33fbJim Miller 4580c91a8ee9321da4dee17f0aeffbc20b0c5bb0644Jim Miller wave.addAnimTo(1000, RING_DELAY, "alpha", 0.0f, false); 4593060421045d4d9e411797f91bb509824b03e33fbJim Miller wave.startAnimations(WaveView.this); 4603060421045d4d9e411797f91bb509824b03e33fbJim Miller 4613060421045d4d9e411797f91bb509824b03e33fbJim Miller mCurrentWave = (mCurrentWave+1) % mWaveCount; 4623060421045d4d9e411797f91bb509824b03e33fbJim Miller if (DBG) Log.v(TAG, "WaveTimerDelay: start new wave in " + mWaveTimerDelay); 4633060421045d4d9e411797f91bb509824b03e33fbJim Miller } else { 4643060421045d4d9e411797f91bb509824b03e33fbJim Miller mWaveTimerDelay += DELAY_INCREMENT2; 4653060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4668996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller if (mFinishWaves) { 4678996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller // sentinel used to restart the waves after they've stopped 4688996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller mWavesRunning = false; 4698996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller } else { 4708996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller postDelayed(mAddWaveAction, mWaveTimerDelay); 4718996cf071abf5e6a6458da258a1d59bcaafc3c2cJim Miller } 4723060421045d4d9e411797f91bb509824b03e33fbJim Miller } 4733060421045d4d9e411797f91bb509824b03e33fbJim Miller }; 4743060421045d4d9e411797f91bb509824b03e33fbJim Miller 4753060421045d4d9e411797f91bb509824b03e33fbJim Miller @Override 4766033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov public boolean onHoverEvent(MotionEvent event) { 4776033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov if (AccessibilityManager.getInstance(mContext).isTouchExplorationEnabled()) { 4786033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov final int action = event.getAction(); 4796033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov switch (action) { 4806033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov case MotionEvent.ACTION_HOVER_ENTER: 4816033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov event.setAction(MotionEvent.ACTION_DOWN); 4826033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov break; 4836033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov case MotionEvent.ACTION_HOVER_MOVE: 4846033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov event.setAction(MotionEvent.ACTION_MOVE); 4856033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov break; 4866033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov case MotionEvent.ACTION_HOVER_EXIT: 4876033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov event.setAction(MotionEvent.ACTION_UP); 4886033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov break; 4896033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 4906033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov onTouchEvent(event); 4916033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov event.setAction(action); 4926033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 4936033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov return super.onHoverEvent(event); 4946033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 4956033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 4966033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov @Override 4973060421045d4d9e411797f91bb509824b03e33fbJim Miller public boolean onTouchEvent(MotionEvent event) { 4983060421045d4d9e411797f91bb509824b03e33fbJim Miller final int action = event.getAction(); 4993060421045d4d9e411797f91bb509824b03e33fbJim Miller mMouseX = event.getX(); 5003060421045d4d9e411797f91bb509824b03e33fbJim Miller mMouseY = event.getY(); 5013060421045d4d9e411797f91bb509824b03e33fbJim Miller boolean handled = false; 5023060421045d4d9e411797f91bb509824b03e33fbJim Miller switch (action) { 5033060421045d4d9e411797f91bb509824b03e33fbJim Miller case MotionEvent.ACTION_DOWN: 5043060421045d4d9e411797f91bb509824b03e33fbJim Miller removeCallbacks(mLockTimerActions); 5053060421045d4d9e411797f91bb509824b03e33fbJim Miller mFingerDown = true; 5066033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov tryTransitionToStartAttemptState(event); 5073060421045d4d9e411797f91bb509824b03e33fbJim Miller handled = true; 5083060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 5093060421045d4d9e411797f91bb509824b03e33fbJim Miller 5103060421045d4d9e411797f91bb509824b03e33fbJim Miller case MotionEvent.ACTION_MOVE: 5116033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov tryTransitionToStartAttemptState(event); 5123060421045d4d9e411797f91bb509824b03e33fbJim Miller handled = true; 5133060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 5143060421045d4d9e411797f91bb509824b03e33fbJim Miller 5153060421045d4d9e411797f91bb509824b03e33fbJim Miller case MotionEvent.ACTION_UP: 516ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller if (DBG) Log.v(TAG, "ACTION_UP"); 5173060421045d4d9e411797f91bb509824b03e33fbJim Miller mFingerDown = false; 5183060421045d4d9e411797f91bb509824b03e33fbJim Miller postDelayed(mLockTimerActions, RESET_TIMEOUT); 5193060421045d4d9e411797f91bb509824b03e33fbJim Miller setGrabbedState(OnTriggerListener.NO_HANDLE); 520ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller // Normally the state machine is driven by user interaction causing redraws. 521ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller // However, when there's no more user interaction and no running animations, 522ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller // the state machine stops advancing because onDraw() never gets called. 523ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller // The following ensures we advance to the next state in this case, 524ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller // either STATE_UNLOCK_ATTEMPT or STATE_RESET_LOCK. 525ec6ac82a295b80a39f12ff7951ec254ba45809fdJim Miller waveUpdateFrame(mMouseX, mMouseY, mFingerDown); 5263060421045d4d9e411797f91bb509824b03e33fbJim Miller handled = true; 5273060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 5283060421045d4d9e411797f91bb509824b03e33fbJim Miller 5293060421045d4d9e411797f91bb509824b03e33fbJim Miller case MotionEvent.ACTION_CANCEL: 5303060421045d4d9e411797f91bb509824b03e33fbJim Miller mFingerDown = false; 5313060421045d4d9e411797f91bb509824b03e33fbJim Miller handled = true; 5323060421045d4d9e411797f91bb509824b03e33fbJim Miller break; 5333060421045d4d9e411797f91bb509824b03e33fbJim Miller } 5343060421045d4d9e411797f91bb509824b03e33fbJim Miller invalidate(); 5353060421045d4d9e411797f91bb509824b03e33fbJim Miller return handled ? true : super.onTouchEvent(event); 5363060421045d4d9e411797f91bb509824b03e33fbJim Miller } 5373060421045d4d9e411797f91bb509824b03e33fbJim Miller 5383060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 5396033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * Tries to transition to start attempt state. 5406033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * 5416033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * @param event A motion event. 5426033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov */ 5436033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov private void tryTransitionToStartAttemptState(MotionEvent event) { 5446033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov final float dx = event.getX() - mUnlockHalo.getX(); 5456033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov final float dy = event.getY() - mUnlockHalo.getY(); 5466033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov float dist = (float) Math.hypot(dx, dy); 5476033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov if (dist <= getScaledGrabHandleRadius()) { 5486033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov setGrabbedState(OnTriggerListener.CENTER_HANDLE); 5496033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov if (mLockState == STATE_READY) { 5506033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov mLockState = STATE_START_ATTEMPT; 5516033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov if (AccessibilityManager.getInstance(mContext).isEnabled()) { 5526033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov announceUnlockHandle(); 5536033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5546033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5556033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5566033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5576033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 5586033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov /** 5596033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * @return The radius in which the handle is grabbed scaled based on 5606033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * whether accessibility is enabled. 5616033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov */ 5626033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov private float getScaledGrabHandleRadius() { 5636033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov if (AccessibilityManager.getInstance(mContext).isEnabled()) { 5646033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_ENABLED * mUnlockHalo.getWidth(); 5656033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } else { 5666033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov return GRAB_HANDLE_RADIUS_SCALE_ACCESSIBILITY_DISABLED * mUnlockHalo.getWidth(); 5676033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5686033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5696033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 5706033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov /** 5716033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov * Announces the unlock handle if accessibility is enabled. 5726033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov */ 5736033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov private void announceUnlockHandle() { 5746033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov setContentDescription(mContext.getString(R.string.description_target_unlock_tablet)); 5756033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); 5766033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov setContentDescription(null); 5776033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov } 5786033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov 5796033c0817427386cd3e95a992d1f34dad4188f96Svetoslav Ganov /** 5803060421045d4d9e411797f91bb509824b03e33fbJim Miller * Triggers haptic feedback. 5813060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 5823060421045d4d9e411797f91bb509824b03e33fbJim Miller private synchronized void vibrate(long duration) { 583723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey final boolean hapticEnabled = Settings.System.getIntForUser( 584723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, 585723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey UserHandle.USER_CURRENT) != 0; 586723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey if (hapticEnabled) { 587723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey if (mVibrator == null) { 588723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey mVibrator = (android.os.Vibrator) getContext() 589723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey .getSystemService(Context.VIBRATOR_SERVICE); 590723a725e790d269f32980116e775d3d7f0037865Jeff Sharkey } 5917b41467704f941b11af6aace3e40993afc7f6c6fJohn Spurlock mVibrator.vibrate(duration, VIBRATION_ATTRIBUTES); 5923060421045d4d9e411797f91bb509824b03e33fbJim Miller } 5933060421045d4d9e411797f91bb509824b03e33fbJim Miller } 5943060421045d4d9e411797f91bb509824b03e33fbJim Miller 5953060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 5963060421045d4d9e411797f91bb509824b03e33fbJim Miller * Registers a callback to be invoked when the user triggers an event. 5973060421045d4d9e411797f91bb509824b03e33fbJim Miller * 5983060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param listener the OnDialTriggerListener to attach to this view 5993060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6003060421045d4d9e411797f91bb509824b03e33fbJim Miller public void setOnTriggerListener(OnTriggerListener listener) { 6013060421045d4d9e411797f91bb509824b03e33fbJim Miller mOnTriggerListener = listener; 6023060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6033060421045d4d9e411797f91bb509824b03e33fbJim Miller 6043060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6053060421045d4d9e411797f91bb509824b03e33fbJim Miller * Dispatches a trigger event to listener. Ignored if a listener is not set. 6063060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param whichHandle the handle that triggered the event. 6073060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6083060421045d4d9e411797f91bb509824b03e33fbJim Miller private void dispatchTriggerEvent(int whichHandle) { 6093060421045d4d9e411797f91bb509824b03e33fbJim Miller vibrate(VIBRATE_LONG); 6103060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mOnTriggerListener != null) { 6113060421045d4d9e411797f91bb509824b03e33fbJim Miller mOnTriggerListener.onTrigger(this, whichHandle); 6123060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6133060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6143060421045d4d9e411797f91bb509824b03e33fbJim Miller 6153060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6163060421045d4d9e411797f91bb509824b03e33fbJim Miller * Sets the current grabbed state, and dispatches a grabbed state change 6173060421045d4d9e411797f91bb509824b03e33fbJim Miller * event to our listener. 6183060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6193060421045d4d9e411797f91bb509824b03e33fbJim Miller private void setGrabbedState(int newState) { 6203060421045d4d9e411797f91bb509824b03e33fbJim Miller if (newState != mGrabbedState) { 6213060421045d4d9e411797f91bb509824b03e33fbJim Miller mGrabbedState = newState; 6223060421045d4d9e411797f91bb509824b03e33fbJim Miller if (mOnTriggerListener != null) { 6233060421045d4d9e411797f91bb509824b03e33fbJim Miller mOnTriggerListener.onGrabbedStateChange(this, mGrabbedState); 6243060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6253060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6263060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6273060421045d4d9e411797f91bb509824b03e33fbJim Miller 6283060421045d4d9e411797f91bb509824b03e33fbJim Miller public interface OnTriggerListener { 6293060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6303060421045d4d9e411797f91bb509824b03e33fbJim Miller * Sent when the user releases the handle. 6313060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6323060421045d4d9e411797f91bb509824b03e33fbJim Miller public static final int NO_HANDLE = 0; 6333060421045d4d9e411797f91bb509824b03e33fbJim Miller 6343060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6353060421045d4d9e411797f91bb509824b03e33fbJim Miller * Sent when the user grabs the center handle 6363060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6373060421045d4d9e411797f91bb509824b03e33fbJim Miller public static final int CENTER_HANDLE = 10; 6383060421045d4d9e411797f91bb509824b03e33fbJim Miller 6393060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6403060421045d4d9e411797f91bb509824b03e33fbJim Miller * Called when the user drags the center ring beyond a threshold. 6413060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6423060421045d4d9e411797f91bb509824b03e33fbJim Miller void onTrigger(View v, int whichHandle); 6433060421045d4d9e411797f91bb509824b03e33fbJim Miller 6443060421045d4d9e411797f91bb509824b03e33fbJim Miller /** 6453060421045d4d9e411797f91bb509824b03e33fbJim Miller * Called when the "grabbed state" changes (i.e. when the user either grabs or releases 6463060421045d4d9e411797f91bb509824b03e33fbJim Miller * one of the handles.) 6473060421045d4d9e411797f91bb509824b03e33fbJim Miller * 6483060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param v the view that was triggered 6493060421045d4d9e411797f91bb509824b03e33fbJim Miller * @param grabbedState the new state: {@link #NO_HANDLE}, {@link #CENTER_HANDLE}, 6503060421045d4d9e411797f91bb509824b03e33fbJim Miller */ 6513060421045d4d9e411797f91bb509824b03e33fbJim Miller void onGrabbedStateChange(View v, int grabbedState); 6523060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6533060421045d4d9e411797f91bb509824b03e33fbJim Miller 6543060421045d4d9e411797f91bb509824b03e33fbJim Miller public void onAnimationUpdate(ValueAnimator animation) { 6553060421045d4d9e411797f91bb509824b03e33fbJim Miller invalidate(); 6563060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6573060421045d4d9e411797f91bb509824b03e33fbJim Miller 6583060421045d4d9e411797f91bb509824b03e33fbJim Miller public void reset() { 659607d320c9d18a57350bef72cc74017366ffd04ecJim Miller if (DBG) Log.v(TAG, "reset() : resets state to STATE_RESET_LOCK"); 6603060421045d4d9e411797f91bb509824b03e33fbJim Miller mLockState = STATE_RESET_LOCK; 661607d320c9d18a57350bef72cc74017366ffd04ecJim Miller invalidate(); 6623060421045d4d9e411797f91bb509824b03e33fbJim Miller } 6633060421045d4d9e411797f91bb509824b03e33fbJim Miller} 664