Improve LayoutInflater's compliance.

There are standards, we should do our best to implement them
properly.

Change-Id: I83a7dc0651795d09b19d536c17b6aefc2eca5c81
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index 81346b4..332a0fa 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -16,6 +16,10 @@
 
 package android.view;
 
+import android.graphics.Canvas;
+import android.os.Handler;
+import android.os.Message;
+import android.widget.FrameLayout;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -83,6 +87,7 @@
 
     private static final String TAG_MERGE = "merge";
     private static final String TAG_INCLUDE = "include";
+    private static final String TAG_1995 = "blink";
     private static final String TAG_REQUEST_FOCUS = "requestFocus";
 
     /**
@@ -454,7 +459,12 @@
                     rInflate(parser, root, attrs, false);
                 } else {
                     // Temp is the root view that was found in the xml
-                    View temp = createViewFromTag(root, name, attrs);
+                    View temp;
+                    if (TAG_1995.equals(name)) {
+                        temp = new BlinkLayout(mContext, attrs);
+                    } else {
+                        temp = createViewFromTag(root, name, attrs);
+                    }
 
                     ViewGroup.LayoutParams params = null;
 
@@ -605,10 +615,9 @@
      * Throw an exception because the specified class is not allowed to be inflated.
      */
     private void failNotAllowed(String name, String prefix, AttributeSet attrs) {
-        InflateException ie = new InflateException(attrs.getPositionDescription()
+        throw new InflateException(attrs.getPositionDescription()
                 + ": Class not allowed to be inflated "
                 + (prefix != null ? (prefix + name) : name));
-        throw ie;
     }
 
     /**
@@ -720,6 +729,12 @@
                 parseInclude(parser, parent, attrs);
             } else if (TAG_MERGE.equals(name)) {
                 throw new InflateException("<merge /> must be the root element");
+            } else if (TAG_1995.equals(name)) {
+                final View view = new BlinkLayout(mContext, attrs);
+                final ViewGroup viewGroup = (ViewGroup) parent;
+                final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
+                rInflate(parser, view, attrs, true);
+                viewGroup.addView(view, params);                
             } else {
                 final View view = createViewFromTag(parent, name, attrs);
                 final ViewGroup viewGroup = (ViewGroup) parent;
@@ -847,5 +862,64 @@
                 parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
             // Empty
         }
-    }    
+    }
+
+    private static class BlinkLayout extends FrameLayout {
+        private static final int MESSAGE_BLINK = 0x42;
+        private static final int BLINK_DELAY = 500;
+
+        private boolean mBlink;
+        private boolean mBlinkState;
+        private final Handler mHandler;
+
+        public BlinkLayout(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            mHandler = new Handler(new Handler.Callback() {
+                @Override
+                public boolean handleMessage(Message msg) {
+                    if (msg.what == MESSAGE_BLINK) {
+                        if (mBlink) {
+                            mBlinkState = !mBlinkState;
+                            makeBlink();
+                        }
+                        invalidate();
+                        return true;
+                    }
+                    return false;
+                }
+            });
+        }
+
+        private void makeBlink() {
+            Message message = mHandler.obtainMessage(MESSAGE_BLINK);
+            mHandler.sendMessageDelayed(message, BLINK_DELAY);
+        }
+
+        @Override
+        protected void onAttachedToWindow() {
+            super.onAttachedToWindow();
+
+            mBlink = true;
+            mBlinkState = true;
+
+            makeBlink();
+        }
+
+        @Override
+        protected void onDetachedFromWindow() {
+            super.onDetachedFromWindow();
+
+            mBlink = false;
+            mBlinkState = true;
+
+            mHandler.removeMessages(MESSAGE_BLINK);
+        }
+
+        @Override
+        protected void dispatchDraw(Canvas canvas) {
+            if (mBlinkState) {
+                super.dispatchDraw(canvas);
+            }
+        }
+    }
 }