Remove ad code.

Moved to UnifiedGmail. Also refactored
HtmlConversationTemplates to use HtmlMessage,
a new interface instead of the Message class.

Change-Id: Ie14694b37800ed9eb9fc692d434508f66660d55b
diff --git a/src/com/android/mail/ads/AdHeaderView.java b/src/com/android/mail/ads/AdHeaderView.java
deleted file mode 100644
index 7a55124..0000000
--- a/src/com/android/mail/ads/AdHeaderView.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc.
- * Licensed to 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.
- */
-
-package com.android.mail.ads;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.mail.R;
-import com.android.mail.browse.ConversationViewAdapter.AdHeaderItem;
-
-public class AdHeaderView extends LinearLayout implements View.OnClickListener {
-    private TextView mAdSubjectView;
-
-    private AdHeaderItem mHeaderItem;
-
-    public AdHeaderView(Context context) {
-        super(context);
-    }
-
-    public AdHeaderView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        mAdSubjectView = (TextView) findViewById(R.id.ad_subject);
-        findViewById(R.id.ad_info).setOnClickListener(this);
-    }
-
-    public void setAdSubject(final String subject) {
-        mAdSubjectView.setText(subject);
-        if (TextUtils.isEmpty(subject)) {
-            mAdSubjectView.setVisibility(GONE);
-        }
-    }
-
-    public void bind(AdHeaderItem headerItem) {
-        mHeaderItem = headerItem;
-    }
-
-    @Override
-    public void onClick(View view) {
-        switch(view.getId()) {
-            case R.id.ad_info:
-                // TODO wire up clicking the ad info button
-//                Utils.showAdPreferenceManager(getContext());
-                break;
-            default:
-                break;
-        }
-    }
-}
diff --git a/src/com/android/mail/ads/AdViewFragment.java b/src/com/android/mail/ads/AdViewFragment.java
deleted file mode 100644
index 529c9d4..0000000
--- a/src/com/android/mail/ads/AdViewFragment.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc.
- * Licensed to 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.
- */
-
-package com.android.mail.ads;
-
-import android.os.Bundle;
-
-import com.android.mail.browse.ConversationMessage;
-import com.android.mail.browse.MessageCursor;
-import com.android.mail.providers.Conversation;
-import com.android.mail.ui.ConversationViewFragment;
-import com.android.mail.ui.ConversationViewState;
-import com.android.mail.utils.LogTag;
-import com.android.mail.utils.LogUtils;
-
-public final class AdViewFragment extends ConversationViewFragment {
-
-    private static final String LOG_TAG = LogTag.getLogTag();
-
-    /**
-     * Constructor needs to be public to handle orientation changes and activity lifecycle events.
-     */
-    public AdViewFragment() {
-        super();
-    }
-
-    /**
-     * Creates a new instance of {@link AdViewFragment}, initialized
-     * to display a conversation with other parameters inherited/copied from an existing bundle,
-     * typically one created using {@link #makeBasicArgs}.
-     */
-    public static AdViewFragment newInstance(Bundle existingArgs,
-            Conversation conversation) {
-        final AdViewFragment f = new AdViewFragment();
-        final Bundle args = new Bundle(existingArgs);
-        args.putParcelable(ARG_CONVERSATION, conversation);
-        f.setArguments(args);
-        return f;
-    }
-
-    /**
-     * Populate the adapter with overlay views (message headers, super-collapsed blocks, a
-     * conversation header), and return an HTML document with spacer divs inserted for all overlays.
-     *
-     */
-    @Override
-    protected String renderMessageBodies(MessageCursor messageCursor,
-            boolean enableContentReadySignal) {
-        int pos = -1;
-
-        LogUtils.d(LOG_TAG, "IN renderMessageBodies, fragment=%s", this);
-        boolean allowNetworkImages = false;
-
-        // TODO: re-use any existing adapter item state (expanded, details expanded, show pics)
-
-        // Walk through the cursor and build up an overlay adapter as you go.
-        // Each overlay has an entry in the adapter for easy scroll handling in the container.
-        // Items are not necessarily 1:1 in cursor and adapter because of super-collapsed blocks.
-        // When adding adapter items, also add their heights to help the container later determine
-        // overlay dimensions.
-
-        // When re-rendering, prevent ConversationContainer from laying out overlays until after
-        // the new spacers are positioned by WebView.
-        mConversationContainer.invalidateSpacerGeometry();
-
-        mAdapter.clear();
-
-        // re-evaluate the message parts of the view state, since the messages may have changed
-        // since the previous render
-        final ConversationViewState prevState = mViewState;
-        mViewState = new ConversationViewState(prevState);
-
-        // N.B. the units of height for spacers are actually dp and not px because WebView assumes
-        // a pixel is an mdpi pixel, unless you set device-dpi.
-
-        // add a single conversation header item
-        final int adHeaderPos = mAdapter.addAdHeader(mConversation);
-        final int adHeaderPx = measureOverlayHeight(adHeaderPos);
-
-        mTemplates.startConversation(mWebView.screenPxToWebPx(mSideMarginPx),
-                mWebView.screenPxToWebPx(adHeaderPx));
-
-        renderBorder(false /* contiguous */, true /* firstBorder */);
-
-        if (messageCursor.moveToFirst()) {
-            final ConversationMessage msg = messageCursor.getMessage();
-            renderMessage(msg);
-        }
-
-        renderBorder(true /* contiguous */, false /* firstBorder */);
-
-        mWebView.getSettings().setBlockNetworkImage(false);
-
-        final boolean applyTransforms = shouldApplyTransforms();
-
-        // If the conversation has specified a base uri, use it here, otherwise use mBaseUri
-        return mTemplates.endConversation(mBaseUri, mConversation.getBaseUri(mBaseUri), 320,
-                mWebView.getViewportWidth(), enableContentReadySignal, isOverviewMode(mAccount),
-                applyTransforms, applyTransforms);
-    }
-
-    private void renderMessage(ConversationMessage msg) {
-        mAdapter.addAdFooter();
-
-        mTemplates.appendMessageHtml(msg, true /** expanded */, true /** showImages */,
-               0 /** headerHeight */, 0 /** footerHeight */);
-        timerMark("rendered message");
-    }
-}
diff --git a/src/com/android/mail/browse/ConversationPagerAdapter.java b/src/com/android/mail/browse/ConversationPagerAdapter.java
index 56810e7..e3b5712 100644
--- a/src/com/android/mail/browse/ConversationPagerAdapter.java
+++ b/src/com/android/mail/browse/ConversationPagerAdapter.java
@@ -109,7 +109,7 @@
             Folder folder, Conversation initialConversation) {
         super(fm, false /* enableSavedStates */);
         mResources = res;
-        mCommonFragmentArgs = AbstractConversationViewFragment.makeBasicArgs(account, folder);
+        mCommonFragmentArgs = AbstractConversationViewFragment.makeBasicArgs(account);
         mInitialConversation = initialConversation;
         mAccount = account;
         mFolder = folder;
diff --git a/src/com/android/mail/browse/ConversationViewAdapter.java b/src/com/android/mail/browse/ConversationViewAdapter.java
index f15acc7..620a5fc 100644
--- a/src/com/android/mail/browse/ConversationViewAdapter.java
+++ b/src/com/android/mail/browse/ConversationViewAdapter.java
@@ -29,7 +29,6 @@
 import com.android.mail.ContactInfoSource;
 import com.android.mail.FormattedDateBuilder;
 import com.android.mail.R;
-import com.android.mail.ads.AdHeaderView;
 import com.android.mail.browse.ConversationViewHeader.ConversationViewHeaderCallbacks;
 import com.android.mail.browse.MessageHeaderView.MessageHeaderViewCallbacks;
 import com.android.mail.browse.SuperCollapsedBlock.OnClickListener;
@@ -38,7 +37,6 @@
 import com.android.mail.providers.UIProvider;
 import com.android.mail.ui.ControllableActivity;
 import com.android.mail.utils.VeiledAddressMatcher;
-
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
 
@@ -76,12 +74,11 @@
 
     public static final int VIEW_TYPE_CONVERSATION_HEADER = 0;
     public static final int VIEW_TYPE_AD_HEADER = 1;
-    public static final int VIEW_TYPE_AD_FOOTER = 2;
-    public static final int VIEW_TYPE_MESSAGE_HEADER = 3;
-    public static final int VIEW_TYPE_MESSAGE_FOOTER = 4;
-    public static final int VIEW_TYPE_SUPER_COLLAPSED_BLOCK = 5;
-    public static final int VIEW_TYPE_BORDER = 6;
-    public static final int VIEW_TYPE_COUNT = 7;
+    public static final int VIEW_TYPE_MESSAGE_HEADER = 2;
+    public static final int VIEW_TYPE_MESSAGE_FOOTER = 3;
+    public static final int VIEW_TYPE_SUPER_COLLAPSED_BLOCK = 4;
+    public static final int VIEW_TYPE_BORDER = 5;
+    public static final int VIEW_TYPE_COUNT = 6;
 
     public class ConversationHeaderItem extends ConversationOverlayItem {
         public final Conversation mConversation;
@@ -123,65 +120,6 @@
 
     }
 
-    public class AdHeaderItem extends ConversationOverlayItem {
-        public final Conversation mConversation;
-
-        private AdHeaderItem(Conversation conv) {
-            mConversation = conv;
-        }
-
-        @Override
-        public int getType() {
-            return VIEW_TYPE_AD_HEADER;
-        }
-
-        @Override
-        public View createView(Context context, LayoutInflater inflater, ViewGroup parent) {
-            final AdHeaderView headerView = (AdHeaderView) inflater.inflate(
-                    R.layout.ad_header_view, parent, false);
-            headerView.bind(this);
-            headerView.setAdSubject(mConversation.subject);
-
-            return headerView;
-        }
-
-        @Override
-        public void bindView(View v, boolean measureOnly) {
-            final AdHeaderView header = (AdHeaderView) v;
-            header.bind(this);
-        }
-
-        @Override
-        public boolean isContiguous() {
-            return true;
-        }
-
-    }
-
-    public class AdFooterItem extends ConversationOverlayItem {
-
-        @Override
-        public int getType() {
-            return VIEW_TYPE_AD_FOOTER;
-        }
-
-        @Override
-        public View createView(Context context, LayoutInflater inflater, ViewGroup parent) {
-            return null;
-        }
-
-        @Override
-        public void bindView(View v, boolean measureOnly) {
-            // DO NOTHING
-        }
-
-        @Override
-        public boolean isContiguous() {
-            return true;
-        }
-
-    }
-
     public static class MessageHeaderItem extends ConversationOverlayItem {
 
         private final ConversationViewAdapter mAdapter;
@@ -535,14 +473,6 @@
         return addItem(new ConversationHeaderItem(conv));
     }
 
-    public int addAdHeader(Conversation conversation) {
-        return addItem(new AdHeaderItem(conversation));
-    }
-
-    public int addAdFooter() {
-        return addItem(new AdFooterItem());
-    }
-
     public int addMessageHeader(ConversationMessage msg, boolean expanded, boolean showImages) {
         return addItem(new MessageHeaderItem(this, mDateBuilder, msg, expanded, showImages));
     }
diff --git a/src/com/android/mail/providers/Message.java b/src/com/android/mail/providers/Message.java
index 4594ae1..74fd007 100644
--- a/src/com/android/mail/providers/Message.java
+++ b/src/com/android/mail/providers/Message.java
@@ -36,6 +36,7 @@
 import com.android.emailcommon.mail.Part;
 import com.android.emailcommon.utility.ConversionUtilities;
 import com.android.mail.providers.UIProvider.MessageColumns;
+import com.android.mail.ui.HtmlMessage;
 import com.android.mail.utils.Utils;
 import com.google.common.base.Objects;
 import com.google.common.collect.Lists;
@@ -46,7 +47,7 @@
 import java.util.regex.Pattern;
 
 
-public class Message implements Parcelable {
+public class Message implements Parcelable, HtmlMessage {
     /**
      * Regex pattern used to look for any inline images in message bodies, including Gmail-hosted
      * relative-URL images, Gmail emoticons, and any external inline images (although we usually
@@ -572,12 +573,12 @@
      * @return true if a "Show Pictures" button should appear.
      */
     public boolean shouldShowImagePrompt() {
-        return !alwaysShowImages && embedsExternalResources();
+        return !alwaysShowImages && (embedsExternalResources ||
+                (!TextUtils.isEmpty(bodyHtml) && INLINE_IMAGE_PATTERN.matcher(bodyHtml).find()));
     }
 
-    private boolean embedsExternalResources() {
-        return embedsExternalResources ||
-                (!TextUtils.isEmpty(bodyHtml) && INLINE_IMAGE_PATTERN.matcher(bodyHtml).find());
+    public boolean embedsExternalResources() {
+        return embedsExternalResources;
     }
 
     /**
@@ -607,4 +608,7 @@
         return body;
     }
 
+    public long getId() {
+        return id;
+    }
 }
diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java
index fa837a4..3f3fa9d 100644
--- a/src/com/android/mail/ui/AbstractConversationViewFragment.java
+++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java
@@ -42,7 +42,6 @@
 import com.android.mail.providers.AccountObserver;
 import com.android.mail.providers.Address;
 import com.android.mail.providers.Conversation;
-import com.android.mail.providers.Folder;
 import com.android.mail.providers.ListParams;
 import com.android.mail.providers.UIProvider;
 import com.android.mail.providers.UIProvider.CursorStatus;
@@ -60,9 +59,8 @@
         ConversationController, ConversationAccountController,
         ConversationViewHeaderCallbacks {
 
-    private static final String ARG_ACCOUNT = "account";
+    protected static final String ARG_ACCOUNT = "account";
     public static final String ARG_CONVERSATION = "conversation";
-    private static final String ARG_FOLDER = "folder";
     private static final String LOG_TAG = LogTag.getLogTag();
     protected static final int MESSAGE_LOADER = 0;
     protected static final int CONTACT_LOADER = 1;
@@ -71,7 +69,6 @@
     private ContactLoaderCallbacks mContactLoaderCallbacks;
     private MenuItem mChangeFoldersMenuItem;
     protected Conversation mConversation;
-    protected Folder mFolder;
     protected String mBaseUri;
     protected Account mAccount;
 
@@ -137,10 +134,9 @@
     private static final String BUNDLE_KEY_HAS_CONVERSATION_BEEN_REVERTED =
             AbstractConversationViewFragment.class.getName() + "conversationreverted";
 
-    public static Bundle makeBasicArgs(Account account, Folder folder) {
+    public static Bundle makeBasicArgs(Account account) {
         Bundle args = new Bundle();
         args.putParcelable(ARG_ACCOUNT, account);
-        args.putParcelable(ARG_FOLDER, folder);
         return args;
     }
 
@@ -187,14 +183,8 @@
     public void onCreate(Bundle savedState) {
         super.onCreate(savedState);
 
-        final Bundle args = getArguments();
-        mAccount = args.getParcelable(ARG_ACCOUNT);
-        mConversation = args.getParcelable(ARG_CONVERSATION);
-        mFolder = args.getParcelable(ARG_FOLDER);
-
-        // Since the uri specified in the conversation base uri may not be unique, we specify a
-        // base uri that us guaranteed to be unique for this conversation.
-        mBaseUri = "x-thread://" + mAccount.name.hashCode() + "/" + mConversation.id;
+        parseArguments();
+        setBaseUri();
 
         LogUtils.d(LOG_TAG, "onCreate in ConversationViewFragment (this=%s)", this);
         // Not really, we just want to get a crack to store a reference to the change_folder item
@@ -215,6 +205,25 @@
         }
     }
 
+    /**
+     * Can be overridden in case a subclass needs to get additional arguments.
+     */
+    protected void parseArguments() {
+        final Bundle args = getArguments();
+        mAccount = args.getParcelable(ARG_ACCOUNT);
+        mConversation = args.getParcelable(ARG_CONVERSATION);
+    }
+
+    /**
+     * Can be overridden in case a subclass needs a different uri format
+     * (such as one that does not rely on account and/or conversation.
+     */
+    protected void setBaseUri() {
+        // Since the uri specified in the conversation base uri may not be unique, we specify a
+        // base uri that us guaranteed to be unique for this conversation.
+        mBaseUri = "x-thread://" + mAccount.name.hashCode() + "/" + mConversation.id;
+    }
+
     @Override
     public String toString() {
         // log extra info at DEBUG level or finer
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 26b789f..e0a45d6 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -301,7 +301,7 @@
             }
         });
 
-        if (mConversation.conversationBaseUri != null &&
+        if (mConversation != null && mConversation.conversationBaseUri != null &&
                 !Utils.isEmpty(mAccount.accoutCookieQueryUri)) {
             // Set the cookie for this base url
             new SetCookieTask(getContext(), mConversation.conversationBaseUri,
@@ -510,8 +510,8 @@
             timerMark("CVF.showConversation");
         } else {
             final boolean disableOffscreenLoading = DISABLE_OFFSCREEN_LOADING
-                    || (mConversation.isRemote
-                            || mConversation.getNumMessages() > mMaxAutoLoadMessages);
+                    || (mConversation != null && (mConversation.isRemote
+                            || mConversation.getNumMessages() > mMaxAutoLoadMessages));
 
             // When not visible, we should not immediately load if either this conversation is
             // too heavyweight, or if the main/initial conversation is busy loading.
@@ -543,13 +543,21 @@
 
     private void startConversationLoad() {
         mWebView.setVisibility(View.VISIBLE);
-        getLoaderManager().initLoader(MESSAGE_LOADER, Bundle.EMPTY, getMessageLoaderCallbacks());
+        loadContent();
         // TODO(mindyp): don't show loading status for a previously rendered
         // conversation. Ielieve this is better done by making sure don't show loading status
         // until XX ms have passed without loading completed.
         mProgressController.showLoadingStatus(isUserVisible());
     }
 
+    /**
+     * Can be overridden in case a subclass needs to load something other than
+     * the messages of a conversation.
+     */
+    protected void loadContent() {
+        getLoaderManager().initLoader(MESSAGE_LOADER, Bundle.EMPTY, getMessageLoaderCallbacks());
+    }
+
     private void revealConversation() {
         timerMark("revealing conversation");
         mProgressController.dismissLoadingStatus(mOnProgressDismiss);
@@ -1312,6 +1320,10 @@
             timerMark("message cursor load finished");
         }
 
+        renderContent(newCursor);
+    }
+
+    protected void renderContent(MessageCursor messageCursor) {
         // if layout hasn't happened, delay render
         // This is needed in addition to the showConversation() delay to speed
         // up rotation and restoration.
@@ -1319,7 +1331,7 @@
             mNeedRender = true;
             mConversationContainer.addOnLayoutChangeListener(this);
         } else {
-            renderConversation(newCursor);
+            renderConversation(messageCursor);
         }
     }
 
diff --git a/src/com/android/mail/ui/HtmlConversationTemplates.java b/src/com/android/mail/ui/HtmlConversationTemplates.java
index 2e73080..d70362c 100644
--- a/src/com/android/mail/ui/HtmlConversationTemplates.java
+++ b/src/com/android/mail/ui/HtmlConversationTemplates.java
@@ -21,7 +21,6 @@
 import android.content.res.Resources.NotFoundException;
 
 import com.android.mail.R;
-import com.android.mail.providers.Message;
 import com.android.mail.utils.LogTag;
 import com.android.mail.utils.LogUtils;
 import com.google.common.annotations.VisibleForTesting;
@@ -133,7 +132,7 @@
         return sAbsoluteImgUrlPattern.matcher(html).replaceAll(IMG_URL_REPLACEMENT);
     }
 
-    public void appendMessageHtml(Message message, boolean isExpanded,
+    public void appendMessageHtml(HtmlMessage message, boolean isExpanded,
             boolean safeForImages, int headerHeight, int footerHeight) {
 
         final String bodyDisplay = isExpanded ? "block" : "none";
@@ -156,7 +155,7 @@
          * URLs) and any false negatives that the regex misses. This maintains overall security
          * level by not relying solely on the regex.
          */
-        if (!safeForImages && message.embedsExternalResources) {
+        if (!safeForImages && message.embedsExternalResources()) {
             body = replaceAbsoluteImgUrls(body);
         }
 
@@ -172,8 +171,8 @@
         );
     }
 
-    public String getMessageDomId(Message msg) {
-        return MESSAGE_PREFIX + msg.id;
+    public String getMessageDomId(HtmlMessage msg) {
+        return MESSAGE_PREFIX + msg.getId();
     }
 
     public void startConversation(int sideMargin, int conversationHeaderHeight) {
diff --git a/src/com/android/mail/ui/HtmlMessage.java b/src/com/android/mail/ui/HtmlMessage.java
new file mode 100644
index 0000000..bf63e60
--- /dev/null
+++ b/src/com/android/mail/ui/HtmlMessage.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2013, Google Inc.
+ *
+ * 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.
+ */
+
+package com.android.mail.ui;
+
+/**
+ * Interface for appending message-like content into an html
+ * document. Used in {@link HtmlConversationTemplates} so that
+ * it does not rely on just {@link com.android.mail.providers.Message}.
+ */
+public interface HtmlMessage {
+    public String getBodyAsHtml();
+    public boolean embedsExternalResources();
+    public long getId();
+}