Merge "Import translations. DO NOT MERGE" into jb-ub-mail-ur10
diff --git a/res/layout/two_pane_activity.xml b/res/layout/two_pane_activity.xml
index a8c1004..fdafb3b 100644
--- a/res/layout/two_pane_activity.xml
+++ b/res/layout/two_pane_activity.xml
@@ -65,6 +65,11 @@
android:layout_width="0dp"
android:layout_height="match_parent" />
+ <FrameLayout
+ android:id="@+id/miscellaneous_pane"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+
<com.android.mail.ui.ActionableToastBar
android:id="@+id/toast_bar"
style="@style/ToastBarStyle" />
diff --git a/src/com/android/mail/analytics/AnalyticsUtils.java b/src/com/android/mail/analytics/AnalyticsUtils.java
index 0cc9e48..038a4bf 100644
--- a/src/com/android/mail/analytics/AnalyticsUtils.java
+++ b/src/com/android/mail/analytics/AnalyticsUtils.java
@@ -51,6 +51,8 @@
s = "mark not important";
} else if (id == R.id.mute) {
s = "mute";
+ } else if (id == R.id.report_phishing) {
+ s = "report_phishing";
} else if (id == R.id.report_spam) {
s = "report_spam";
} else if (id == R.id.mark_not_spam) {
@@ -99,6 +101,8 @@
s = "send_message";
} else if (id == R.id.discard) {
s = "compose_discard_draft";
+ } else if (id == R.id.search) {
+ s = "search";
} else {
s = null;
}
diff --git a/src/com/android/mail/browse/MessageAttachmentBar.java b/src/com/android/mail/browse/MessageAttachmentBar.java
index 18efa86..a66fd21 100644
--- a/src/com/android/mail/browse/MessageAttachmentBar.java
+++ b/src/com/android/mail/browse/MessageAttachmentBar.java
@@ -40,6 +40,7 @@
import android.widget.TextView;
import com.android.mail.R;
+import com.android.mail.analytics.Analytics;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.UIProvider.AttachmentDestination;
import com.android.mail.providers.UIProvider.AttachmentState;
@@ -173,15 +174,27 @@
if (mAttachment.canSave()) {
mActionHandler.startDownloadingAttachment(AttachmentDestination.EXTERNAL);
mSaveClicked = true;
+
+ Analytics.getInstance().sendEvent(
+ "save_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
+ "attachment_bar", mAttachment.size);
}
} else if (res == R.id.download_again) {
if (mAttachment.isPresentLocally()) {
mActionHandler.showDownloadingDialog();
mActionHandler.startRedownloadingAttachment(mAttachment);
+
+ Analytics.getInstance().sendEvent("redownload_attachment",
+ Utils.normalizeMimeType(mAttachment.getContentType()), "attachment_bar",
+ mAttachment.size);
}
} else if (res == R.id.cancel_attachment) {
mActionHandler.cancelAttachment();
mSaveClicked = false;
+
+ Analytics.getInstance().sendEvent(
+ "cancel_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
+ "attachment_bar", mAttachment.size);
} else if (res == R.id.overflow) {
// If no overflow items are visible, just bail out.
// We shouldn't be able to get here anyhow since the overflow
@@ -207,6 +220,9 @@
// button or cancel button or one of the
// overflow items.
+ final String mime = Utils.normalizeMimeType(mAttachment.getContentType());
+ final String action;
+
// If the mimetype is blocked, show the info dialog
if (MimeType.isBlocked(mAttachment.getContentType())) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
@@ -214,6 +230,9 @@
builder.setTitle(R.string.more_info_attachment)
.setMessage(dialogMessage)
.show();
+
+ action = "attachment_bar_blocked";
+
}
// If we can install, install.
else if (MimeType.isInstallable(mAttachment.getContentType())) {
@@ -222,16 +241,22 @@
// workaround in
// UiProvider#getUiAttachmentsCursorForUIAttachments()
mActionHandler.showAttachment(AttachmentDestination.EXTERNAL);
+
+ action = "attachment_bar_install";
}
// If we can view or play with an on-device app,
// view or play.
else if (MimeType.isViewable(
getContext(), mAttachment.contentUri, mAttachment.getContentType())) {
mActionHandler.showAttachment(AttachmentDestination.CACHE);
+
+ action = "attachment_bar";
}
// If we can only preview the attachment, preview.
else if (mAttachment.canPreview()) {
previewAttachment();
+
+ action = null;
}
// Otherwise, if we cannot do anything, show the info dialog.
else {
@@ -240,6 +265,13 @@
builder.setTitle(R.string.more_info_attachment)
.setMessage(dialogMessage)
.show();
+
+ action = "attachment_bar_no_viewer";
+ }
+
+ if (action != null) {
+ Analytics.getInstance()
+ .sendEvent("view_attachment", mime, action, mAttachment.size);
}
}
@@ -305,6 +337,10 @@
final Intent previewIntent =
new Intent(Intent.ACTION_VIEW, mAttachment.previewIntentUri);
getContext().startActivity(previewIntent);
+
+ Analytics.getInstance().sendEvent(
+ "preview_attachment", Utils.normalizeMimeType(mAttachment.getContentType()),
+ null, mAttachment.size);
}
}
diff --git a/src/com/android/mail/browse/MessageAttachmentTile.java b/src/com/android/mail/browse/MessageAttachmentTile.java
index 61e104b..90a87cc 100644
--- a/src/com/android/mail/browse/MessageAttachmentTile.java
+++ b/src/com/android/mail/browse/MessageAttachmentTile.java
@@ -32,6 +32,7 @@
import com.android.ex.photo.util.ImageUtils;
import com.android.mail.R;
+import com.android.mail.analytics.Analytics;
import com.android.mail.photo.MailPhotoViewActivity;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.UIProvider;
@@ -151,7 +152,12 @@
@Override
public void viewAttachment() {
- if (ImageUtils.isImageMimeType(Utils.normalizeMimeType(mAttachment.getContentType()))) {
+ final String mime = Utils.normalizeMimeType(mAttachment.getContentType());
+
+ Analytics.getInstance()
+ .sendEvent("view_attachment", mime, "attachment_tile", mAttachment.size);
+
+ if (ImageUtils.isImageMimeType(mime)) {
MailPhotoViewActivity
.startMailPhotoViewActivity(getContext(), mAttachmentsListUri, mPhotoIndex);
return;
@@ -161,7 +167,7 @@
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
Utils.setIntentDataAndTypeAndNormalize(
- intent, mAttachment.contentUri, mAttachment.getContentType());
+ intent, mAttachment.contentUri, mime);
try {
getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
diff --git a/src/com/android/mail/compose/ComposeActivity.java b/src/com/android/mail/compose/ComposeActivity.java
index bb3b0f4..e3558bd 100644
--- a/src/com/android/mail/compose/ComposeActivity.java
+++ b/src/com/android/mail/compose/ComposeActivity.java
@@ -447,6 +447,8 @@
previews = savedState.getParcelableArrayList(EXTRA_ATTACHMENT_PREVIEWS);
mRefMessage = (Message) savedState.getParcelable(EXTRA_IN_REFERENCE_TO_MESSAGE);
quotedText = savedState.getCharSequence(EXTRA_QUOTED_TEXT);
+
+ mExtraValues = savedState.getParcelable(EXTRA_VALUES);
} else {
account = obtainAccount(intent);
action = intent.getIntExtra(EXTRA_ACTION, COMPOSE);
@@ -750,7 +752,7 @@
if (!isChangingConfigurations()) {
saveIfNeeded();
- if (isFinishing() && !mPerformedSendOrDiscard) {
+ if (isFinishing() && !mPerformedSendOrDiscard && !isBlank()) {
// log saving upon backing out of activity. (we avoid logging every sendOrSave()
// because that method can be invoked many times in a single compose session.)
logSendOrSave(true /* save */);
@@ -869,6 +871,8 @@
state.putBoolean(EXTRA_SAVE_ENABLED, mSave != null && mSave.isEnabled());
state.putParcelableArrayList(
EXTRA_ATTACHMENT_PREVIEWS, mAttachmentsView.getAttachmentPreviews());
+
+ state.putParcelable(EXTRA_VALUES, mExtraValues);
}
private int getMode() {
@@ -1530,7 +1534,12 @@
final Uri uri = Uri.parse(uriString);
long size = 0;
try {
- size = mAttachmentsView.addAttachment(mAccount, uri);
+ final Attachment a = mAttachmentsView.generateLocalAttachment(uri);
+ size = mAttachmentsView.addAttachment(mAccount, a);
+
+ Analytics.getInstance().sendEvent("send_intent_attachment",
+ Utils.normalizeMimeType(a.getContentType()), null, size);
+
} catch (AttachmentFailureException e) {
LogUtils.e(LOG_TAG, e, "Error adding attachment");
showAttachmentTooBigToast(e.getErrorRes());
@@ -1545,7 +1554,13 @@
ArrayList<Attachment> attachments = new ArrayList<Attachment>();
for (Parcelable uri : uris) {
try {
- attachments.add(mAttachmentsView.generateLocalAttachment((Uri) uri));
+ final Attachment a = mAttachmentsView.generateLocalAttachment(
+ (Uri) uri);
+ attachments.add(a);
+
+ Analytics.getInstance().sendEvent("send_intent_attachment",
+ Utils.normalizeMimeType(a.getContentType()), null, a.size);
+
} catch (AttachmentFailureException e) {
LogUtils.e(LOG_TAG, e, "Error adding attachment");
String maxSize = AttachmentUtils.convertToHumanReadableSize(
@@ -1560,7 +1575,12 @@
final Uri uri = (Uri) extras.getParcelable(Intent.EXTRA_STREAM);
long size = 0;
try {
- size = mAttachmentsView.addAttachment(mAccount, uri);
+ final Attachment a = mAttachmentsView.generateLocalAttachment(uri);
+ size = mAttachmentsView.addAttachment(mAccount, a);
+
+ Analytics.getInstance().sendEvent("send_intent_attachment",
+ Utils.normalizeMimeType(a.getContentType()), null, size);
+
} catch (AttachmentFailureException e) {
LogUtils.e(LOG_TAG, e, "Error adding attachment");
showAttachmentTooBigToast(e.getErrorRes());
@@ -1572,6 +1592,9 @@
if (totalSize > 0) {
mAttachmentsChanged = true;
updateSaveUi();
+
+ Analytics.getInstance().sendEvent("send_intent_with_attachments",
+ Integer.toString(getAttachments().size()), null, totalSize);
}
}
}
diff --git a/src/com/android/mail/providers/Folder.java b/src/com/android/mail/providers/Folder.java
index 0262e06..fb25905 100644
--- a/src/com/android/mail/providers/Folder.java
+++ b/src/com/android/mail/providers/Folder.java
@@ -719,9 +719,9 @@
public String getTypeDescription() {
final String desc;
if (isType(FolderType.INBOX_SECTION)) {
- desc = "inbox_section";
+ desc = "inbox_section:" + persistentId;
} else if (isInbox()) {
- desc = "inbox";
+ desc = "inbox:" + persistentId;
} else if (isDraft()) {
desc = "draft";
} else if (isImportantOnly()) {
@@ -741,7 +741,7 @@
} else if (isViewAll()) {
desc = "all_mail";
} else if (isProviderFolder()) {
- desc = "(other)";
+ desc = "other:" + persistentId;
} else {
desc = "user_folder";
}
diff --git a/src/com/android/mail/ui/ConversationSyncDisabledTipView.java b/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
index 8593f14..f2782d3 100644
--- a/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
+++ b/src/com/android/mail/ui/ConversationSyncDisabledTipView.java
@@ -226,7 +226,7 @@
accountPreferences.resetNumOfDismissesForAccountSyncOff();
// Now check for whether airplane mode is on
- if (Utils.isAirplaneModeOn(context)) {
+ if (Utils.isAirplaneModeOnAndDeviceOffline(context)) {
return ReasonSyncOff.AIRPLANE_MODE_ON;
} else {
mailPrefs.resetNumOfDismissesForAirplaneModeOn();
diff --git a/src/com/android/mail/ui/TwoPaneController.java b/src/com/android/mail/ui/TwoPaneController.java
index 1d44375..646ee52 100644
--- a/src/com/android/mail/ui/TwoPaneController.java
+++ b/src/com/android/mail/ui/TwoPaneController.java
@@ -18,6 +18,7 @@
package com.android.mail.ui;
import android.app.Fragment;
+import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.net.Uri;
@@ -164,6 +165,12 @@
@Override
public void onViewModeChanged(int newMode) {
+ if (mMiscellaneousViewTransactionId >= 0) {
+ final FragmentManager fragmentManager = mActivity.getFragmentManager();
+ fragmentManager.popBackStackImmediate(mMiscellaneousViewTransactionId, 0 /* flags */);
+ mMiscellaneousViewTransactionId = -1;
+ }
+
super.onViewModeChanged(newMode);
if (newMode != ViewMode.WAITING_FOR_ACCOUNT_INITIALIZATION) {
// Clear the wait fragment
@@ -174,7 +181,8 @@
// untouched.
// When the conversation list is made visible again, try to enable the CAB
// mode if any conversations are selected.
- if (newMode == ViewMode.CONVERSATION || newMode == ViewMode.CONVERSATION_LIST){
+ if (newMode == ViewMode.CONVERSATION || newMode == ViewMode.CONVERSATION_LIST
+ || ViewMode.isAdMode(newMode)) {
enableOrDisableCab();
}
}
@@ -342,7 +350,7 @@
@Override
public boolean handleUpPress() {
int mode = mViewMode.getMode();
- if (mode == ViewMode.CONVERSATION) {
+ if (mode == ViewMode.CONVERSATION || mViewMode.isAdMode()) {
handleBackPress();
} else if (mode == ViewMode.SEARCH_RESULTS_CONVERSATION) {
if (mLayout.isConversationListCollapsed()
@@ -388,7 +396,7 @@
int mode = mViewMode.getMode();
if (mode == ViewMode.SEARCH_RESULTS_LIST) {
mActivity.finish();
- } else if (mode == ViewMode.CONVERSATION) {
+ } else if (mode == ViewMode.CONVERSATION || mViewMode.isAdMode()) {
// Go to conversation list.
mViewMode.enterConversationListMode();
} else if (mode == ViewMode.SEARCH_RESULTS_CONVERSATION) {
@@ -558,8 +566,17 @@
return ListView.CHOICE_MODE_SINGLE;
}
+ private int mMiscellaneousViewTransactionId = -1;
+
@Override
public void launchFragment(final Fragment fragment) {
- // TODO(skennedy)
+ final int containerViewId = TwoPaneLayout.MISCELLANEOUS_VIEW_ID;
+
+ final FragmentManager fragmentManager = mActivity.getFragmentManager();
+ final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.replace(containerViewId, fragment, TAG_CUSTOM_FRAGMENT);
+ mMiscellaneousViewTransactionId = fragmentTransaction.commitAllowingStateLoss();
+ fragmentManager.executePendingTransactions();
}
}
diff --git a/src/com/android/mail/ui/TwoPaneLayout.java b/src/com/android/mail/ui/TwoPaneLayout.java
index 2d00d28..f4276a3 100644
--- a/src/com/android/mail/ui/TwoPaneLayout.java
+++ b/src/com/android/mail/ui/TwoPaneLayout.java
@@ -91,10 +91,13 @@
private DrawerLayout mDrawerLayout;
+ private View mMiscellaneousView;
private View mConversationView;
private View mFoldersView;
private View mListView;
+ public static final int MISCELLANEOUS_VIEW_ID = R.id.miscellaneous_pane;
+
private final Runnable mTransitionCompleteRunnable = new Runnable() {
@Override
public void run() {
@@ -158,6 +161,7 @@
mListView = findViewById(R.id.conversation_list_pane);
mListCopyView = (ConversationListCopy) findViewById(R.id.conversation_list_copy);
mConversationView = findViewById(R.id.conversation_pane);
+ mMiscellaneousView = findViewById(MISCELLANEOUS_VIEW_ID);
// all panes start GONE in initial UNKNOWN mode to avoid drawing misplaced panes
mCurrentMode = ViewMode.UNKNOWN;
@@ -165,6 +169,7 @@
mListView.setVisibility(GONE);
mListCopyView.setVisibility(GONE);
mConversationView.setVisibility(GONE);
+ mMiscellaneousView.setVisibility(GONE);
}
@VisibleForTesting
@@ -217,12 +222,14 @@
LogUtils.i(LOG_TAG, "setting up new TPL, w=%d fw=%d cv=%d", parentWidth,
foldersWidth, convWidth);
+ setPaneWidth(mMiscellaneousView, convWidth);
setPaneWidth(mConversationView, convWidth);
}
final int currListWidth = getPaneWidth(mListView);
int listWidth = currListWidth;
switch (mCurrentMode) {
+ case ViewMode.AD:
case ViewMode.CONVERSATION:
case ViewMode.SEARCH_RESULTS_CONVERSATION:
if (!mListCollapsible) {
@@ -263,6 +270,7 @@
int convX = 0, listX = 0, foldersX = 0;
switch (mCurrentMode) {
+ case ViewMode.AD:
case ViewMode.CONVERSATION:
case ViewMode.SEARCH_RESULTS_CONVERSATION: {
final int foldersW = getPaneWidth(mFoldersView);
@@ -330,6 +338,7 @@
// a view intent.
if (mPositionedMode == ViewMode.UNKNOWN) {
mConversationView.setX(convX);
+ mMiscellaneousView.setX(convX);
mListView.setX(listX);
if (!isDrawerView(mFoldersView)) {
mFoldersView.setX(foldersX);
@@ -354,7 +363,12 @@
useHardwareLayer(true);
- mConversationView.animate().x(convX);
+ if (ViewMode.isAdMode(mCurrentMode)) {
+ mMiscellaneousView.animate().x(convX);
+ } else {
+ mConversationView.animate().x(convX);
+ }
+
if (!isDrawerView(mFoldersView)) {
mFoldersView.animate().x(foldersX);
}
@@ -365,7 +379,8 @@
.x(listX)
.alpha(1.0f)
.setListener(mPaneAnimationListener);
- configureAnimations(mConversationView, mFoldersView, mListView, mListCopyView);
+ configureAnimations(mConversationView, mFoldersView, mListView, mListCopyView,
+ mMiscellaneousView);
}
private void configureAnimations(View... views) {
@@ -387,6 +402,7 @@
mListView.setLayerType(layerType, null);
mListCopyView.setLayerType(layerType, null);
mConversationView.setLayerType(layerType, null);
+ mMiscellaneousView.setLayerType(layerType, null);
if (useHardware) {
// these buildLayer calls are safe because layout is the only way we get here
// (i.e. these views must already be attached)
@@ -396,6 +412,7 @@
mListView.buildLayer();
mListCopyView.buildLayer();
mConversationView.buildLayer();
+ mMiscellaneousView.buildLayer();
}
}
@@ -431,6 +448,11 @@
dispatchConversationListVisibilityChange(true);
break;
+ case ViewMode.AD:
+ dispatchConversationVisibilityChanged(false);
+ dispatchConversationListVisibilityChange(false);
+
+ break;
default:
break;
}
@@ -452,6 +474,7 @@
case ViewMode.WAITING_FOR_ACCOUNT_INITIALIZATION:
case ViewMode.SEARCH_RESULTS_LIST:
return totalWidth - computeFolderListWidth(totalWidth);
+ case ViewMode.AD:
case ViewMode.CONVERSATION:
case ViewMode.SEARCH_RESULTS_CONVERSATION:
return (int) (totalWidth * mConversationListWeight);
@@ -505,10 +528,6 @@
return isDrawerView(pane) ? 0 : pane.getLayoutParams().width;
}
- public View getConversationView() {
- return mConversationView;
- }
-
private boolean isDrawerView(View child) {
return child != null && child.getParent() == mDrawerLayout;
}
@@ -527,7 +546,14 @@
mFoldersView.setVisibility(VISIBLE);
mListView.setVisibility(VISIBLE);
mListCopyView.setVisibility(VISIBLE);
+ }
+
+ if (ViewMode.isAdMode(newMode)) {
+ mMiscellaneousView.setVisibility(VISIBLE);
+ mConversationView.setVisibility(GONE);
+ } else {
mConversationView.setVisibility(VISIBLE);
+ mMiscellaneousView.setVisibility(GONE);
}
// set up the drawer as appropriate for the configuration
@@ -585,6 +611,8 @@
s = "conv-list";
} else if (pane == mConversationView) {
s = "conv-view";
+ } else if (pane == mMiscellaneousView) {
+ s = "misc-view";
} else {
s = "???:" + pane;
}
diff --git a/src/com/android/mail/utils/Utils.java b/src/com/android/mail/utils/Utils.java
index 620234a..a992dad 100644
--- a/src/com/android/mail/utils/Utils.java
+++ b/src/com/android/mail/utils/Utils.java
@@ -33,6 +33,8 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@@ -1394,8 +1396,17 @@
}
}
- public static boolean isAirplaneModeOn(Context context) {
- return Settings.System.getInt(context.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON, 0) != 0;
+ public static boolean isAirplaneModeOnAndDeviceOffline(Context context) {
+ final int airplaneMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, 0);
+ if (airplaneMode == 0) {
+ return false;
+ }
+ // Otherwise check if device is online, since it's possible to still use
+ // wifi when airplane mode is on
+ ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = connectivityManager.getActiveNetworkInfo();
+ return (info == null || !info.isConnected());
}
}