Add support for showing help
Change-Id: I61755c203eaef56f2c27d9110f297ee410265934
diff --git a/src/com/android/mail/providers/Account.java b/src/com/android/mail/providers/Account.java
index 8392c54..172df23 100644
--- a/src/com/android/mail/providers/Account.java
+++ b/src/com/android/mail/providers/Account.java
@@ -94,6 +94,12 @@
public final String settingIntentUri;
/**
+ * Uri for VIEW intent that will cause the help screens for this account type to be
+ * shown.
+ */
+ public final String helpIntentUri;
+
+ /**
* The sync status of the account
*/
public final int syncStatus;
@@ -104,7 +110,7 @@
* includes the members described above and name and type from the
* superclass.
*/
- private static final int NUMBER_MEMBERS = 14;
+ private static final int NUMBER_MEMBERS = 15;
/**
* Examples of expected format for the joined account strings
@@ -137,6 +143,7 @@
out.append(expungeMessageUri).append(ACCOUNT_COMPONENT_SEPARATOR);
out.append(undoUri).append(ACCOUNT_COMPONENT_SEPARATOR);
out.append(settingIntentUri).append(ACCOUNT_COMPONENT_SEPARATOR);
+ out.append(helpIntentUri).append(ACCOUNT_COMPONENT_SEPARATOR);
out.append(syncStatus);
return out.toString();
}
@@ -165,7 +172,8 @@
expungeMessageUri = accountMembers[10];
undoUri = accountMembers[11];
settingIntentUri = accountMembers[12];
- syncStatus = Integer.valueOf(accountMembers[13]);
+ helpIntentUri = accountMembers[13];
+ syncStatus = Integer.valueOf(accountMembers[14]);
}
public Account(Parcel in) {
@@ -181,6 +189,7 @@
expungeMessageUri = in.readString();
undoUri = in.readString();
settingIntentUri = in.readString();
+ helpIntentUri = in.readString();
syncStatus = in.readInt();
}
@@ -197,6 +206,7 @@
expungeMessageUri = cursor.getString(UIProvider.ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN);
undoUri = cursor.getString(UIProvider.ACCOUNT_UNDO_URI_COLUMN);
settingIntentUri = cursor.getString(UIProvider.ACCOUNT_SETTINGS_INTENT_URI_COLUMN);
+ helpIntentUri = cursor.getString(UIProvider.ACCOUNT_HELP_INTENT_URI_COLUMN);
syncStatus = cursor.getInt(UIProvider.ACCOUNT_SYNC_STATUS_COLUMN);
}
@@ -242,6 +252,7 @@
dest.writeString(expungeMessageUri);
dest.writeString(undoUri);
dest.writeString(settingIntentUri);
+ dest.writeString(helpIntentUri);
dest.writeInt(syncStatus);
}
diff --git a/src/com/android/mail/providers/AccountCacheProvider.java b/src/com/android/mail/providers/AccountCacheProvider.java
index 84d8d38..c7ec0f3 100644
--- a/src/com/android/mail/providers/AccountCacheProvider.java
+++ b/src/com/android/mail/providers/AccountCacheProvider.java
@@ -116,6 +116,9 @@
} else if (TextUtils.equals(column,
UIProvider.AccountColumns.SETTINGS_INTENT_URI)) {
builder.add(account.mSettingsIntentUri);
+ } else if (TextUtils.equals(column,
+ UIProvider.AccountColumns.HELP_INTENT_URI)) {
+ builder.add(account.mHelpIntentUri);
} else if (TextUtils.equals(column, UIProvider.AccountColumns.SYNC_STATUS)) {
builder.add(Integer.valueOf((int)account.mSyncStatus));
} else {
@@ -198,12 +201,13 @@
private final String mExpungeMessageUri;
private final String mUndoUri;
private final String mSettingsIntentUri;
+ private final String mHelpIntentUri;
private final int mSyncStatus;
public CachedAccount(long id, String name, String uri, long capabilities,
String folderListUri, String searchUri, String fromAddressesUri,
String saveDraftUri, String sendMailUri, String expungeMessageUri,
- String undoUri, String settingsIntentUri, int syncStatus) {
+ String undoUri, String settingsIntentUri, String helpIntentUri, int syncStatus) {
mId = id;
mName = name;
mUri = uri;
@@ -216,6 +220,7 @@
mExpungeMessageUri = expungeMessageUri;
mUndoUri = undoUri;
mSettingsIntentUri = settingsIntentUri;
+ mHelpIntentUri = helpIntentUri;
mSyncStatus = syncStatus;
}
@@ -240,6 +245,7 @@
TextUtils.equals(mExpungeMessageUri, other.mExpungeMessageUri) &&
TextUtils.equals(mUndoUri, other.mUndoUri) &&
TextUtils.equals(mSettingsIntentUri, other.mSettingsIntentUri) &&
+ TextUtils.equals(mHelpIntentUri, other.mHelpIntentUri) &&
(mSyncStatus == other.mSyncStatus);
}
@@ -247,7 +253,7 @@
public int hashCode() {
return Objects.hashCode(mId, mName, mUri, mCapabilities, mFolderListUri, mSearchUri,
mAccountFromAddressesUri, mSaveDraftUri, mSendMailUri, mExpungeMessageUri,
- mUndoUri, mSettingsIntentUri, mSyncStatus);
+ mUndoUri, mSettingsIntentUri, mHelpIntentUri, mSyncStatus);
}
}
}
\ No newline at end of file
diff --git a/src/com/android/mail/providers/UIProvider.java b/src/com/android/mail/providers/UIProvider.java
index 18c5044..d8c5290 100644
--- a/src/com/android/mail/providers/UIProvider.java
+++ b/src/com/android/mail/providers/UIProvider.java
@@ -92,7 +92,8 @@
AccountColumns.EXPUNGE_MESSAGE_URI,
AccountColumns.UNDO_URI,
AccountColumns.SETTINGS_INTENT_URI,
- AccountColumns.SYNC_STATUS
+ AccountColumns.SYNC_STATUS,
+ AccountColumns.HELP_INTENT_URI
};
public static final int ACCOUNT_ID_COLUMN = 0;
@@ -109,6 +110,7 @@
public static final int ACCOUNT_UNDO_URI_COLUMN = 11;
public static final int ACCOUNT_SETTINGS_INTENT_URI_COLUMN = 12;
public static final int ACCOUNT_SYNC_STATUS_COLUMN = 13;
+ public static final int ACCOUNT_HELP_INTENT_URI_COLUMN = 14;
public static final class AccountCapabilities {
/**
@@ -184,6 +186,10 @@
* Whether the provider supports undoing operations. If it doesn't, never show the undo bar.
*/
public static final int UNDO = 0x2000;
+ /**
+ * Whether the account provides help content.
+ */
+ public static final int HELP_CONTENT = 0x4000;
}
public static final class AccountColumns {
@@ -263,6 +269,14 @@
public static String SETTINGS_INTENT_URI = "accountSettingsIntentUri";
/**
+ * Uri for VIEW intent that will cause the help screens for this account type to be
+ * shown.
+ * TODO: When we want to support a heterogeneous set of account types, this value may need
+ * to be moved to a global content provider.
+ */
+ public static String HELP_INTENT_URI = "helpIntentUri";
+
+ /**
* This int column contains the current sync status of the account (the logical AND of the
* sync status of folders in this account)
*/
diff --git a/src/com/android/mail/providers/protos/mock/MockUiProvider.java b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
index 3166b39..7347f9b 100644
--- a/src/com/android/mail/providers/protos/mock/MockUiProvider.java
+++ b/src/com/android/mail/providers/protos/mock/MockUiProvider.java
@@ -269,6 +269,7 @@
accountMap.put(AccountColumns.EXPUNGE_MESSAGE_URI, accountUri + "/expungeMessage");
accountMap.put(AccountColumns.UNDO_URI, accountUri + "/undo");
accountMap.put(AccountColumns.SETTINGS_INTENT_URI, "http://www.google.com");
+ accountMap.put(AccountColumns.HELP_INTENT_URI, "http://www.google.com");
accountMap.put(AccountColumns.SYNC_STATUS, 0);
if (cacheMap) {
@@ -359,6 +360,7 @@
(String)accountInfo.get(AccountColumns.EXPUNGE_MESSAGE_URI),
(String)accountInfo.get(AccountColumns.UNDO_URI),
(String)accountInfo.get(AccountColumns.SETTINGS_INTENT_URI),
+ (String)accountInfo.get(AccountColumns.HELP_INTENT_URI),
(Integer)accountInfo.get(AccountColumns.SYNC_STATUS));
diff --git a/src/com/android/mail/ui/AbstractActivityController.java b/src/com/android/mail/ui/AbstractActivityController.java
index 27825e3..c175c18 100644
--- a/src/com/android/mail/ui/AbstractActivityController.java
+++ b/src/com/android/mail/ui/AbstractActivityController.java
@@ -32,6 +32,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.net.Uri;
+import android.text.TextUtils;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -51,11 +52,14 @@
import com.android.mail.providers.Conversation;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
+import com.android.mail.providers.UIProvider.AccountCapabilities;
import com.android.mail.providers.UIProvider.LastSyncResult;
import com.android.mail.ui.AsyncRefreshTask;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
+import java.lang.Readable;
+
/**
* This is an abstract implementation of the Activity Controller. This class knows how to
* respond to menu items, state changes, layout changes, etc. It weaves together the views and
@@ -103,6 +107,7 @@
private AsyncRefreshTask mAsyncRefreshTask;
private MenuItem mRefreshItem;
+ private MenuItem mHelpItem;
private View mRefreshActionView;
private boolean mRefreshInProgress;
private final Handler mHandler = new Handler();
@@ -237,6 +242,8 @@
mAccount = account;
fetchAccountFolderInfo();
+
+ updateHelpMenuItem();
}
}
@@ -335,6 +342,7 @@
MenuInflater inflater = mActivity.getMenuInflater();
inflater.inflate(mActionBarView.getOptionsMenuId(), menu);
mRefreshItem = menu.findItem(R.id.refresh);
+ mHelpItem = menu.findItem(R.id.help_info_menu_item);
return true;
}
@@ -370,6 +378,10 @@
case R.id.preferences:
showPreferences();
break;
+ case R.id.help_info_menu_item:
+ // TODO: enable context sensitive help
+ Utils.showHelp(mActivity.getActivityContext(), mAccount.helpIntentUri, null);
+ break;
default:
handled = false;
break;
@@ -437,9 +449,19 @@
mRefreshItem.setActionView(null);
}
}
+
+ // Show/hide the help menu item
+ updateHelpMenuItem();
return true;
}
+ private void updateHelpMenuItem() {
+ if (mHelpItem != null) {
+ mHelpItem.setVisible(mAccount != null &&
+ mAccount.supportsCapability(AccountCapabilities.HELP_CONTENT));
+ }
+ }
+
@Override
public void onResume() {
if (mActionBarView != null) {
diff --git a/src/com/android/mail/utils/Utils.java b/src/com/android/mail/utils/Utils.java
index 3648cf5..0711233 100644
--- a/src/com/android/mail/utils/Utils.java
+++ b/src/com/android/mail/utils/Utils.java
@@ -20,9 +20,13 @@
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.net.Uri;
+import android.provider.Browser;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
@@ -40,10 +44,12 @@
import android.webkit.WebView;
import com.android.mail.R;
+import com.android.mail.browse.ConversationCursor;
import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
+import java.util.Locale;
import java.util.Map;
public class Utils {
@@ -70,8 +76,16 @@
* can be very broad and is NOT the preferred way of getting notification.
*/
// TODO: UI Provider has this notification URI?
- public static final String ACTION_NOTIFY_DATASET_CHANGED =
- "com.android.mail.ACTION_NOTIFY_DATASET_CHANGED";
+ public static final String ACTION_NOTIFY_DATASET_CHANGED =
+ "com.android.mail.ACTION_NOTIFY_DATASET_CHANGED";
+
+ /** Parameter keys for context-aware help. */
+ private static final String SMART_HELP_LINK_PARAMETER_NAME = "p";
+
+ private static final String SMART_LINK_APP_VERSION = "version";
+ private static String sVersionCode = null;
+
+ private static final String LOG_TAG = new LogUtils().getLogTag();
/**
* Sets WebView in a restricted mode suitable for email use.
@@ -570,4 +584,88 @@
return intent;
}
+
+ /**
+ * Helper method to show context-aware Gmail help.
+ *
+ * @param context Context to be used to open the help.
+ * @param fromWhere Information about the activity the user was in
+ * when they requested help.
+ */
+ public static void showHelp(Context context, String accountHelpUrl, String fromWhere) {
+ final Uri uri = addParamsToUrl(context, accountHelpUrl);
+ Uri.Builder builder = uri.buildUpon();
+ // Add the activity specific information parameter.
+ if (fromWhere != null) {
+ builder = builder.appendQueryParameter(SMART_HELP_LINK_PARAMETER_NAME, fromWhere);
+ }
+
+ openUrl(context, builder.build());
+ }
+
+ /**
+ * Helper method to open a link in a browser.
+ *
+ * @param context Context
+ * @param uri Uri to open.
+ */
+ private static void openUrl(Context context, Uri uri) {
+ if(uri == null || TextUtils.isEmpty(uri.toString())) {
+ LogUtils.wtf(LOG_TAG, "invalid url in Utils.openUrl(): %s", uri);
+ return;
+ }
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
+ context.startActivity(intent);
+ }
+
+
+ private static Uri addParamsToUrl(Context context, String url) {
+ url = replaceLocale(url);
+ Uri.Builder builder = Uri.parse(url).buildUpon();
+ final String versionCode = getVersionCode(context);
+ if (versionCode != null) {
+ builder = builder.appendQueryParameter(SMART_LINK_APP_VERSION, versionCode);
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Replaces the language/country of the device into the given string. The pattern "%locale%"
+ * will be replaced with the <language_code>_<country_code> value.
+ *
+ * @param str the string to replace the language/country within
+ *
+ * @return the string with replacement
+ */
+ private static String replaceLocale(String str) {
+ // Substitute locale if present in string
+ if (str.contains("%locale%")) {
+ Locale locale = Locale.getDefault();
+ String tmp = locale.getLanguage() + "_" + locale.getCountry().toLowerCase();
+ str = str.replace("%locale%", tmp);
+ }
+ return str;
+ }
+
+ /**
+ * Returns the version code for the package, or null if it cannot be retrieved.
+ */
+ public static String getVersionCode(Context context) {
+ if (sVersionCode == null) {
+ try {
+ sVersionCode = String.valueOf(context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0 /* flags */)
+ .versionCode);
+ } catch (NameNotFoundException e) {
+ LogUtils.e(Utils.LOG_TAG, "Error finding package %s",
+ context.getApplicationInfo().packageName);
+ }
+ }
+ return sVersionCode;
+ }
+
+
+
}