Fix a couple of drag & drop crashes

1. ViewGroups being removed from the layout during a drag would wind up
crashing the app with an NPE at drag-ended time, due to blind dereference
of now-cleared object pointers.

2. Passing a 'null' ClipData to startDrag() would crash the system
process with an NPE.  Should this even be valid?  I'm inclined to say
yes, though it means that apps will need to guard against it.

Fixes bug 3369542

Change-Id: I168fc1284d6fd4403999946609725414cf254df0
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d1781cc..115431e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -935,15 +935,17 @@
         } break;
 
         case DragEvent.ACTION_DRAG_ENDED: {
-            // If a child was notified about an ongoing drag, it's told that it's over
-            for (View child : mDragNotifiedChildren) {
-                child.dispatchDragEvent(event);
-            }
-
             // Release the bookkeeping now that the drag lifecycle has ended
-            mDragNotifiedChildren.clear();
-            mCurrentDrag.recycle();
-            mCurrentDrag = null;
+            if (mDragNotifiedChildren != null) {
+                for (View child : mDragNotifiedChildren) {
+                    // If a child was notified about an ongoing drag, it's told that it's over
+                    child.dispatchDragEvent(event);
+                }
+
+                mDragNotifiedChildren.clear();
+                mCurrentDrag.recycle();
+                mCurrentDrag = null;
+            }
 
             // We consider drag-ended to have been handled if one of our children
             // had offered to handle the drag.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 961b633..1f15628 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2803,6 +2803,7 @@
 
                 // Report the drop result when we're done
                 if (what == DragEvent.ACTION_DROP) {
+                    mDragDescription = null;
                     try {
                         Log.i(TAG, "Reporting drop result: " + result);
                         sWindowSession.reportDropResult(mWindow, result);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3e930ae..bbb2228 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -583,7 +583,7 @@
         void broadcastDragStartedLw(final float touchX, final float touchY) {
             // Cache a base-class instance of the clip metadata so that parceling
             // works correctly in calling out to the apps.
-            mDataDescription = mData.getDescription();
+            mDataDescription = (mData != null) ? mData.getDescription() : null;
             mNotifiedWindows.clear();
             mDragInProgress = true;