/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at
* src/com/vodafone360/people/VODAFONE.LICENSE.txt or
* http://github.com/360/360-Engine-for-Android
* See the License for the specific language governing permissions and
* limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each file and
* include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the fields
* enclosed by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2010 Vodafone Sales & Services Ltd. All rights reserved.
* Use is subject to license terms.
*/
package com.vodafone360.people;
import java.lang.ref.SoftReference;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.content.SharedPreferences;
import com.vodafone360.people.database.tables.ActivitiesTable.TimelineSummaryItem;
import com.vodafone360.people.datatypes.Contact;
import com.vodafone360.people.datatypes.ContactSummary;
import com.vodafone360.people.engine.EngineManager;
import com.vodafone360.people.engine.contactsync.SyncStatus;
import com.vodafone360.people.service.ServiceStatus;
import com.vodafone360.people.service.io.api.Auth;
import com.vodafone360.people.utils.LogUtils;
import com.vodafone360.people.utils.LoginPreferences;
import com.vodafone360.people.utils.ThirdPartyAccount;
/**
* Caches information about the current state of the application. Stores most
* recent activity and caches other information such as login details, so that
* the application is returned to its most recent state when brought back to the
* foreground or re-entered. The cached details can be cleared if required (as
* part of 'Remove user data' for example).
*/
public class ApplicationCache {
/** Text key for Terms of Service content. **/
private final static String TERMS_OF_SERVICE = "TERMS_OF_SERVICE";
/** Text key for Terms of Service last updated time. **/
private final static String TERMS_OF_SERVICE_TIME = "TERMS_OF_SERVICE_TIME";
/** Text key for Privacy content. **/
private final static String PRIVACY = "PRIVACY";
/** Text key for Privacy last updated time. **/
private final static String PRIVACY_TIME = "PRIVACY_TIME";
/**
* Refresh any cached terms of service or privacy content after 10 minutes.
*/
private final static long REFRESH_TIME = 10 * 60 * 1000;
private static final String TRUE = "true";
private static final String FALSE = "false";
/**
* Login details are stored in the preferences file so that they can be used
* to pre-populate the edit fields if the user is interrupted in the middle
* of login/signup
*/
public static final String PREFS_FILE = "NOW_PLUS";
public static final String CONTACT_DATA = "ContactData";
public static final String CONTACT_SUMMARY = "ContactSummary";
public static final String CONTACT_ID = "CONTACTID";
public static final String CONTACT_NAME = "CONTACTNAME";
public static final String CONTACT_NUMBER = "CONTACTNUMBER";
public static final String CONTACT_NETWORK = "CONTACTNETWORK";
public static final String CONTACT_MODIFIED = "ContactModified";
public static final String STARTUP_LAUNCH_PATH_KEY = "LAUNCHED_FROM";
public static final String ADD_ACCOUNT_CLICKED = "ADD_ACCOUNT_CLICKED";
/***
* New String ID for Opening a chat from contextual menu, always opens the first connected (first in list) chat account.
*/
public static final String PREFERRED_ONLINE_SNS = "PREFERRED_ONLINE_SNS";
public static final int RESULT_DELETE = -100;
public static final int CONTACT_PROFILE_VIEW = 0;
public static final int CONTACT_PROFILE_EDIT = 1;
public static final int CONTACT_PROFILE_ADD = 2;
public static final int CONTACT_PROFILE_VIEW_ME = 3;
public static final String THIRD_PARTY_ACCOUNT_NAME_KEY = "ThirdPartyAccountName";
public static final String THIRD_PARTY_ACCOUNT_NETWORK_KEY = "ThirdPartyNetworkName";
public static final String THIRD_PARTY_ACCOUNT_USERNAME_KEY = "ThirdPartyAccountUsername";
public static final String THIRD_PARTY_ACCOUNT_PASSWORD_KEY = "ThirdPartyAccountPassword";
public static final String THIRD_PARTY_ACCOUNT_CAPABILITIES = "ThirdPartyAccountCapabilities";
public static final String THIRD_PARTY_ACCOUNT_ERROR_CODE = "ThirdPartyAccountErrorCode";
private final static String FACEBOOK_SUBSCRIBED = "FacebookSubscribed";
private final static String HYVES_SUBSCRIBED = "HyvesSubscribed";
public final static String PREFS_NAME = "NowPlus_Prefs";
// Check settings
public final static String PREFS_CHECK_FREQUENCY = "checkFrequency";
// Upgrade version - these values are deleted when the latest version is not
// new
public final static String PREFS_LAST_DIALOG_DATE = "lastDialogDate";
public final static String PREFS_LAST_CHECKED_DATE = "lastCheckedDate";
public final static String PREFS_UPGRADE_LATEST_VERSION = "upgradeLatestVersion";
public final static String PREFS_UPGRADE_URL = "upgradeUrl";
public final static String PREFS_UPGRADE_TEXT = "upgradeText";
/**
* To keep track of whether contact sync screen is visible to the user.
*/
private static boolean sContactSyncScreenVisible = false;
/**
* Current state of the Activities engine fetching older time line logic.
*/
private static boolean sFetchingOlderTimeline = false;
/**
* Current state of the Activities engine updating statuses logic.
*/
private static boolean sUpdatingStatuses = false;
/**
* Current state of the Activities engine fetching newer time line logic.
*/
private static boolean sFetchingOlderStatuses = false;
public static String sIsNewMessage = "isNewMessage";
private static String mPrivacyLanguage;
private static String mTermsLanguage;
// Frequency setting descriptions and defaults
public final static long[] FREQUENCY_SETTING_LONG = {
-1, // Off
7 * 24 * 60 * 60 * 1000, // Weekly
24 * 60 * 60 * 1000, // Daily
6 * 60 * 60 * 1000, // Every 6 hours
1 * 60 * 60 * 1000, // Hourly
10 * 60 * 1000
// Every 10 minutes
};
/** In memory cache of the current contacts sync status. **/
private SyncStatus mSyncStatus = null;
private boolean mScanThirdPartyAccounts = true;
private boolean mAcceptedTermsAndConditions = false;
private int mIdentityBeingProcessed = -1;
private ArrayList<ThirdPartyAccount> mThirdPartyAccountsCache;
private ContactSummary mMeProfileSummary;
private Contact mCurrentContact;
private ContactSummary mCurrentContactSummary;
private ServiceStatus mServiceStatus = ServiceStatus.ERROR_UNKNOWN;
/**
* The constant for storing the "Add Account" button state (hidden or shown).
*/
public static final String JUST_LOGGED_IN = "first_time";
private TimelineSummaryItem mCurrentTimelineSummary;
private long mCurrentContactFilter;
/** Cached whether ThirdPartyAccountsActivity is opened. */
private boolean mIsAddAccountActivityOpened;
/** Cached filter type for TimelineListActivity. **/
private int mTimelineListActivityFilter = 0;
/** Cached filter type for TimelineHistoryActivity. **/
private int mTimelineHistoryActivityFilter = 0;
/**
* True if the menu "Sync Now" request is being processed.
*/
private static boolean sIsContactSyncBusy = false;
/**
* Setter for the TimelineListActivityFilter value.
*
* @param filter Value to set.
*/
public final void setTimelineListActivityFilter(final int filter) {
mTimelineListActivityFilter = filter;
}
/**
* Getter for the TimelineListActivityFilter value.
*
* @return Cached value for the TimelineListActivityFilter.
*/
public final int getTimelineListActivityFilter() {
return mTimelineListActivityFilter;
}
/**
* Setter for the TimelineHistoryActivityFilter value.
*
* @param filter Value to set.
*/
public final void setTimelineHistoryActivityFilter(final int filter) {
mTimelineHistoryActivityFilter = filter;
}
/**
* Getter for the TimelineHistoryActivityFilter value.
*
* @return Cached value for the TimelineListActivityFilter.
*/
public final int getTimelineHistoryActivityFilter() {
return mTimelineHistoryActivityFilter;
}
/***
* GETTER Whether "add Account" activity is opened
*
* @return True if "add Account" activity is opened
*/
public boolean addAccountActivityOpened() {
return mIsAddAccountActivityOpened;
}
/***
* SETTER Whether "add Account" activity is opened.
*
* @param flag if "add Account" activity is opened
*/
public void setAddAccountActivityOpened(final boolean flag) {
mIsAddAccountActivityOpened = flag;
}
/**
* Set whether application should re-scan 3rd party accounts.
*
* @param state true if application should re-scan 3rd party accounts.
*/
public void setScanThirdPartyAccounts(boolean state) {
mScanThirdPartyAccounts = state;
}
/**
* Return whether application should re-scan 3rd party accounts.
*
* @return true if application should re-scan 3rd party accounts.
*/
public boolean getScanThirdPartyAccounts() {
return mScanThirdPartyAccounts;
}
/**
* Set index of Identity currently being processed.
*
* @param index Index of Identity currently being processed.
*/
public void setIdentityBeingProcessed(int index) {
mIdentityBeingProcessed = index;
}
/**
* Return index of the Identity currently being processed.
*
* @return index of the Identity currently being processed.
*/
public int getIdentityBeingProcessed() {
return mIdentityBeingProcessed;
}
/**
* Set whether user has accepted the Terms and Conditions on sign-up.
*
* @param state true if user has accepted terms and conditions.
*/
public void setAcceptedTermsAndConditions(boolean state) {
mAcceptedTermsAndConditions = state;
}
/**
* Return whether user has accepted the Terms and Conditions on sign-up.
*
* @return true if user has accepted terms and conditions.
*/
public boolean getAcceptedTermsAndConditions() {
return mAcceptedTermsAndConditions;
}
/**
* Sets the language for the cached terms string. If the language of the
* device changes, the cache becomes invalid
*
* @param privacyLanguage language of last fetched terms string
*/
public static void setTermsLanguage(String termsLanguage) {
mTermsLanguage = termsLanguage;
}
/**
* Sets the language for the cached privacy string. If the language of the
* device changes, the cache becomes invalid
*
* @param privacyLanguage language of last fetched privacy string
*/
public static void setPrivacyLanguage(String privacyLanguage) {
mPrivacyLanguage = privacyLanguage;
}
/**
* Clear all cached data currently stored in People application.
*/
public void clearCachedData(Context context) {
LoginPreferences.clearPreferencesFile(context);
LoginPreferences.clearCachedLoginDetails();
setBooleanValue(context, JUST_LOGGED_IN, true);
setBooleanValue(context, ADD_ACCOUNT_CLICKED, false);
mScanThirdPartyAccounts = true;
mIdentityBeingProcessed = -1;
mAcceptedTermsAndConditions = false;
mMeProfileSummary = null;
mCurrentContact = null;
mCurrentContactSummary = null;
mTimelineListActivityFilter = 0;
mTimelineHistoryActivityFilter = 0;
mCurrentContactFilter = -1;
mServiceStatus = ServiceStatus.ERROR_UNKNOWN;
mThirdPartyAccountsCache = null;
mSyncStatus = null;
mIsAddAccountActivityOpened = false;
sFetchingOlderTimeline = false;
sUpdatingStatuses = false;
sFetchingOlderStatuses = false;
sContactSyncScreenVisible = false;
}
/**
* Gets the ME profile object.
*
* @return The ME profile object.
*/
public ContactSummary getMeProfile() {
return mMeProfileSummary;
}
/**
* Sets the ME profile object.
*
* @param summary ContyactSummary for Me profile.
*/
public void setMeProfile(ContactSummary summary) {
mMeProfileSummary = summary;
}
/**
* Gets the contact currently being viewed in the UI.
*
* @return The currently view contact.
*/
public Contact getCurrentContact() {
return mCurrentContact;
}
/**
* Sets the contact currently being viewed in the UI.
*
* @param contact The currently viewed contact.
*/
public void setCurrentContact(Contact contact) {
mCurrentContact = contact;
}
/**
* Gets the summary information of the contact currently being viewed in the
* UI.
*
* @return Contact summary information.
*/
public ContactSummary getCurrentContactSummary() {
return mCurrentContactSummary;
}
/**
* Sets the summary information of the contact currently being viewed in the
* UI.
*
* @param contactSummary Contact summary information.
*/
public void setCurrentContactSummary(ContactSummary contactSummary) {
mCurrentContactSummary = contactSummary;
}
/**
* Return status of request issued to People service.
*
* @return status of request issued to People service.
*/
public ServiceStatus getServiceStatus() {
return mServiceStatus;
}
/**
* Set status of request issued to People service.
*
* @param status of request issued to People service.
*/
public void setServiceStatus(ServiceStatus status) {
mServiceStatus = status;
}
/**
* Cache list of 3rd party accounts (Identities) associated with current
* login.
*
* @param list List of ThirdPartyAccount items retrieved from current login.
*/
public void storeThirdPartyAccounts(Context context, ArrayList<ThirdPartyAccount> list) {
setValue(context, FACEBOOK_SUBSCRIBED, EngineManager.getInstance().getIdentityEngine().isFacebookInThirdPartyAccountList() + "");
setValue(context, HYVES_SUBSCRIBED, EngineManager.getInstance().getIdentityEngine().isHyvesInThirdPartyAccountList() + "");
mThirdPartyAccountsCache = list;
}
/**
* Return cached list of 3rd party accounts (Identities) associated with
* current login.
*
* @return List of ThirdPartyAccount items retrieved from current login.
*/
public ArrayList<ThirdPartyAccount> getThirdPartyAccounts() {
return mThirdPartyAccountsCache;
}
/***
* Set a value in the preferences file.
*
* @param context Android context.
* @param key Preferences file parameter key.
* @param value Preference value.
*/
private static void setValue(Context context, String key, String value) {
SharedPreferences.Editor editor = context.getSharedPreferences(ApplicationCache.PREFS_FILE,
0).edit();
editor.putString(key, value);
if (!editor.commit()) {
throw new NullPointerException("MainApplication.setValue() Failed to set key[" + key
+ "] with value[" + value + "]");
}
LogUtils.logV("ApplicationCache.setValue() key [" + key + "] value [" + value
+ "] saved to properties file");
}
/***
* Gets the current sync state, or NULL if the state has not been set in
* this JVM instance.
*
* Note: The sync state is an in memory condition. If this is not NULL
* then the UI should be redirected to the SyncingYourAddressBookActivity.
*
* @return SyncStatus or NULL.
*/
public SyncStatus getSyncStatus() {
return mSyncStatus;
}
/***
* Sets the current sync status.
*
* @param syncStatus New sync status.
*/
public void setSyncStatus(SyncStatus syncStatus) {
mSyncStatus = syncStatus;
}
/***
* Get a value from the preferences file.
*
* @param context Android context.
* @param key Preferences file parameter key.
* @param defaultValue Preference value.
* @return
*/
private static String getValue(Context context, String key, String defaultValue) {
return context.getSharedPreferences(ApplicationCache.PREFS_FILE, 0).getString(key,
defaultValue);
}
/***
* Return the resource ID for the SNS Subscribed warning (e.g.
* facebook/hyves/etc posting), or -1 if no warning is necessary.
*
* @param context Android context.
* @return Resource ID for textView or -1 is warning is not required.
* @throws InvalidParameterException when context is NULL.
*/
public static int getSnsSubscribedWarningId(Context context) {
if (context == null) {
throw new InvalidParameterException("ApplicationCache.getSnsSubscribedWarningId() "
+ "context cannot be NULL");
}
boolean facebook = EngineManager.getInstance().getIdentityEngine().isFacebookInThirdPartyAccountList();
boolean hyves =EngineManager.getInstance().getIdentityEngine().isHyvesInThirdPartyAccountList();
if (facebook && hyves) {
return R.string.ContactStatusListActivity_update_status_on_hyves_and_facebook;
} else if (facebook) {
return R.string.ContactStatusListActivity_update_status_on_facebook;
} else if (hyves) {
return R.string.ContactStatusListActivity_update_status_on_hyves;
} else {
return -1;
}
}
public static boolean isBooleanValue(Context context, String key) {
return TRUE.equals(getValue(context, key, FALSE));
}
public static void setBooleanValue(Context context, String key, boolean value) {
setValue(context, key, value ? TRUE : FALSE);
}
/**
* Gets the summary information of the Timeline currently being viewed in the
* UI.
*
* @return Timeline summary information.
*/
public TimelineSummaryItem getCurrentTimelineSummary() {
return mCurrentTimelineSummary;
}
/**
* Sets the summary information of the Timeline Item currently being viewed in the
* UI.
*
* @param timelineSummary Timeline summary information.
*/
public void setCurrentTimelineSummary(TimelineSummaryItem timelineSummary) {
mCurrentTimelineSummary = timelineSummary;
}
/***
* Set the Terms of Service content into the cache.
*
* @param value Terms of Service content.
* @param context Android context.
*/
public static void setTermsOfService(final String value,
final Context context) {
SharedPreferences.Editor editor = context.getSharedPreferences(
ApplicationCache.PREFS_FILE, 0).edit();
editor.putString(TERMS_OF_SERVICE, value);
editor.putLong(TERMS_OF_SERVICE_TIME, System.currentTimeMillis());
if (!editor.commit()) {
throw new NullPointerException(
"MainApplication.setTermsOfService() Failed to set Terms "
+ "of Service with value[" + value + "]");
}
}
/***
* Set the Privacy content into the cache.
*
* @param value Privacy content.
* @param context Android context.
*/
public static void setPrivacyStatemet(final String value,
final Context context) {
SharedPreferences.Editor editor = context.getSharedPreferences(
ApplicationCache.PREFS_FILE, 0).edit();
editor.putString(PRIVACY, value);
editor.putLong(PRIVACY_TIME, System.currentTimeMillis());
if (!editor.commit()) {
throw new NullPointerException(
"MainApplication.setPrivacyStatemet() Failed to set Terms "
+ "of Service with value[" + value + "]");
}
}
/***
* Get the Terms of Service content from the cache. Will return NULL if
* there is no content, or it is over REFRESH_TIME ms old.
*
* @param context Android context.
* @return Terms of Service content
*/
public static String getTermsOfService(final Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
ApplicationCache.PREFS_FILE, 0);
long time = sharedPreferences.getLong(TERMS_OF_SERVICE_TIME, -1);
if (time == -1 || time < System.currentTimeMillis() - REFRESH_TIME || !Auth.getLocalString().equals(mTermsLanguage)) {
return null;
} else {
return sharedPreferences.getString(TERMS_OF_SERVICE, null);
}
}
/***
* Get the Privacy content from the cache. Will return NULL if there is no
* content, or it is over REFRESH_TIME ms old.
*
* @param context Android context.
* @return Privacy content
*/
public static String getPrivacyStatement(final Context context) {
SharedPreferences sharedPreferences = context.getSharedPreferences(
ApplicationCache.PREFS_FILE, 0);
long time = sharedPreferences.getLong(PRIVACY_TIME, -1);
if (time == -1 || time < System.currentTimeMillis() - REFRESH_TIME || !Auth.getLocalString().equals(mPrivacyLanguage) ) {
return null;
} else {
return sharedPreferences.getString(PRIVACY, null);
}
}
private static ServiceStatus sStatus = ServiceStatus.SUCCESS;
public static void setTermsStatus(final ServiceStatus status) {
sStatus = status;
}
public static ServiceStatus getTermsStatus() {
return sStatus;
}
/**
* @param currentContactFilter the mCurrentContactFilter to set
*/
public final void setCurrentContactFilter(final long currentContactFilter) {
mCurrentContactFilter = currentContactFilter;
}
/**
* @return the mCurrentContactFilter
*/
public final long getCurrentContactFilter() {
return mCurrentContactFilter;
}
/** Background thread for caching Thumbnails in memory. **/
private SoftReference<ThumbnailCache> mThumbnailCache;
/***
* Get or create a background thread for caching Thumbnails in memory.
* Note: This object can be used by multiple activities.
*/
public synchronized ThumbnailCache getThumbnailCache() {
ThumbnailCache local = null;
if (mThumbnailCache == null || mThumbnailCache.get() == null) {
local = new ThumbnailCache();
mThumbnailCache =new SoftReference<ThumbnailCache>(local);
}
return mThumbnailCache.get();
}
/***
* TRUE if the Activities engine is currently fetching older time line
* data.
*
* @return TRUE if the Activities engine is currently fetching older time
* line data.
*/
public static boolean isFetchingOlderTimeline() {
return sFetchingOlderTimeline;
}
/***
* Set if the Activities engine is currently fetching older time line
* data.
*
* @param fetchingOlderTimeline Specific current state.
*/
public static void setFetchingOlderTimeline(
final boolean fetchingOlderTimeline) {
sFetchingOlderTimeline = fetchingOlderTimeline;
}
/***
* TRUE if the Activities engine is currently updating status data.
*
* @return TRUE if the Activities engine is currently updating status data.
*/
public static boolean isUpdatingStatuses() {
return sUpdatingStatuses;
}
/***
* Set if the Activities engine is currently updating status data.
*
* @param updatingStatuses Specific current state.
*/
public static void setUpdatingStatuses(final boolean updatingStatuses) {
sUpdatingStatuses = updatingStatuses;
}
/***
* TRUE if the Activities engine is currently fetching older time line
* statuses.
*
* @return TRUE if the Activities engine is currently fetching older time
* line data.
*/
public static boolean isFetchingOlderStatuses() {
return sFetchingOlderStatuses;
}
/***
* Set if the Activities engine is currently fetching older time line
* statuses.
*
* @param fetchingOlderStatuses Specific current state.
*/
public static void setFetchingOlderStatuses(
final boolean fetchingOlderStatuses) {
sFetchingOlderStatuses = fetchingOlderStatuses;
}
/**
* This method is used by menu "Sync Now" to check if the current BG sync
* has finished to place a new BG sync request.
* @return TRUE if the background sync is still on-going
*/
synchronized public static boolean isSyncBusy() {
return sIsContactSyncBusy;
}
/**
* This flag is set by ContactSyncEngine to indicate his state synchronizing the account.
* @param isSyncBusy must be FALSE if state of ContactSync is State.IDLE, TRUE otherwise.
*/
synchronized public static void setSyncBusy(boolean isSyncBusy) {
ApplicationCache.sIsContactSyncBusy = isSyncBusy;
}
/***
* TRUE if the contact sync screen is visible to the user.
*
* @return TRUE if contact sync screen is visible to the user.
*/
public static boolean isContactSyncScreenVisible() {
return sContactSyncScreenVisible;
}
/***
* Set contact sync screen visible.
*
* @param contactSyncScreenVisible contact sync screen state.
*/
public static void setContactSyncScreenVisible(
final boolean contactSyncScreenVisible) {
sContactSyncScreenVisible = contactSyncScreenVisible;
}
}