package com.gettingmobile.goodnews.settings; import android.content.Context; import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.util.Log; import android.webkit.WebSettings; import com.actionbarsherlock.view.MenuItem; import com.gettingmobile.android.app.settings.AbstractSettings; import com.gettingmobile.goodnews.R; import com.gettingmobile.goodnews.download.OfflineContentType; import com.gettingmobile.goodnews.download.OfflineStrategy; import com.gettingmobile.goodnews.storage.StorageProvider; import com.gettingmobile.goodnews.storage.StorageProviderFactory; import com.gettingmobile.goodnews.tip.TipStatusStorage; import com.gettingmobile.google.reader.ElementId; import com.gettingmobile.google.reader.Item; import com.gettingmobile.google.reader.ItemContentTreatment; import com.gettingmobile.google.reader.ItemTeaserSource; import com.gettingmobile.google.reader.db.SortOrder; import com.gettingmobile.google.reader.sync.SyncSettings; import com.gettingmobile.net.mobilizer.MobilizerImplementation; import com.gettingmobile.net.mobilizer.UrlMobilizer; import com.gettingmobile.net.mobilizer.UrlMobilizerFactory; import java.text.MessageFormat; import java.util.Calendar; public final class Settings extends AbstractSettings implements SyncSettings, TipStatusStorage { public static final String GLOBAL = "GLOBAL"; private static final int MAX_UNREAD_KEEPING = 10000; private static final String ITEM_VIEW_ACTION_BASE = "pref_item_view_action_"; private StorageProvider databaseStorageProvider = null; private StorageProvider contentStorageProvider = null; private UrlMobilizerFactory mobilizerFactory = new UrlMobilizerFactory(); public Settings(Context context) { super(context); /* * set default values */ Log.d(LOG_TAG, "initializing default values"); PreferenceManager.setDefaultValues(context, R.xml.pref_sync, true); PreferenceManager.setDefaultValues(context, R.xml.pref_view_tag_list, true); PreferenceManager.setDefaultValues(context, R.xml.pref_view_feed_list, true); PreferenceManager.setDefaultValues(context, R.xml.pref_view_item_list, true); PreferenceManager.setDefaultValues(context, R.xml.pref_view_item_view, true); PreferenceManager.setDefaultValues(context, R.xml.pref_news_reading, true); PreferenceManager.setDefaultValues(context, R.xml.pref_storage, true); PreferenceManager.setDefaultValues(context, R.xml.pref_other, true); PreferenceManager.setDefaultValues(context, R.xml.pref_app, true); initContentStorageProviderSetting(); /* * init usage statistics */ initInstallTime(); } /* * usage statistics */ public Calendar getInstallTime() { return getTimestamp("usage_install_time"); } public void initInstallTime() { if (getInstallTime() == null) { setTimestampToNow("usage_install_time"); } } public int getCurrentVersionCode() { return getInt("version_code_current"); } public void setCurrentVersionCode(int versionCode) { final int oldVersionCode = getCurrentVersionCode(); setInt("version_code_current", versionCode); if (versionCode > oldVersionCode) { onUpdate(oldVersionCode, versionCode); } } public int getPreviousVersionCode() { return getInt("version_code_previous"); } public void setPreviousVersionCode(int versionCode) { setInt("version_code_previous", versionCode); } private void onUpdate(int oldVersionCode, int newVersionCode) { Log.i(LOG_TAG, "Updating from version " + oldVersionCode + " to " + newVersionCode); if (oldVersionCode < 207 || (oldVersionCode < 200 && oldVersionCode < 128)) { updateValues(".*mobilizer", "(GETTINGMOBILE|REAT_IT_LATER)", MobilizerImplementation.READABILITY.name()); } } /* * tips */ @Override public boolean wasTipShown(String tipId) { return getBoolean("tip_" + tipId); } @Override public void setTipShown(String tipId) { setBoolean("tip_" + tipId, true); } /* * changelog */ public boolean shouldShowChangelogAutomatically() { return getBoolean("changelog_show_automatically", true); } public void setShouldShowChangelogAutomatically(boolean show) { setBoolean("changelog_show_automatically", show); } /* * authentication */ public void setAccountType(String accountType) { setString("account_type", accountType); } public String getAccountType() { return getString("account_type"); } public String getAccountName() { return getString("account_name"); } public void setAccountName(String accountName) { final SharedPreferences.Editor editor = prefs.edit(); editor.putString("account_name", accountName); editor.commit(); } public String getUserName() { return getString("user_name"); } public void setUserName(String userName) { final SharedPreferences.Editor editor = prefs.edit(); editor.putString("user_name", userName); editor.commit(); } public String getPassword() { return getString("password"); } public void setPassword(String password) { final SharedPreferences.Editor editor = prefs.edit(); editor.putString("password", password); editor.commit(); } public String getAuthToken() { return getString("auth_token"); } public void setAuthToken(String authToken) { final SharedPreferences.Editor editor = prefs.edit(); editor.putString("auth_token", authToken); editor.commit(); } /* * database handling */ public void setDatabasesSwapped(boolean swapped) { setBoolean("databases_swapped", swapped); } public boolean areDatabasesSwapped() { return getBoolean("databases_swapped"); } /* * cleanup */ public Calendar getMostRecentCleanupTimestamp() { return getTimestamp("cleanup_most_recent_timestamp"); } public void setMostRecentCleanupTimestamp() { setTimestampToNow("cleanup_most_recent_timestamp"); } /* * synchronization */ @Override public boolean getPushImmediately() { return getBoolean("sync_push_immediately"); } public int getContinousSyncInterval() { return getIntFromString("sync_continous", 0) * 60 * 1000; } public Calendar getNextContinousSyncTimestamp() { final int intervalMillis = getContinousSyncInterval(); if (intervalMillis <= 0) return null; final Calendar c = getLastSuccessfulPullTimestamp(); if (c != null) { c.add(Calendar.MILLISECOND, intervalMillis); return c; } else { return Calendar.getInstance(); } } public long getNextContinousSyncTimestampInMillis() { final Calendar c = getNextContinousSyncTimestamp(); return c != null ? c.getTimeInMillis() : 0; } public boolean requiresWifiForContinousSync() { return getBoolean("sync_continous_wifi_only"); } public boolean shouldNotifyOnNewUnreadItems() { return getBoolean("sync_notify_unread"); } public String getLabelReadListName() { return getString("sync_labels_readlist"); } @Override public ElementId getLabelReadListId() { return ElementId.createUserLabel(getLabelReadListName()); } @Override public int getMaxUnreadSync() { return getIntFromString("sync_unread_max"); } private boolean syncNewUnreadOnly() { return getBoolean("sync_new_unread_only"); } @Override public Calendar getMinUnreadTimestamp() { Calendar c = getTimestamp("sync_min_unread_timestamp"); if (!syncNewUnreadOnly() || c == null) { c = Calendar.getInstance(); c.setTimeInMillis(0); } return c; } @Override public void setMinUnreadTimestamp(Calendar timestamp) { final Calendar prevSetting = getMinUnreadTimestamp(); if (prevSetting == null || timestamp.after(prevSetting)) { setTimestamp("sync_min_unread_timestamp", timestamp); } } public void resetMinUnreadTimestamp() { setTimestamp("sync_min_unread_timestamp", 0); } @Override public int getMaxUnreadKeeping() { return getBoolean("sync_unread_keeping_restrict") ? getMaxUnreadSync() : MAX_UNREAD_KEEPING; } @Override public int getMaxTaggedSync() { return getIntFromString("sync_tagged_max"); } @Override public int getDaysToCache() { return getIntFromString("sync_cache_days"); } @Override public int getDaysToCleanupUnread() { return getIntFromString("sync_cleanup_unread_days"); } @Override public boolean shouldSyncTag(ElementId tagId) { return getBoolean(tagId.getId() + "_sync", true); } public Calendar getLastSuccessfulPullTimestamp() { return getTimestamp("sync_timestamp_last_successful_pull"); } @Override public void updateLastSuccessfulPullTimestamp() { setTimestampToNow("sync_timestamp_last_successful_pull"); } public Calendar getLastSuccessfulPushTimestamp() { return getTimestamp("sync_timestamp_last_successful_push"); } @Override public void updateLastSuccessfulPushTimestamp() { setTimestampToNow("sync_timestamp_last_successful_push"); } public long getLastFailedSyncTimestampInMillis() { final Calendar c = getLastFailedSyncTimestamp(); return c != null ? c.getTimeInMillis() : 0; } public Calendar getLastFailedSyncTimestamp() { return getTimestamp("sync_timestamp_last_failed"); } @Override public void updateLastFailedSyncTimestamp() { setTimestampToNow("sync_timestamp_last_failed"); } public int getFetchOldMaxAge() { return prefs.getInt("fetch_old_max_age", 31); } public void setFetchOldMaxAge(int maxDays) { setInt("fetch_old_max_age", maxDays); } public int getFetchOldMaxCount() { return prefs.getInt("fetch_old_max_count", 50); } public void setFetchOldMaxCount(int maxCount) { setInt("fetch_old_max_count", maxCount); } /* * item specific settings */ @Override public boolean shouldIgnoreUnread(ElementId feedId) { return feedId != null && getBoolean(feedId.getId() + "_ignore_unread"); } @Override public boolean autoListFeedArticles(ElementId feedId) { /* * the global setting "articles_autolist" does not exist -- we use it here to be able to use the * get...Override() method. */ return getBooleanOverride((feedId != null ? feedId.getId() : null) + "_autolist", "articles_autolist", true); } @Override public ItemContentTreatment getFeedSummaryTreatment(ElementId feedId) { return feedId != null ? getValue(ItemContentTreatment.class, feedId.getId() + "_summary_treatment", ItemContentTreatment.TREAT_AS_SUMMARY) : ItemContentTreatment.TREAT_AS_SUMMARY; } @Override public ItemContentTreatment getFeedContentTreatment(ElementId feedId) { return feedId != null ? getValue(ItemContentTreatment.class, feedId.getId() + "_content_treatment", ItemContentTreatment.TREAT_AS_CONTENT) : ItemContentTreatment.TREAT_AS_CONTENT; } /* * tag list */ public boolean folderClickOpensItemList() { return getIntFromString("folder_click_action") != 0; } public boolean sortByDragAndDropOrder() { return getIntFromString("sort_strategy") != 0; } public boolean shouldShowSyncStatus() { return getBoolean("taglist_show_syncstatus"); } public boolean shouldShowStarredTag() { return getBoolean("taglist_show_starred"); } public boolean shouldShowReadListTag() { return getBoolean("taglist_show_readlist"); } public boolean shouldShowAllItemsTag() { return getBoolean("taglist_show_allitems"); } /* * list */ @Override public int getTeaserWordCount() { return getIntFromString("teaser_word_count"); } @Override public ItemTeaserSource getFeedTeaserSource(ElementId feedId) { return getValue(ItemTeaserSource.class, feedId + "_teaser_source", ItemTeaserSource.PREFER_SUMMARY); } @Override public int getFeedTeaserStartChar(ElementId feedId) { return getIntFromString(feedId + "_teaser_start_char"); } @Override public boolean shouldFixDuplicateItems() { return getBoolean("sync_fix_duplicate_items", true); } public boolean hideRead() { return getBoolean("hide_read"); } public void setHideRead(boolean hideRead) { setBoolean("hide_read", hideRead); } public boolean hideReadInLabelItemList() { return getBoolean("hide_read_label_item_list"); } public void setHideReadInLabelItemList(boolean hideRead) { setBoolean("hide_read_label_item_list", hideRead); } public boolean groupByFeedsInFolders() { return getBoolean("group_folder_item_list"); } public void setGroupByFeedsInFolders(boolean group) { setBoolean("group_folder_item_list", group); } public boolean groupByFeedsInLabels() { return getBoolean("group_label_item_list"); } public void setGroupByFeedsInLabels(boolean group) { setBoolean("group_label_item_list", group); } public SortOrder getItemSortOrder() { return SortOrder.valueOf(getString("item_list_sort_order")); } public void setItemSortOrder(SortOrder sortOrder) { final SharedPreferences.Editor editor = prefs.edit(); editor.putString("item_list_sort_order", sortOrder.name()); editor.commit(); } public boolean offlineIndicatorTogglesReadState() { return getBoolean("item_list_offline_indicator_toggles_read_state"); } public void setOfflineIndicatorTogglesReadState(boolean checked) { setBoolean("item_list_offline_indicator_toggles_read_state", checked); } public WebSettings.TextSize getItemListTitleTextSize() { return getValue(WebSettings.TextSize.class, "item_list_title_text_size"); } /* * implicit labeling */ public boolean markReadOnScrollOver() { return getBoolean("labeling_mark_read_scrollover"); } public boolean markReadOnView() { return getBoolean("labeling_mark_read_on_view"); } public boolean markReadOnTag() { return getBoolean("labeling_mark_read_on_tag"); } public boolean removeFromReadListOnView() { return getBoolean("labeling_remove_readlist_on_view"); } /* * extended control */ public boolean useVolumeKeysForItemNavigation() { return getBoolean("control_item_navigation_volumekeys"); } public boolean useVolumeKeysForArticleScrolling() { return getBoolean("control_item_scroll_volumekeys"); } public boolean articleTurnOverRequiresBorderSwipe() { return getBoolean("item_swipe_border"); } public boolean keepItemScreenOn() { return getBoolean("item_keep_screen_on"); } /* * item display */ public boolean isArticleFullScreenEnabled() { return getBoolean("item_view_full_screen"); } public void setArticleFullScreenEnabled(boolean enabled) { setBoolean("item_view_full_screen", enabled); } public int getItemActionButtonCount() { final String[] keys = { "share", "labels", "browser", "load", "browser_back", "prev", "next" }; int count = 0; for (String key : keys) { if (getActionButtonVisibility(key) == ActionButtonVisibility.ALWAYS) ++count; } return count; } public ActionButtonVisibility getActionButtonVisibility(String key) { return getBoolean(ITEM_VIEW_ACTION_BASE + key) ? ActionButtonVisibility.ALWAYS : ActionButtonVisibility.NEVER; } public int getActionButtonVisibilityFlags(String key) { switch (getActionButtonVisibility(key)) { case IF_ROOM: return MenuItem.SHOW_AS_ACTION_IF_ROOM; case ALWAYS: return MenuItem.SHOW_AS_ACTION_ALWAYS; default: return MenuItem.SHOW_AS_ACTION_NEVER; } } public ItemTitleClickAction getItemTitleClickAction() { return getValue(ItemTitleClickAction.class, "item_view_title_click_action", ItemTitleClickAction.LABELS); } public WebSettings.TextSize getItemViewTextSize() { return getValue(WebSettings.TextSize.class, "item_view_text_size"); } private ItemDisplayType getDisplayType(String key) { final String value = getString(key); return ItemDisplayType.valueOf(value); } public ItemDisplayType getDisplayTypeForBlankItems() { return getDisplayType("item_view_none"); } public ItemDisplayType getDisplayTypeForItemsWithSummary() { return getDisplayType("item_view_summary"); } public ItemDisplayType getDisplayTypeForItemsWithContent() { return getDisplayType("item_view_content"); } public ItemDisplayType getItemDisplayType(Item item) { ItemDisplayType displayType = getFeedItemDisplayType(item); if (displayType == null) { /* * there are no feed specific settings for this item -- use global settings */ if (item.hasContent()) { displayType = getDisplayTypeForItemsWithContent(); if (displayType == ItemDisplayType.SUMMARY && !item.hasSummary()) { displayType = ItemDisplayType.CONTENT; } } else if (item.hasSummary()) { displayType = getDisplayTypeForItemsWithSummary(); } else { displayType = getDisplayTypeForBlankItems(); } } /* * ensure that display type matches article capabilities */ if ((displayType == ItemDisplayType.BROWSER || displayType == ItemDisplayType.LOAD) && item.getAlternate() == null) { displayType = ItemDisplayType.CONTENT; } if (displayType == ItemDisplayType.CONTENT && !item.hasContent()) { displayType = ItemDisplayType.SUMMARY; } if (displayType == ItemDisplayType.SUMMARY && !item.hasSummary()) { displayType = ItemDisplayType.NOTHING; } return displayType; } /* * UI Others */ public boolean automaticallyCloseReadItemList() { return getBoolean("ui_other_close_empty_item_list"); } public Theme getTheme() { return getValue(Theme.class, "theme", Theme.WHITE); } public void setTheme(Theme theme) { setValue("theme", theme); } public boolean shouldUnsplitActionBar() { return getBoolean("actionbar_unsplit"); } /* * Notifications */ public boolean showSyncFinishedNotificationInLists() { return getBoolean("notifications_list_sync_finished"); } public void setShowSyncFinishedNotificationInLists(boolean enable) { setBoolean("notifications_list_sync_finished", enable); } /* * Confirmations */ public boolean confirmMarkAllReadInTagList() { return getBoolean("confirmations_mark_read_in_tag_list"); } public boolean confirmMarkAllReadInFeedList() { return getBoolean("confirmations_mark_read_in_feed_list"); } public boolean confirmMarkAllReadInItemList() { return getBoolean("confirmations_mark_read_in_item_list"); } /* * News Reading */ public MobilizerImplementation getMobilizerImplementation(ElementId feedId) { return getValueOverride(MobilizerImplementation.class, feedId.getId() + "_mobilizer", "mobilizer", MobilizerImplementation.NONE); } public UrlMobilizer getUrlMobilizer(ElementId feedId) { return mobilizerFactory.getMobilizer(getMobilizerImplementation(feedId)); } public boolean scaleImages(ElementId feedId) { return getBooleanOverride((feedId != null ? feedId.getId() : null) + "_scale_images", "scale_images"); } protected ItemDisplayType getFeedItemDisplayType(Item item) { final ElementId feedId = item.getFeedId(); if (feedId == null) return null; final String name = getString(feedId.getId() + "_item_view"); return name != null && !GLOBAL.equals(name) ? ItemDisplayType.valueOf(name) : null; } public OfflineContentType getOfflineContentType(ElementId feedId) { return getValueOverride(OfflineContentType.class, feedId.getId() + "_offline_content", "offline_content", OfflineContentType.TEXT); } public OfflineStrategy getOfflineStrategy() { return getValue(OfflineStrategy.class, "offline_strategy", OfflineStrategy.MANUAL); } public boolean offlineDownloadRequiresWifi() { return getBoolean("offline_wifi"); } /* * storage stuff */ @Override public boolean cancelSyncOnLowDeviceStorage() { return getBoolean("sync_cancel_on_low_device_storage"); } private StorageProvider getStorageProvider(String key, StorageProvider current, StorageProvider.Storage defaultStorage) { StorageProvider.Storage requestedStorage = getValue(StorageProvider.Storage.class, key, defaultStorage); if (current == null || (requestedStorage != null && current.getType() != requestedStorage)) { current = StorageProviderFactory.createStorageProvider(context, requestedStorage); } return current; } private StorageProvider getStorageProvider(String key, StorageProvider current) { return getStorageProvider(key, current, StorageProvider.Storage.INTERNAL); } private void initContentStorageProviderSetting() { final StorageProvider.Storage storage = getValue(StorageProvider.Storage.class, "content_storage_provider", null); if (storage == null) { setValue("content_storage_provider", getValue(StorageProvider.Storage.class, "database_storage_provider", StorageProvider.Storage.EXTERNAL)); } } @Override public StorageProvider getContentStorageProvider() { contentStorageProvider = getStorageProvider("content_storage_provider", contentStorageProvider, null); return contentStorageProvider; } @Override public StorageProvider getDatabaseStorageProvider() { databaseStorageProvider = getStorageProvider("database_storage_provider", databaseStorageProvider); return databaseStorageProvider; } public void setDatabaseStorageProvider(StorageProvider storageProvider) { setValue("database_storage_provider", storageProvider.getType()); } @Override public boolean storeContentInFiles() { return !getBoolean("enforce_content_database_storage", false); } /* * other stuff */ /** * Returns the content format for sharing links. Argument 0 is the link and argument 1 the title. */ public MessageFormat getShareContentFormat() { return new MessageFormat(getString("share_content")); } public boolean checkForInternetConnection() { return getBoolean("check_for_internet_connection"); } public String getUserEMailAddress() { return getString("user_email_address"); } public void setUserEMailAddress(String emailAddress) { setString("user_email_address", emailAddress); } /* * info & support stuff */ public boolean autoShowUsageTips() { return getBoolean("tips_auto_show"); } public void setAutoShowUsageTips(boolean show) { setBoolean("tips_auto_show", show); } }