18f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate/* 28f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * Copyright (C) 2010 The Android Open Source Project 38f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * 48f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * Licensed under the Apache License, Version 2.0 (the "License"); 58f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * you may not use this file except in compliance with the License. 68f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * You may obtain a copy of the License at 78f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * 88f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * http://www.apache.org/licenses/LICENSE-2.0 98f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * 108f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * Unless required by applicable law or agreed to in writing, software 118f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * distributed under the License is distributed on an "AS IS" BASIS, 128f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * See the License for the specific language governing permissions and 148f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * limitations under the License. 158f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate */ 168f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 178f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tatepackage com.example.android.apis.view; 188f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 198f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport com.example.android.apis.R; 208f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 218f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.content.ClipData; 228f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.content.Context; 238f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.content.res.TypedArray; 248f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.graphics.*; 258f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.os.SystemClock; 268f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.text.TextPaint; 278f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.util.AttributeSet; 288f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.util.Log; 298f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.view.DragEvent; 308f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.view.View; 318f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tateimport android.widget.TextView; 328f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 338f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tatepublic class DraggableDot extends View { 348f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate static final String TAG = "DraggableDot"; 358f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 368f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private boolean mDragInProgress; 378f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private boolean mHovering; 388f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private boolean mAcceptsDrag; 398f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate TextView mReportView; 408f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 418f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private Paint mPaint; 428f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private TextPaint mLegendPaint; 438f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private Paint mGlow; 448f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private static final int NUM_GLOW_STEPS = 10; 458f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private static final int GREEN_STEP = 0x0000FF00 / NUM_GLOW_STEPS; 468f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private static final int WHITE_STEP = 0x00FFFFFF / NUM_GLOW_STEPS; 478f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private static final int ALPHA_STEP = 0xFF000000 / NUM_GLOW_STEPS; 488f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 498f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate int mRadius; 508f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate int mAnrType; 518f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate CharSequence mLegend; 528f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 538f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate static final int ANR_NONE = 0; 547f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate static final int ANR_SHADOW = 1; 558f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate static final int ANR_DROP = 2; 568f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 578f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate void sleepSixSeconds() { 588f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // hang forever; good for producing ANRs 598f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate long start = SystemClock.uptimeMillis(); 608f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate do { 618f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate try { Thread.sleep(1000); } catch (InterruptedException e) {} 628f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } while (SystemClock.uptimeMillis() < start + 6000); 638f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 648f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 657f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate // Shadow builder that can ANR if desired 667f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate class ANRShadowBuilder extends DragShadowBuilder { 678f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate boolean mDoAnr; 688f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 697f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate public ANRShadowBuilder(View view, boolean doAnr) { 708f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate super(view); 718f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mDoAnr = doAnr; 728f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 738f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 748f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate @Override 757f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate public void onDrawShadow(Canvas canvas) { 768f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mDoAnr) { 778f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate sleepSixSeconds(); 788f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 797f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate super.onDrawShadow(canvas); 808f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 818f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 828f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 838f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate public DraggableDot(Context context, AttributeSet attrs) { 848f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate super(context, attrs); 858f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 868f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate setFocusable(true); 878f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate setClickable(true); 888f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 898f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegend = ""; 908f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 918f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mPaint = new Paint(); 928f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mPaint.setAntiAlias(true); 938f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mPaint.setStrokeWidth(6); 948f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mPaint.setColor(0xFFD00000); 958f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 968f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegendPaint = new TextPaint(); 978f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegendPaint.setAntiAlias(true); 988f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegendPaint.setTextAlign(Paint.Align.CENTER); 998f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegendPaint.setColor(0xFFF0F0FF); 1008f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1018f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mGlow = new Paint(); 1028f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mGlow.setAntiAlias(true); 1038f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mGlow.setStrokeWidth(1); 1048f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mGlow.setStyle(Paint.Style.STROKE); 1058f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1068f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // look up any layout-defined attributes 1078f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate TypedArray a = context.obtainStyledAttributes(attrs, 1088f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate R.styleable.DraggableDot); 1098f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1108f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate final int N = a.getIndexCount(); 1118f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate for (int i = 0; i < N; i++) { 1128f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate int attr = a.getIndex(i); 1138f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate switch (attr) { 1148f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case R.styleable.DraggableDot_radius: { 1158f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mRadius = a.getDimensionPixelSize(attr, 0); 1168f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 1178f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1188f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case R.styleable.DraggableDot_legend: { 1198f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegend = a.getText(attr); 1208f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 1218f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1228f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case R.styleable.DraggableDot_anr: { 1238f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mAnrType = a.getInt(attr, 0); 1248f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 1258f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1268f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1278f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1288f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "DraggableDot @ " + this + " : radius=" + mRadius + " legend='" + mLegend 129134fada434cae8dc5a00b91cb5ff0541de94ea64Christopher Tate + "' anr=" + mAnrType); 1308f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1318f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate setOnLongClickListener(new View.OnLongClickListener() { 1328f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate public boolean onLongClick(View v) { 1330d11c9c34501a9a9dedee1092fd63af218dc28c8Dianne Hackborn ClipData data = ClipData.newPlainText("dot", "Dot : " + v.toString()); 1347f68ce1a1913bb8ffa13cf518b0daaa1bcf5eb4dChristopher Tate v.startDrag(data, new ANRShadowBuilder(v, mAnrType == ANR_SHADOW), 135134fada434cae8dc5a00b91cb5ff0541de94ea64Christopher Tate (Object)v, 0); 1368f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate return true; 1378f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1388f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate }); 1398f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1408f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1418f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate void setReportView(TextView view) { 1428f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mReportView = view; 1438f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1448f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1458f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate @Override 1468f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate protected void onDraw(Canvas canvas) { 1478f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate float wf = getWidth(); 1488f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate float hf = getHeight(); 1498f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate final float cx = wf/2; 1508f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate final float cy = hf/2; 1518f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate wf -= getPaddingLeft() + getPaddingRight(); 1528f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate hf -= getPaddingTop() + getPaddingBottom(); 1538f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate float rad = (wf < hf) ? wf/2 : hf/2; 1548f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate canvas.drawCircle(cx, cy, rad, mPaint); 1558f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1568f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mLegend != null && mLegend.length() > 0) { 1578f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate canvas.drawText(mLegend, 0, mLegend.length(), 1588f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate cx, cy + mLegendPaint.getFontSpacing()/2, 1598f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mLegendPaint); 1608f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1618f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1628f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // if we're in the middle of a drag, light up as a potential target 1638f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mDragInProgress && mAcceptsDrag) { 1648f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate for (int i = NUM_GLOW_STEPS; i > 0; i--) { 1658f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate int color = (mHovering) ? WHITE_STEP : GREEN_STEP; 1668f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate color = i*(color | ALPHA_STEP); 1678f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mGlow.setColor(color); 1688f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate canvas.drawCircle(cx, cy, rad, mGlow); 1698f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate rad -= 0.5f; 1708f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate canvas.drawCircle(cx, cy, rad, mGlow); 1718f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate rad -= 0.5f; 1728f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1738f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1748f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1758f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1768f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate @Override 1778f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate protected void onMeasure(int widthSpec, int heightSpec) { 1788f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate int totalDiameter = 2*mRadius + getPaddingLeft() + getPaddingRight(); 1798f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate setMeasuredDimension(totalDiameter, totalDiameter); 1808f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1818f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 1828f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate /** 1838f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate * Drag and drop 1848f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate */ 1858f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate @Override 1868f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate public boolean onDragEvent(DragEvent event) { 1878f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate boolean result = false; 1888f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate switch (event.getAction()) { 1898f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DRAG_STARTED: { 1908f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // claim to accept any dragged content 1918f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Drag started, event=" + event); 1928f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // cache whether we accept the drag to return for LOCATION events 1938f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mDragInProgress = true; 1948f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mAcceptsDrag = result = true; 1958f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // Redraw in the new visual state if we are a potential drop target 1968f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mAcceptsDrag) { 1978f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate invalidate(); 1988f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 1998f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2008f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2018f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DRAG_ENDED: { 2028f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Drag ended."); 2038f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mAcceptsDrag) { 2048f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate invalidate(); 2058f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2068f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mDragInProgress = false; 2078f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mHovering = false; 2088f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2098f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2108f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DRAG_LOCATION: { 2118f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate // we returned true to DRAG_STARTED, so return true here 2128f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "... seeing drag locations ..."); 2138f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate result = mAcceptsDrag; 2148f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2158f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2168f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DROP: { 2178f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Got a drop! dot=" + this + " event=" + event); 2188f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mAnrType == ANR_DROP) { 2198f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate sleepSixSeconds(); 2208f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2218f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate processDrop(event); 2228f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate result = true; 2238f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2248f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2258f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DRAG_ENTERED: { 2268f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Entered dot @ " + this); 2278f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mHovering = true; 2288f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate invalidate(); 2298f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2308f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2318f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate case DragEvent.ACTION_DRAG_EXITED: { 2328f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Exited dot @ " + this); 2338f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mHovering = false; 2348f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate invalidate(); 2358f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } break; 2368f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2378f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate default: 2388f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "other drag event: " + event); 2398f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate result = mAcceptsDrag; 2408f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate break; 2418f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2428f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2438f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate return result; 2448f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2458f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate 2468f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate private void processDrop(DragEvent event) { 2478f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate final ClipData data = event.getClipData(); 2488f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate final int N = data.getItemCount(); 2498f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate for (int i = 0; i < N; i++) { 2500d11c9c34501a9a9dedee1092fd63af218dc28c8Dianne Hackborn ClipData.Item item = data.getItemAt(i); 2518f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate Log.i(TAG, "Dropped item " + i + " : " + item); 2528f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (mReportView != null) { 2538f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate String text = item.coerceToText(getContext()).toString(); 2548f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate if (event.getLocalState() == (Object) this) { 2558f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate text += " : Dropped on self!"; 2568f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2578f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate mReportView.setText(text); 2588f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2598f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2608f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate } 2618f2e8f48b924ecc87086b8ab7af348031dd848c9Christopher Tate}