Placeholder invite-accept UI

This is a lightweight placeholder so calendar functionality can be
tested.  Simply presents a message about the invitation, and a set of
yes/maybe/no buttons to click.

The UI is shown whenever the message appears to contain an invite.

There are many elements left to be done here:
TODO: response code (EAS protocol) doesn't seem to work
TODO: use real assets & design
TODO: provide a click-link into calendar event
TODO: show calendar icon in messagelist too
TODO: (if possible) persist user's response in button state?
diff --git a/res/layout/message_view_header.xml b/res/layout/message_view_header.xml
index f86475b..bb7b592 100644
--- a/res/layout/message_view_header.xml
+++ b/res/layout/message_view_header.xml
@@ -166,6 +166,7 @@
             android:text="@string/message_view_show_pictures_action" />
     </LinearLayout>
     <!-- content area -->
+    <include layout="@layout/message_view_invitation" />
     <WebView
         android:id="@+id/message_content"
         android:layout_height="wrap_content"
diff --git a/res/layout/message_view_invitation.xml b/res/layout/message_view_invitation.xml
new file mode 100644
index 0000000..a1c1a67
--- /dev/null
+++ b/res/layout/message_view_invitation.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/invite_section"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:background="@drawable/text_box"
+    android:gravity="center_vertical" 
+    android:visibility="gone" >
+    <TextView
+        android:id="@+id/invite_info"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="6dip"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:text="@string/message_view_invite_text"
+        android:textColor="?android:attr/textColorPrimaryInverse"
+        android:layout_alignParentTop="true" />
+    <Button
+        android:id="@+id/decline"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/buttonStyleSmall"
+        android:text="@string/message_view_invite_decline"
+        android:singleLine="true"
+        android:layout_alignParentRight="true"
+        android:layout_below="@id/invite_info"
+        android:layout_marginTop="6dip" />
+    <Button
+        android:id="@+id/maybe"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/buttonStyleSmall"
+        android:text="@string/message_view_invite_maybe"
+        android:singleLine="true"
+        android:layout_toLeftOf="@id/decline"
+        android:layout_below="@id/invite_info"
+        android:layout_marginTop="6dip" />
+    <Button
+        android:id="@+id/accept"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="?android:attr/buttonStyleSmall"
+        android:text="@string/message_view_invite_accept"
+        android:singleLine="true"
+        android:layout_toLeftOf="@id/maybe"
+        android:layout_below="@id/invite_info"
+        android:layout_marginTop="6dip" />
+</RelativeLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b8c175a..a88a395 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -260,6 +260,14 @@
     <string name="message_view_fetching_attachment_toast">Fetching attachment.</string>
     <!-- Appears progress dialog for fetching attachment -->
     <string name="message_view_fetching_attachment_progress">Fetching attachment <xliff:g id="filename">%s</xliff:g></string>
+    <!-- String shown with a calendar invitation. -->
+    <string name="message_view_invite_text">Accept invitation?</string>
+    <!-- Button text: Calendar invitation: Accept -->
+    <string name="message_view_invite_accept">Accept</string>
+    <!-- Button text: Calendar invitation: Maybe -->
+    <string name="message_view_invite_maybe">Maybe</string>
+    <!-- Button text: Calendar invitation: Decline -->
+    <string name="message_view_invite_decline">Decline</string>
     <!-- Toast shown briefly while deleting a message -->
     <plurals name="message_deleted_toast">
         <item quantity="one">Message <xliff:g id="deleted.">deleted.</xliff:g></item>
diff --git a/src/com/android/email/activity/MessageView.java b/src/com/android/email/activity/MessageView.java
index 06f1296..0e12b52 100644
--- a/src/com/android/email/activity/MessageView.java
+++ b/src/com/android/email/activity/MessageView.java
@@ -122,6 +122,7 @@
     private ImageView mAttachmentIcon;
     private ImageView mFavoriteIcon;
     private View mShowPicturesSection;
+    private View mInviteSection;
     private ImageView mSenderPresenceView;
     private ProgressDialog mProgressDialog;
     private View mScrollView;
@@ -342,6 +343,7 @@
         mAttachmentIcon = (ImageView) findViewById(R.id.attachment);
         mFavoriteIcon = (ImageView) findViewById(R.id.favorite);
         mShowPicturesSection = findViewById(R.id.show_pictures_section);
+        mInviteSection = findViewById(R.id.invite_section);
         mSenderPresenceView = (ImageView) findViewById(R.id.presence);
         mMoveToNewer = findViewById(R.id.moveToNewer);
         mMoveToOlder = findViewById(R.id.moveToOlder);
@@ -356,6 +358,9 @@
         findViewById(R.id.reply_all).setOnClickListener(this);
         findViewById(R.id.delete).setOnClickListener(this);
         findViewById(R.id.show_pictures).setOnClickListener(this);
+        findViewById(R.id.accept).setOnClickListener(this);
+        findViewById(R.id.maybe).setOnClickListener(this);
+        findViewById(R.id.decline).setOnClickListener(this);
 
         mMessageContentView.setVerticalScrollBarEnabled(false);
         mMessageContentView.getSettings().setBlockNetworkImage(true);
@@ -677,14 +682,11 @@
         return null;
     }
 
-    // NOTE
-    // This is a placeholder for code used to accept a meeting invitation, and would presumably
-    // be called in response to a button press or menu selection
-    // The appropriate EmailServiceConstant would be changed to implement "decline" and
-    // "tentative" responses
-    private void onAccept() {
-        mController.sendMeetingResponse(mMessageId, EmailServiceConstants.MEETING_REQUEST_ACCEPTED,
-                mControllerCallback);
+    /**
+     * Send a service message indicating that a meeting invite button has been clicked.
+     */
+    private void onAccept(int response) {
+        mController.sendMeetingResponse(mMessageId, response, mControllerCallback);
     }
 
     private void onDownloadAttachment(AttachmentInfo attachment) {
@@ -758,6 +760,15 @@
             case R.id.show_pictures:
                 onShowPictures();
                 break;
+            case R.id.accept:
+                onAccept(EmailServiceConstants.MEETING_REQUEST_ACCEPTED);
+                break;
+            case R.id.maybe:
+                onAccept(EmailServiceConstants.MEETING_REQUEST_TENTATIVE);
+                break;
+            case R.id.decline:
+                onAccept(EmailServiceConstants.MEETING_REQUEST_DECLINED);
+                break;
         }
     }
 
@@ -1277,6 +1288,8 @@
         mCcContainerView.setVisibility((friendlyCc != null) ? View.VISIBLE : View.GONE);
         mAttachmentIcon.setVisibility(message.mAttachments != null ? View.VISIBLE : View.GONE);
         mFavoriteIcon.setImageDrawable(message.mFlagFavorite ? mFavoriteIconOn : mFavoriteIconOff);
+        mInviteSection.setVisibility(!TextUtils.isEmpty(message.mMeetingInfo) ?
+                View.VISIBLE : View.GONE);
 
         // Handle partially-loaded email, as follows:
         // 1. Check value of message.mFlagLoaded