Add more switches to enable/disable carrier features

Add bools to enable/disable the following carrier specific features:
- Exit menu item with 'Minimize or quit' dialog
- Display page title instead of URL in URL bar
- Allow users to provide custom download path
Add method to detect if a carrier specific feature is enabled.

Change-Id: I9db1b16afd14e476de474e8c86bd60ba1a450aba
diff --git a/src/com/android/browser/BrowserConfigBase.java b/src/com/android/browser/BrowserConfigBase.java
index 9dd0bc0..a96e6ad 100644
--- a/src/com/android/browser/BrowserConfigBase.java
+++ b/src/com/android/browser/BrowserConfigBase.java
@@ -90,5 +90,39 @@
             return null;
         }
     }
+
+    public static enum Feature {
+        WAP2ESTORE, /* Launch custom app when URL scheme is 'estore:' */
+        DRM_UPLOADS, /* Prevent uploading files with DRM filename extensions */
+        NETWORK_NOTIFIER, /* Prompt user to select WiFi access point or otherwise enable WLAN */
+        EXIT_DIALOG, /* Add 'Exit' menu item and show 'Minimize or quit' dialog */
+        TITLE_IN_URL_BAR, /* Display page title instead of url in URL bar */
+        CUSTOM_DOWNLOAD_PATH, /* Allow users to provide custom download path */
+        ALLOW_MEDIA_DOWNLOADS, /* Add 'Allow media downloads' menu item */
+        DISABLE_HISTORY /* Allow disabling saving history for non-incognito tabs */
+    }
+
+    public boolean hasFeature(Feature feature) {
+        switch (feature) {
+            case WAP2ESTORE:
+                return mContext.getResources().getBoolean(R.bool.feature_wap2estore);
+            case DRM_UPLOADS:
+                return mContext.getResources().getBoolean(R.bool.feature_drm_uploads);
+            case NETWORK_NOTIFIER:
+                return mContext.getResources().getBoolean(R.bool.feature_network_notifier);
+            case EXIT_DIALOG:
+                return mContext.getResources().getBoolean(R.bool.feature_exit_dialog);
+            case TITLE_IN_URL_BAR:
+                return mContext.getResources().getBoolean(R.bool.feature_title_in_URL_bar);
+            case CUSTOM_DOWNLOAD_PATH:
+                return mContext.getResources().getBoolean(R.bool.feature_custom_download_path);
+            case ALLOW_MEDIA_DOWNLOADS:
+                return mContext.getResources().getBoolean(R.bool.feature_allow_media_downloads);
+            case DISABLE_HISTORY:
+                return mContext.getResources().getBoolean(R.bool.feature_disable_history);
+            default:
+                return false;
+        }
+    }
 }
 
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 7e07721..4d7bc55 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -734,18 +734,23 @@
     }
 
     public boolean allowMediaDownloads() {
-        boolean enableMediaDownloads = mController.getContext().getResources().getBoolean(
-                                       R.bool.def_enable_media_downloads);
-        boolean shouldAllowMediaDownloads = mPrefs.getBoolean(
-                                        PREF_ALLOW_MEDIA_DOWNLOADS, enableMediaDownloads);
+        // Return false if preference is not exposed to user
+        if (!BrowserConfig.getInstance(mContext)
+                .hasFeature(BrowserConfig.Feature.ALLOW_MEDIA_DOWNLOADS))
+            return false;
 
-        if(!mPrefs.contains(PREF_ALLOW_MEDIA_DOWNLOADS)){
+        // Otherwise, look at default value
+        boolean defaultAllowMediaDownloadsValue = mController.getContext()
+                .getResources().getBoolean(R.bool.def_allow_media_downloads);
+
+        // If preference is not saved, save default value
+        if (!mPrefs.contains(PREF_ALLOW_MEDIA_DOWNLOADS)){
             Editor edit = mPrefs.edit();
-            edit.putBoolean(PREF_ALLOW_MEDIA_DOWNLOADS, shouldAllowMediaDownloads);
+            edit.putBoolean(PREF_ALLOW_MEDIA_DOWNLOADS, defaultAllowMediaDownloadsValue);
             edit.apply();
         }
 
-        return shouldAllowMediaDownloads;
+        return mPrefs.getBoolean(PREF_ALLOW_MEDIA_DOWNLOADS, defaultAllowMediaDownloadsValue);
     }
 
     // TODO: Cache
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index c149a0b..181b148 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -919,8 +919,8 @@
         CookieSyncManager.getInstance().resetSync();
         WifiManager wifiMgr = (WifiManager) this.getContext()
                 .getSystemService(Context.WIFI_SERVICE);
-        boolean networkNotifier =
-            mActivity.getApplicationContext().getResources().getBoolean(R.bool.network_notifier);
+        boolean networkNotifier = BrowserConfig.getInstance(getContext())
+                .hasFeature(BrowserConfig.Feature.NETWORK_NOTIFIER);
         if (networkNotifier && mNetworkShouldNotify && wifiMgr.isWifiEnabled()){
             handleNetworkNotify(view);
         } else {
@@ -1111,12 +1111,12 @@
 
     @Override
     public void doUpdateVisitedHistory(Tab tab, boolean isReload) {
-        boolean disableHistoryWrites =
-                mActivity.getResources().getBoolean(R.bool.def_disable_history);
+        // Don't save anything in private browsing mode or when disabling history
+        // for regular tabs is enabled
+        if (tab.isPrivateBrowsingEnabled() || BrowserConfig.getInstance(getContext())
+                        .hasFeature(BrowserConfig.Feature.DISABLE_HISTORY))
+            return;
 
-        // Don't save anything in private browsing mode or when explicitly set
-        // not to write history via an overlay
-        if (tab.isPrivateBrowsingEnabled() || disableHistoryWrites) return;
         String url = tab.getOriginalUrl();
 
         if (TextUtils.isEmpty(url)
@@ -2018,7 +2018,9 @@
                              "android.os.SystemProperties","get", type, params);
                 if (ret != null && ret.equals("enable"))
                     break;
-                showExitDialog(mActivity);
+                if (BrowserConfig.getInstance(getContext())
+                        .hasFeature(BrowserConfig.Feature.EXIT_DIALOG))
+                    showExitDialog(mActivity);
                 return true;
             case R.id.homepage_menu_id:
                 Tab current = mTabControl.getCurrentTab();
@@ -3138,14 +3140,18 @@
     void goBackOnePageOrQuit() {
         Tab current = mTabControl.getCurrentTab();
         if (current == null) {
-            /*
-             * Instead of finishing the activity, simply push this to the back
-             * of the stack and let ActivityManager to choose the foreground
-             * activity. As BrowserActivity is singleTask, it will be always the
-             * root of the task. So we can use either true or false for
-             * moveTaskToBack().
-             */
-            showExitDialog(mActivity);
+            if (BrowserConfig.getInstance(getContext()).hasFeature(BrowserConfig.Feature.EXIT_DIALOG)) {
+                showExitDialog(mActivity);
+            } else {
+                /*
+                 * Instead of finishing the activity, simply push this to the back
+                 * of the stack and let ActivityManager to choose the foreground
+                 * activity. As BrowserActivity is singleTask, it will be always the
+                 * root of the task. So we can use either true or false for
+                 * moveTaskToBack().
+                 */
+                mActivity.moveTaskToBack(true);
+            }
             return;
         }
         if (current.canGoBack()) {
@@ -3158,7 +3164,13 @@
                 switchToTab(parent);
                 // Now we close the other tab
                 closeTab(current);
+            } else if (BrowserConfig.getInstance(getContext())
+                    .hasFeature(BrowserConfig.Feature.EXIT_DIALOG)) {
+                showExitDialog(mActivity);
             } else {
+                if ((current.getAppId() != null) || current.closeOnBack()) {
+                    closeCurrentTab(true);
+                }
                 /*
                  * Instead of finishing the activity, simply push this to the back
                  * of the stack and let ActivityManager to choose the foreground
@@ -3166,7 +3178,7 @@
                  * root of the task. So we can use either true or false for
                  * moveTaskToBack().
                  */
-                showExitDialog(mActivity);
+                mActivity.moveTaskToBack(true);
             }
         }
     }
diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java
index 01435b6..819608d 100644
--- a/src/com/android/browser/NavigationBarBase.java
+++ b/src/com/android/browser/NavigationBarBase.java
@@ -210,7 +210,8 @@
         stopEditingUrl();
         if (UrlInputView.TYPED.equals(source)) {
             String url = null;
-            boolean wap2estore = getContext().getResources().getBoolean(R.bool.wap2estore);
+            boolean wap2estore = BrowserConfig.getInstance(getContext())
+                    .hasFeature(BrowserConfig.Feature.WAP2ESTORE);
             if ((wap2estore && isEstoreTypeUrl(text)) || isRtspTypeUrl(text)
                 || isMakeCallTypeUrl(text)) {
                 url = text;
diff --git a/src/com/android/browser/NavigationBarPhone.java b/src/com/android/browser/NavigationBarPhone.java
index e73f218..b07f035 100644
--- a/src/com/android/browser/NavigationBarPhone.java
+++ b/src/com/android/browser/NavigationBarPhone.java
@@ -145,7 +145,9 @@
         if (!isEditingUrl()) {
            // add for carrier requirement - show title from native instead of url
             Tab currentTab = mUiController.getTabControl().getCurrentTab();
-            if (currentTab != null && currentTab.getTitle() != null) {
+            if (BrowserConfig.getInstance(getContext())
+                    .hasFeature(BrowserConfig.Feature.TITLE_IN_URL_BAR) &&
+                    currentTab != null && currentTab.getTitle() != null) {
                 mUrlInput.setText(currentTab.getTitle(), false);
             } else if (title == null) {
                 mUrlInput.setText(R.string.new_tab);
diff --git a/src/com/android/browser/UploadHandler.java b/src/com/android/browser/UploadHandler.java
index e0d1527..2041ecf 100644
--- a/src/com/android/browser/UploadHandler.java
+++ b/src/com/android/browser/UploadHandler.java
@@ -124,9 +124,11 @@
             filePath = "file://"+filePath;
         }
 
-        // Add for carrier feature - prevent uploading DRM type files.
-        boolean drmUploadEnabled = mController.getContext().getResources().getBoolean(
-                                       R.bool.drm_uploads);
+        // Add for carrier feature - prevent uploading DRM type files based on file extension. This
+        // is not a secure implementation since malicious users can trivially modify the filename.
+        // DRM files can be securely detected by inspecting their integrity protected content.
+        boolean drmUploadEnabled = BrowserConfig.getInstance(mController.getContext())
+                .hasFeature(BrowserConfig.Feature.DRM_UPLOADS);
         boolean isDRMFileType = false;
         if (drmUploadEnabled && filePath != null
                 && (filePath.endsWith(".fl") || filePath.endsWith(".dm")
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index c841d46..8ecffe4 100755
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -108,8 +108,8 @@
         }
 
         // add for carrier feature - wap2estore
-        boolean wap2estore =
-                mActivity.getApplicationContext().getResources().getBoolean(R.bool.wap2estore);
+        boolean wap2estore = BrowserConfig.getInstance(mController.getContext())
+                .hasFeature(BrowserConfig.Feature.WAP2ESTORE);
         if (wap2estore && isEstoreTypeUrl(url) && handleEstoreTypeUrl(url)) {
             return true;
         }
diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
index 9ffa09b..e6f2f1c 100644
--- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
+++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -34,6 +34,7 @@
 import android.widget.Toast;
 
 import com.android.browser.BrowserActivity;
+import com.android.browser.BrowserConfig;
 import com.android.browser.BrowserSettings;
 import com.android.browser.DownloadHandler;
 import com.android.browser.PreferenceKeys;
@@ -77,21 +78,30 @@
         e = mFragment.findPreference("accessibility_menu");
         e.setOnPreferenceClickListener(this);
 
+        // Below are preferences for carrier specific features
+        PreferenceScreen contentSettingsPrefScreen =
+                (PreferenceScreen) mFragment.findPreference("content_settings");
+        if (!BrowserConfig.getInstance(mFragment.getActivity().getApplicationContext())
+                .hasFeature(BrowserConfig.Feature.ALLOW_MEDIA_DOWNLOADS))
+            contentSettingsPrefScreen.removePreference(contentSettingsPrefScreen
+                    .findPreference(PreferenceKeys.PREF_ALLOW_MEDIA_DOWNLOADS));
 
-        onInitdownloadSettingsPreference();
-    }
+        if (!BrowserConfig.getInstance(mFragment.getActivity().getApplicationContext())
+                .hasFeature(BrowserConfig.Feature.CUSTOM_DOWNLOAD_PATH)) {
+            contentSettingsPrefScreen.removePreference(contentSettingsPrefScreen
+                    .findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH));
+        } else {
+            PreferenceScreen downloadPathPreset =
+                    (PreferenceScreen) mFragment.findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH);
+            downloadPathPreset.setOnPreferenceClickListener(onClickDownloadPathSettings());
 
-    private void onInitdownloadSettingsPreference() {
-        PreferenceScreen downloadPathPreset =
-                (PreferenceScreen) mFragment.findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH);
-        downloadPathPreset.setOnPreferenceClickListener(onClickDownloadPathSettings());
-
-        String downloadPath = downloadPathPreset.getSharedPreferences().
-                getString(PreferenceKeys.PREF_DOWNLOAD_PATH,
-                        BrowserSettings.getInstance().getDownloadPath());
-        String downloadPathForUser = DownloadHandler.getDownloadPathForUser(mFragment.getActivity(),
-                downloadPath);
-        downloadPathPreset.setSummary(downloadPathForUser);
+            String downloadPath = downloadPathPreset.getSharedPreferences().
+                    getString(PreferenceKeys.PREF_DOWNLOAD_PATH,
+                            BrowserSettings.getInstance().getDownloadPath());
+            String downloadPathForUser = DownloadHandler.getDownloadPathForUser(mFragment.getActivity(),
+                    downloadPath);
+            downloadPathPreset.setSummary(downloadPathForUser);
+        }
     }
 
     private Preference.OnPreferenceClickListener onClickDownloadPathSettings() {