Share progress logic between secure and regular conversation view.
Fixes part of b/6383847 Implement secure/sanitized conversation view for unsanitized message content from IMAP and POP server
Change-Id: Ia2ba1185997c46952221f4ee7a57f3f198a749de
diff --git a/res/layout/conversation_load_spinner.xml b/res/layout/conversation_load_spinner.xml
new file mode 100644
index 0000000..0e19b2f
--- /dev/null
+++ b/res/layout/conversation_load_spinner.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2012 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/background_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:background="@android:color/white"
+ android:visibility="gone">
+ <RelativeLayout
+ android:id="@+id/info_view"
+ android:layout_width="match_parent"
+ android:layout_height="70sp"
+ android:layout_marginLeft="@dimen/info_view_margin"
+ android:layout_marginRight="@dimen/info_view_margin"
+ android:paddingLeft="8dip"
+ android:paddingRight="16dip"
+ android:gravity="center"
+ android:visibility="gone">
+ <ProgressBar
+ android:id="@+id/progress_bar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="6dip"
+ android:layout_marginRight="8dip"
+ android:indeterminate="true"
+ android:layout_centerVertical="true" />
+ <RelativeLayout
+ android:layout_centerVertical="true"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/progress_bar">
+ <TextView
+ android:id="@+id/senders_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textSize="@dimen/senders_font_size"
+ android:layout_alignParentTop="true"/>
+ <TextView
+ android:id="@+id/info_subject_view"
+ style="@style/SwipeSubjectStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/senders_view"/>
+ </RelativeLayout>
+ </RelativeLayout>
+
+ <com.android.mail.MinTimeProgressView
+ android:id="@+id/loading_progress"
+ style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ android:indeterminateBehavior="repeat"
+ android:layout_gravity="center"
+ android:visibility="gone" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/res/layout/conversation_view.xml b/res/layout/conversation_view.xml
index 6a2efec..9c286d6 100644
--- a/res/layout/conversation_view.xml
+++ b/res/layout/conversation_view.xml
@@ -56,61 +56,5 @@
</FrameLayout>
</com.android.mail.browse.ConversationContainer>
- <RelativeLayout
- android:id="@+id/background_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:background="@android:color/white"
- android:visibility="gone">
- <RelativeLayout
- android:id="@+id/info_view"
- android:layout_width="match_parent"
- android:layout_height="70sp"
- android:layout_marginLeft="@dimen/info_view_margin"
- android:layout_marginRight="@dimen/info_view_margin"
- android:paddingLeft="8dip"
- android:paddingRight="16dip"
- android:gravity="center"
- android:visibility="gone">
- <ProgressBar
- android:id="@+id/progress_bar"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="6dip"
- android:layout_marginRight="8dip"
- android:indeterminate="true"
- android:layout_centerVertical="true" />
- <RelativeLayout
- android:layout_centerVertical="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/progress_bar">
- <TextView
- android:id="@+id/senders_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:textSize="@dimen/senders_font_size"
- android:layout_alignParentTop="true"/>
- <TextView
- android:id="@+id/info_subject_view"
- style="@style/SwipeSubjectStyle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/senders_view"/>
- </RelativeLayout>
- </RelativeLayout>
-
- <com.android.mail.MinTimeProgressView
- android:id="@+id/loading_progress"
- style="?android:attr/progressBarStyleLarge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:indeterminate="true"
- android:indeterminateBehavior="repeat"
- android:layout_gravity="center"
- android:visibility="gone" />
-
- </RelativeLayout>
+ <include layout="@layout/conversation_load_spinner"/>
</FrameLayout>
diff --git a/res/layout/secure_conversation_view.xml b/res/layout/secure_conversation_view.xml
index 3fa0702..8f0f75c 100644
--- a/res/layout/secure_conversation_view.xml
+++ b/res/layout/secure_conversation_view.xml
@@ -49,15 +49,6 @@
<!-- TODO: scroll indicators go HERE on top of all other layers -->
</FrameLayout>
</RelativeLayout>
-
- <com.android.mail.MinTimeProgressView
- android:id="@+id/loading_progress"
- style="?android:attr/progressBarStyleLarge"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:indeterminate="true"
- android:indeterminateBehavior="repeat"
- android:layout_gravity="center"
- android:visibility="gone" />
+ <include layout="@layout/conversation_load_spinner"/>
</FrameLayout>
diff --git a/src/com/android/mail/browse/SecureConversationViewFragment.java b/src/com/android/mail/browse/SecureConversationViewFragment.java
index 46b0677..9405890 100644
--- a/src/com/android/mail/browse/SecureConversationViewFragment.java
+++ b/src/com/android/mail/browse/SecureConversationViewFragment.java
@@ -28,6 +28,7 @@
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
+import android.webkit.WebViewClient;
import com.android.mail.R;
import com.android.mail.browse.ConversationViewAdapter.MessageHeaderItem;
@@ -53,6 +54,12 @@
private ConversationViewHeader mConversationHeaderView;
private MessageHeaderView mMessageHeaderView;
private ConversationMessage mMessage;
+ private WebViewClient mWebViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ dismissLoadingStatus();
+ }
+ };
/**
* Creates a new instance of {@link ConversationViewFragment}, initialized
@@ -92,6 +99,7 @@
mMessageHeaderView.setCallbacks(this);
mMessageHeaderView.setExpandable(false);
getLoaderManager().initLoader(MESSAGE_LOADER, null, getMessageLoaderCallbacks());
+ showLoadingStatus();
}
@Override
@@ -100,7 +108,9 @@
View rootView = inflater.inflate(R.layout.secure_conversation_view, container, false);
mConversationHeaderView = (ConversationViewHeader) rootView.findViewById(R.id.conv_header);
mMessageHeaderView = (MessageHeaderView) rootView.findViewById(R.id.message_header);
+ instantiateProgressIndicators(rootView);
mWebView = (WebView) rootView.findViewById(R.id.webview);
+ mWebView.setWebViewClient(mWebViewClient);
final WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(false);
diff --git a/src/com/android/mail/ui/AbstractConversationViewFragment.java b/src/com/android/mail/ui/AbstractConversationViewFragment.java
index 9a97fdd..6a2c85d 100644
--- a/src/com/android/mail/ui/AbstractConversationViewFragment.java
+++ b/src/com/android/mail/ui/AbstractConversationViewFragment.java
@@ -17,20 +17,32 @@
package com.android.mail.ui;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.Animator.AnimatorListener;
import android.app.Activity;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
+import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
+import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
import com.android.mail.ContactInfo;
import com.android.mail.ContactInfoSource;
@@ -70,6 +82,9 @@
private static final String LOG_TAG = LogTag.getLogTag();
protected static final int MESSAGE_LOADER = 0;
protected static final int CONTACT_LOADER = 1;
+ private static int sSubjectColor = Integer.MIN_VALUE;
+ private static int sSnippetColor = Integer.MIN_VALUE;
+ private static long sMinDelay = -1;
protected ControllableActivity mActivity;
private final MessageLoaderCallbacks mMessageLoaderCallbacks = new MessageLoaderCallbacks();
protected FormattedDateBuilder mDateBuilder;
@@ -84,6 +99,26 @@
private MessageCursor mCursor;
private Context mContext;
public boolean mUserVisible;
+ private View mProgressView;
+ private View mBackgroundView;
+ private View mInfoView;
+ private final Handler mHandler = new Handler();
+ private Runnable mDelayedShow = new Runnable() {
+ @Override
+ public void run() {
+ mBackgroundView.setVisibility(View.VISIBLE);
+ String senders = mConversation.getSenders(getContext());
+ if (!TextUtils.isEmpty(senders) && mConversation.subject != null) {
+ mInfoView.setVisibility(View.VISIBLE);
+ mSendersView.setText(senders);
+ mSubjectView.setText(createSubjectSnippet(mConversation.subject,
+ mConversation.getSnippet()));
+ } else {
+ mProgressView.setVisibility(View.VISIBLE);
+ }
+ }
+ };
+
private final AccountObserver mAccountObserver = new AccountObserver() {
@Override
public void onChanged(Account newAccount) {
@@ -91,6 +126,8 @@
onAccountChanged();
}
};
+ private TextView mSendersView;
+ private TextView mSubjectView;
public static Bundle makeBasicArgs(Account account, Folder folder) {
Bundle args = new Bundle();
@@ -158,6 +195,57 @@
setHasOptionsMenu(true);
}
+ public void instantiateProgressIndicators(View rootView) {
+ mSendersView = (TextView) rootView.findViewById(R.id.senders_view);
+ mSubjectView = (TextView) rootView.findViewById(R.id.info_subject_view);
+ mBackgroundView = rootView.findViewById(R.id.background_view);
+ mInfoView = rootView.findViewById(R.id.info_view);
+ mProgressView = rootView.findViewById(R.id.loading_progress);
+ }
+
+ protected void dismissLoadingStatus() {
+ if (mBackgroundView.getVisibility() != View.VISIBLE) {
+ // The runnable hasn't run yet, so just remove it.
+ mHandler.removeCallbacks(mDelayedShow);
+ return;
+ }
+ // Fade out the info view.
+ if (mBackgroundView.getVisibility() == View.VISIBLE) {
+ Animator animator = AnimatorInflater.loadAnimator(getContext(), R.anim.fade_out);
+ animator.setTarget(mBackgroundView);
+ animator.addListener(new AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (mProgressView.getVisibility() != View.VISIBLE) {
+ mProgressView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mBackgroundView.setVisibility(View.GONE);
+ mInfoView.setVisibility(View.GONE);
+ mProgressView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ // Do nothing.
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ // Do nothing.
+ }
+ });
+ animator.start();
+ } else {
+ mBackgroundView.setVisibility(View.GONE);
+ mInfoView.setVisibility(View.GONE);
+ mProgressView.setVisibility(View.GONE);
+ }
+ }
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -182,6 +270,49 @@
return activity != null ? activity.getConversationUpdater() : null;
}
+
+ protected void showLoadingStatus() {
+ if (sMinDelay == -1) {
+ sMinDelay = getContext().getResources()
+ .getInteger(R.integer.conversationview_show_loading_delay);
+ }
+ // In case there were any other instances around, get rid of them.
+ mHandler.removeCallbacks(mDelayedShow);
+ mHandler.postDelayed(mDelayedShow, sMinDelay);
+ }
+
+ private CharSequence createSubjectSnippet(CharSequence subject, CharSequence snippet) {
+ if (TextUtils.isEmpty(subject) && TextUtils.isEmpty(snippet)) {
+ return "";
+ }
+ if (subject == null) {
+ subject = "";
+ }
+ if (snippet == null) {
+ snippet = "";
+ }
+ SpannableStringBuilder subjectText = new SpannableStringBuilder(getContext().getString(
+ R.string.subject_and_snippet, subject, snippet));
+ ensureSubjectSnippetColors();
+ int snippetStart = 0;
+ int fontColor = sSubjectColor;
+ subjectText.setSpan(new ForegroundColorSpan(fontColor), 0, subject.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ snippetStart = subject.length() + 1;
+ fontColor = sSnippetColor;
+ subjectText.setSpan(new ForegroundColorSpan(fontColor), snippetStart, subjectText.length(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return subjectText;
+ }
+
+ private void ensureSubjectSnippetColors() {
+ if (sSubjectColor == Integer.MIN_VALUE) {
+ Resources res = getContext().getResources();
+ sSubjectColor = res.getColor(R.color.subject_text_color_read);
+ sSnippetColor = res.getColor(R.color.snippet_text_color_read);
+ }
+ }
+
public Context getContext() {
return mContext;
}
@@ -195,6 +326,10 @@
return mCursor;
}
+ public Handler getHandler() {
+ return mHandler;
+ }
+
public MessageLoaderCallbacks getMessageLoaderCallbacks() {
return mMessageLoaderCallbacks;
}
diff --git a/src/com/android/mail/ui/ConversationViewFragment.java b/src/com/android/mail/ui/ConversationViewFragment.java
index 2a5d1fb..fe24ef0 100644
--- a/src/com/android/mail/ui/ConversationViewFragment.java
+++ b/src/com/android/mail/ui/ConversationViewFragment.java
@@ -17,28 +17,20 @@
package com.android.mail.ui;
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.Animator.AnimatorListener;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
-import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.Handler;
import android.os.SystemClock;
import android.provider.Browser;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -114,20 +106,8 @@
private View mNewMessageBar;
- private View mBackgroundView;
-
- private View mInfoView;
-
- private TextView mSendersView;
-
- private TextView mSubjectView;
-
- private View mProgressView;
-
private HtmlConversationTemplates mTemplates;
- private final Handler mHandler = new Handler();
-
private final MailJsBridge mJsBridge = new MailJsBridge();
private final WebViewClient mWebViewClient = new ConversationWebViewClient();
@@ -162,28 +142,10 @@
private ConversationViewState mViewState;
private boolean mEnableContentReadySignal;
- private Runnable mDelayedShow = new Runnable() {
- @Override
- public void run() {
- mBackgroundView.setVisibility(View.VISIBLE);
- String senders = mConversation.getSenders(getContext());
- if (!TextUtils.isEmpty(senders) && mConversation.subject != null) {
- mInfoView.setVisibility(View.VISIBLE);
- mSendersView.setText(senders);
- mSubjectView.setText(createSubjectSnippet(mConversation.subject,
- mConversation.getSnippet()));
- } else {
- mProgressView.setVisibility(View.VISIBLE);
- }
- }
- };
private ContentSizeChangeListener mWebViewSizeChangeListener;
private static final String BUNDLE_VIEW_STATE = "viewstate";
- private static int sSubjectColor = Integer.MIN_VALUE;
- private static int sSnippetColor = Integer.MIN_VALUE;
- private static long sMinDelay = -1;
private static final boolean DEBUG_DUMP_CONVERSATION_HTML = false;
private static final boolean DISABLE_OFFSCREEN_LOADING = false;
@@ -253,38 +215,6 @@
}
}
- private CharSequence createSubjectSnippet(CharSequence subject, CharSequence snippet) {
- if (TextUtils.isEmpty(subject) && TextUtils.isEmpty(snippet)) {
- return "";
- }
- if (subject == null) {
- subject = "";
- }
- if (snippet == null) {
- snippet = "";
- }
- SpannableStringBuilder subjectText = new SpannableStringBuilder(getContext().getString(
- R.string.subject_and_snippet, subject, snippet));
- ensureSubjectSnippetColors();
- int snippetStart = 0;
- int fontColor = sSubjectColor;
- subjectText.setSpan(new ForegroundColorSpan(fontColor), 0, subject.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- snippetStart = subject.length() + 1;
- fontColor = sSnippetColor;
- subjectText.setSpan(new ForegroundColorSpan(fontColor), snippetStart, subjectText.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- return subjectText;
- }
-
- private void ensureSubjectSnippetColors() {
- if (sSubjectColor == Integer.MIN_VALUE) {
- Resources res = getContext().getResources();
- sSubjectColor = res.getColor(R.color.subject_text_color_read);
- sSnippetColor = res.getColor(R.color.snippet_text_color_read);
- }
- }
-
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
@@ -307,11 +237,7 @@
}
});
- mBackgroundView = rootView.findViewById(R.id.background_view);
- mInfoView = rootView.findViewById(R.id.info_view);
- mSendersView = (TextView) rootView.findViewById(R.id.senders_view);
- mSubjectView = (TextView) rootView.findViewById(R.id.info_subject_view);
- mProgressView = rootView.findViewById(R.id.loading_progress);
+ instantiateProgressIndicators(rootView);
mWebView = (ConversationWebView) mConversationContainer.findViewById(R.id.webview);
@@ -950,59 +876,6 @@
mActivity.onConversationLoadError();
}
- private void showLoadingStatus() {
- if (sMinDelay == -1) {
- sMinDelay = getContext().getResources()
- .getInteger(R.integer.conversationview_show_loading_delay);
- }
- // In case there were any other instances around, get rid of them.
- mHandler.removeCallbacks(mDelayedShow);
- mHandler.postDelayed(mDelayedShow, sMinDelay);
- }
-
- private void dismissLoadingStatus() {
- if (mBackgroundView.getVisibility() != View.VISIBLE) {
- // The runnable hasn't run yet, so just remove it.
- mHandler.removeCallbacks(mDelayedShow);
- return;
- }
- // Fade out the info view.
- if (mBackgroundView.getVisibility() == View.VISIBLE) {
- Animator animator = AnimatorInflater.loadAnimator(getContext(), R.anim.fade_out);
- animator.setTarget(mBackgroundView);
- animator.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- if (mProgressView.getVisibility() != View.VISIBLE) {
- mProgressView.setVisibility(View.GONE);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mBackgroundView.setVisibility(View.GONE);
- mInfoView.setVisibility(View.GONE);
- mProgressView.setVisibility(View.GONE);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- // Do nothing.
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- // Do nothing.
- }
- });
- animator.start();
- } else {
- mBackgroundView.setVisibility(View.GONE);
- mInfoView.setVisibility(View.GONE);
- mProgressView.setVisibility(View.GONE);
- }
- }
-
/**
* NOTE: all public methods must be listed in the proguard flags so that they can be accessed
* via reflection and not stripped.
@@ -1014,7 +887,7 @@
@JavascriptInterface
public void onWebContentGeometryChange(final String[] overlayBottomStrs) {
try {
- mHandler.post(new Runnable() {
+ getHandler().post(new Runnable() {
@Override
public void run() {
if (!mViewsCreated) {
@@ -1058,7 +931,7 @@
public void onContentReady() {
final Conversation conv = mConversation;
try {
- mHandler.post(new Runnable() {
+ getHandler().post(new Runnable() {
@Override
public void run() {
LogUtils.d(LOG_TAG, "ANIMATION STARTED, ready to draw. t=%s",