Android Open Source - force_analytics_example Salesforce S D K Manager






From Project

Back to project page force_analytics_example.

License

The source code is released under:

Copyright (c) 2011, salesforce.com, inc. All rights reserved. ======================================== Redistribution and use of this software in source and binary forms, with or without modificatio...

If you think the Android project force_analytics_example listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (c) 2014, salesforce.com, inc.
 * All rights reserved./*from w w  w . j a va 2  s .c  om*/
 * Redistribution and use of this software in source and binary forms, with or
 * without modification, are permitted provided that the following conditions
 * are met:
 * - Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of salesforce.com, inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission of salesforce.com, inc.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package com.salesforce.androidsdk.app;

import java.net.URI;
import java.util.List;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Build;
import android.os.SystemClock;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;

import com.salesforce.androidsdk.accounts.UserAccount;
import com.salesforce.androidsdk.accounts.UserAccountManager;
import com.salesforce.androidsdk.auth.AccountWatcher;
import com.salesforce.androidsdk.auth.AccountWatcher.AccountRemoved;
import com.salesforce.androidsdk.auth.AuthenticatorService;
import com.salesforce.androidsdk.auth.HttpAccess;
import com.salesforce.androidsdk.auth.LoginServerManager;
import com.salesforce.androidsdk.auth.OAuth2;
import com.salesforce.androidsdk.push.PushMessaging;
import com.salesforce.androidsdk.push.PushNotificationInterface;
import com.salesforce.androidsdk.rest.AdminPrefsManager;
import com.salesforce.androidsdk.rest.BootConfig;
import com.salesforce.androidsdk.rest.ClientManager;
import com.salesforce.androidsdk.rest.ClientManager.LoginOptions;
import com.salesforce.androidsdk.security.Encryptor;
import com.salesforce.androidsdk.security.PRNGFixes;
import com.salesforce.androidsdk.security.PasscodeManager;
import com.salesforce.androidsdk.ui.AccountSwitcherActivity;
import com.salesforce.androidsdk.ui.LoginActivity;
import com.salesforce.androidsdk.ui.PasscodeActivity;
import com.salesforce.androidsdk.ui.SalesforceR;
import com.salesforce.androidsdk.ui.sfhybrid.SalesforceDroidGapActivity;
import com.salesforce.androidsdk.util.EventsObservable;
import com.salesforce.androidsdk.util.EventsObservable.EventType;

/**
 * Singleton class used as an interface to the various
 * functions provided by the Salesforce SDK. This class
 * should be instantiated in order to use the Salesforce SDK.
 */
public class SalesforceSDKManager implements AccountRemoved {

    /**
     * Current version of this SDK.
     */
    public static final String SDK_VERSION = "2.2.1";

    /**
     * Last phone version.
     */
    private static final int GINGERBREAD_MR1 = 10;

    /**
     * Default app name.
     */
    private static final String DEFAULT_APP_DISPLAY_NAME = "Salesforce";

    /**
     * Instance of the SalesforceSDKManager to use for this process.
     */
    protected static SalesforceSDKManager INSTANCE;

    /**
     * Timeout value for push un-registration.
     */
    private static final int PUSH_UNREGISTER_TIMEOUT_MILLIS = 30000;

    protected Context context;
    protected KeyInterface keyImpl;
    protected LoginOptions loginOptions;
    protected Class<? extends Activity> mainActivityClass;
    protected Class<? extends Activity> loginActivityClass = LoginActivity.class;
    protected Class<? extends PasscodeActivity> passcodeActivityClass = PasscodeActivity.class;
    protected Class<? extends AccountSwitcherActivity> switcherActivityClass = AccountSwitcherActivity.class;
    protected AccountWatcher accWatcher;
    private String encryptionKey;
    private SalesforceR salesforceR = new SalesforceR();
    private PasscodeManager passcodeManager;
    private LoginServerManager loginServerManager;
    private boolean isTestRun = false;
    private boolean isLoggingOut = false;
    private AdminPrefsManager adminPrefsManager;
    private PushNotificationInterface pushNotificationInterface;
    private volatile boolean loggedOut = false;

    /**
     * Returns a singleton instance of this class.
     *
     * @param context Application context.
     * @return Singleton instance of SalesforceSDKManager.
     */
    public static SalesforceSDKManager getInstance() {
      if (INSTANCE != null) {
        return INSTANCE;
      } else {
            throw new RuntimeException("Applications need to call SalesforceSDKManager.init() first.");
      }
    }

    /**
     * Protected constructor.
     *
     * @param context Application context.
     * @param keyImpl Implementation for KeyInterface.
     * @param mainActivity Activity that should be launched after the login flow.
     * @param loginActivity Login activity.
     */
    protected SalesforceSDKManager(Context context, KeyInterface keyImpl, 
        Class<? extends Activity> mainActivity, Class<? extends Activity> loginActivity) {
      this.context = context;
      this.keyImpl = keyImpl;
      this.mainActivityClass = mainActivity;
      if (loginActivity != null) {
            this.loginActivityClass = loginActivity;  
      }
    }

    /**
     * Returns the class for the main activity.
     *
     * @return The class for the main activity.
     */
    public Class<? extends Activity> getMainActivityClass() {
      return mainActivityClass;
    }

    /**
     * Returns the class for the account switcher activity.
     *
     * @return The class for the account switcher activity.
     */
    public Class<? extends AccountSwitcherActivity> getAccountSwitcherActivityClass() {
      return switcherActivityClass;
    }

    /**
     * Returns the class for the account switcher activity.
     *
     * @return The class for the account switcher activity.
     */
    public void setAccountSwitcherActivityClass(Class<? extends AccountSwitcherActivity> activity) {
      if (activity != null) {
          switcherActivityClass = activity;
      }
    }

    public interface KeyInterface {

        /**
         * This function must return the same value for name
         * even when the application is restarted. The value this
         * function returns must be Base64 encoded.
         *
         * {@link Encryptor#isBase64Encoded(String)} can be used to
         * determine whether the generated key is Base64 encoded.
         *
         * {@link Encryptor#hash(String, String)} can be used to
         * generate a Base64 encoded string.
         *
         * For example:
         * <code>
         * Encryptor.hash(name + "12s9adfgret=6235inkasd=012", name + "12kl0dsakj4-cuygsdf625wkjasdol8");
         * </code>
         *
         * @param name The name associated with the key.
         * @return The key used for encrypting salts and keys.
         */
        public String getKey(String name);
    }

    /**
     * This function must return the same value for name
     * even when the application is restarted. The value this
     * function returns must be Base64 encoded.
     *
     * {@link Encryptor#isBase64Encoded(String)} can be used to
     * determine whether the generated key is Base64 encoded.
     *
     * {@link Encryptor#hash(String, String)} can be used to
     * generate a Base64 encoded string.
     *
     * For example:
     * <code>
     * Encryptor.hash(name + "12s9adfgret=6235inkasd=012", name + "12kl0dsakj4-cuygsdf625wkjasdol8");
     * </code>
     *
     * @param name The name associated with the key.
     * @return The key used for encrypting salts and keys.
     */
    public String getKey(String name) {
      String key = null;
      if (keyImpl != null) {
        key = keyImpl.getKey(name);
      }
      return key;
    }

    /**
     * Before 1.3, SalesforceSDK was packaged as a jar, and project had to provide a subclass of SalesforceR.
     * Since 1.3, SalesforceSDK is packaged as a library project and we no longer need to to that.
     * @return SalesforceR object which allows reference to resources living outside the SDK.
     */
    public SalesforceR getSalesforceR() {
        return salesforceR;
    }

    /**
     * Returns the class of the activity used to perform the login process and create the account.
     *
     * @return the class of the activity used to perform the login process and create the account.
     */
    public Class<? extends Activity> getLoginActivityClass() {
      return loginActivityClass;
    }

  /**
     * Returns login options associated with the app.
     *
   * @return LoginOptions instance.
   */
  public LoginOptions getLoginOptions() {
    if (loginOptions == null) {
      final BootConfig config = BootConfig.getBootConfig(context);
      loginOptions = new LoginOptions(null, getPasscodeHash(), config.getOauthRedirectURI(),
              config.getRemoteAccessConsumerKey(), config.getOauthScopes());
    }
    return loginOptions;
  }

  /**
   * Initializes components required for this class
   * to properly function. This method is for internal
   * usage by the Salesforce Mobile SDK.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
     * @param mainActivity Activity that should be launched after the login flow.
     * @param loginActivity Login activity.
   */
    private static void init(Context context, KeyInterface keyImpl,
        Class<? extends Activity> mainActivity, Class<? extends Activity> loginActivity) {
      if (INSTANCE == null) {
        INSTANCE = new SalesforceSDKManager(context, keyImpl, mainActivity, loginActivity);
      }
      initInternal(context);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method is for internal
   * usage by the Salesforce Mobile SDK or by subclasses
   * of SalesforceSDKManager.
   *
   * @param context Application context.
   */
    public static void initInternal(Context context) {

      // Applies PRNG fixes for certain older versions of Android.
        PRNGFixes.apply();

        // Initializes the encryption module.
        Encryptor.init(context);

        // Initializes the HTTP client.
        HttpAccess.init(context, INSTANCE.getUserAgent());

        // Ensures that we have a CookieSyncManager instance.
        CookieSyncManager.createInstance(context);

        /*
         * Initializes an AccountWatcher instance, only if the current instance
         * is NOT running in the auth process. This prevents multiple
         * callbacks when an account is removed from settings.
         */
        if (!INSTANCE.isRunningInAuthProcess()) {
            INSTANCE.accWatcher = new AccountWatcher(context, INSTANCE);
        }

        // Upgrades to the latest version.
        UpgradeManager.getInstance().upgradeAccMgr();
        EventsObservable.get().notifyEvent(EventType.AppCreateComplete);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method should be called
   * by hybrid apps using the Salesforce Mobile SDK.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
   */
    public static void initHybrid(Context context, KeyInterface keyImpl) {
      SalesforceSDKManager.init(context, keyImpl, SalesforceDroidGapActivity.class, LoginActivity.class);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method should be called
   * by hybrid apps using the Salesforce Mobile SDK.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
     * @param loginActivity Login activity.
   */
    public static void initHybrid(Context context, KeyInterface keyImpl, Class<? extends Activity> loginActivity) {
      SalesforceSDKManager.init(context, keyImpl, SalesforceDroidGapActivity.class, loginActivity);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method should be called
   * by hybrid apps that use a subclass of SalesforceDroidGapActivity.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
     * @param mainActivity Main activity.
     * @param loginActivity Login activity.
   */
    public static void initHybrid(Context context, KeyInterface keyImpl,
        Class<? extends SalesforceDroidGapActivity> mainActivity, Class<? extends Activity> loginActivity) {
      SalesforceSDKManager.init(context, keyImpl, mainActivity, loginActivity);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method should be called
   * by native apps using the Salesforce Mobile SDK.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
     * @param mainActivity Activity that should be launched after the login flow.
   */
    public static void initNative(Context context, KeyInterface keyImpl, Class<? extends Activity> mainActivity) {
      SalesforceSDKManager.init(context, keyImpl, mainActivity, LoginActivity.class);
    }

  /**
   * Initializes components required for this class
   * to properly function. This method should be called
   * by native apps using the Salesforce Mobile SDK.
   *
   * @param context Application context.
     * @param keyImpl Implementation of KeyInterface.
     * @param mainActivity Activity that should be launched after the login flow.
     * @param loginActivity Login activity.
   */
    public static void initNative(Context context, KeyInterface keyImpl,
        Class<? extends Activity> mainActivity, Class<? extends Activity> loginActivity) {
      SalesforceSDKManager.init(context, keyImpl, mainActivity, loginActivity);
    }

    /**
     * Sets a custom sub-class of PasscodeActivity to be used.
     *
     * @param activity Sub-class of PasscodeActivity.
     */
    public void setPasscodeActivity(Class<? extends PasscodeActivity> activity) {
      if (activity != null) {
        passcodeActivityClass = activity;
      }
    }

    /**
     * Returns the custom sub-class of PasscodeActivity being used.
     *
     * @return Sub-class of PasscodeActivity.
     */
    public Class<? extends PasscodeActivity> getPasscodeActivity() {
      return passcodeActivityClass;
    }

    /**
     * Returns whether the SDK should automatically logout when the
     * access token is revoked. This should be overridden to return
     * false, if the app wants to handle cleanup by itself when the
     * access token is revoked.
     *
     * @return True - if the SDK should automatically logout, False - otherwise.
     */
    public boolean shouldLogoutWhenTokenRevoked() {
      return true;
    }

    /**
     * Returns the application context.
     *
     * @return Application context.
     */
    public Context getAppContext() {
      return context;
    }

    @Override
    public void onAccountRemoved() {
      INSTANCE.cleanUp(null, null);
    }

    /**
     * Returns the login server manager associated with SalesforceSDKManager.
     *
     * @return LoginServerManager instance.
     */
    public synchronized LoginServerManager getLoginServerManager() {
        if (loginServerManager == null) {
          loginServerManager = new LoginServerManager(context);
        }
        return loginServerManager;
    }    

    /**
     * Sets a receiver that handles received push notifications.
     *
     * @param pnInterface Implementation of PushNotificationInterface.
     */
    public synchronized void setPushNotificationReceiver(PushNotificationInterface pnInterface) {
      pushNotificationInterface = pnInterface;
    }

    /**
     * Returns the configured receiver that handles received push notifications.
     *
     * @return Configured implementation of PushNotificationInterface.
     */
    public synchronized PushNotificationInterface getPushNotificationReceiver() {
      return pushNotificationInterface;
    }

    /**
     * Returns the passcode manager associated with SalesforceSDKManager.
     *
     * @return PasscodeManager instance.
     */
    public synchronized PasscodeManager getPasscodeManager() {
      if (passcodeManager == null) {
        passcodeManager = new PasscodeManager(context);
        }
        return passcodeManager;
    }

    /**
     * Returns an instance of the UserAccountManager class.
     *
     * @return Instance of the UserAccountManager class.
     */
    public UserAccountManager getUserAccountManager() {
      return UserAccountManager.getInstance();
    }

    /**
     * Returns the admin prefs manager associated with SalesforceSDKManager.
     *
     * @return AdminPrefsManager instance.
     */
    public synchronized AdminPrefsManager getAdminPrefsManager() {
      if (adminPrefsManager == null) {
        adminPrefsManager = new AdminPrefsManager();
      }
      return adminPrefsManager;
    }

    /**
     * Changes the passcode to a new value.
     *
     * @param oldPass Old passcode.
     * @param newPass New passcode.
     */
    public synchronized void changePasscode(String oldPass, String newPass) {
        if (!isNewPasscode(oldPass, newPass)) {
            return;
        }

        // Resets the cached encryption key, since the passcode has changed.
        encryptionKey = null;
        ClientManager.changePasscode(oldPass, newPass);
    }

    /**
     * Checks if the new passcode is different from the old passcode.
     *
     * @param oldPass Old passcode.
     * @param newPass New passcode.
     * @return True - if the new passcode is different from the old passcode, False - otherwise.
     */
    protected boolean isNewPasscode(String oldPass, String newPass) {
        return !((oldPass == null && newPass == null)
                || (oldPass != null && newPass != null && oldPass.trim().equals(newPass.trim())));
    }

    /**
     * Returns the encryption key being used.
     *
     * @param actualPass Passcode.
     * @return Encryption key for passcode.
     */
    public synchronized String getEncryptionKeyForPasscode(String actualPass) {
        if (actualPass != null && !actualPass.trim().equals("")) {
            return actualPass;
        }
        if (encryptionKey == null) {
            encryptionKey = getPasscodeManager().hashForEncryption("");
        }
        return encryptionKey;
    }

    /**
     * Returns the app display name used by the passcode dialog.
     *
     * @return App display string.
     */
    public String getAppDisplayString() {
      return DEFAULT_APP_DISPLAY_NAME;
    }

    /**
     * Returns the passcode hash being used.
     *
     * @return The hashed passcode, or null if it's not required.
     */
    public String getPasscodeHash() {
        return getPasscodeManager().getPasscodeHash();
    }

    /**
     * Returns the name of the application (as defined in AndroidManifest.xml).
     *
     * @return The name of the application.
     */
    public String getApplicationName() {
        return context.getPackageManager().getApplicationLabel(context.getApplicationInfo()).toString();
    }

    /**
     * Checks if network connectivity exists.
     *
     * @return True - if network is available, False - otherwise.
     */
    public boolean hasNetwork() {
      return HttpAccess.DEFAULT.hasNetwork();
    }

    /**
     * Cleans up cached credentials and data.
     *
     * @param frontActivity Front activity.
     * @param account Account.
     */
    protected void cleanUp(Activity frontActivity, Account account) {
        final List<UserAccount> users = getUserAccountManager().getAuthenticatedUsers();

        // Finishes front activity if specified, and if this is the last account.
        if (frontActivity != null && (users == null || users.size() <= 1)) {
            frontActivity.finish();
        }

        /*
         * Checks how many accounts are left that are authenticated. If only one
         * account is left, this is the account that is being removed. In this
         * case, we can safely reset passcode manager, admin prefs, and encryption keys.
         * Otherwise, we don't reset passcode manager and admin prefs since
         * there might be other accounts on that same org, and these policies
         * are stored at the org level.
         */
        if (users == null || users.size() <= 1) {
            getAdminPrefsManager().resetAll();
            adminPrefsManager = null;
            getPasscodeManager().reset(context);
            passcodeManager = null;
            encryptionKey = null;
            UUIDManager.resetUuids();
        }
    }

    /**
     * Starts login flow if user account has been removed.
     */
    protected void startLoginPage() {

        // Clears cookies.
        CookieSyncManager.createInstance(context);
        CookieManager.getInstance().removeAllCookie();

        // Restarts the application.
        final Intent i = new Intent(context, getMainActivityClass());
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }

    /**
     * Starts account switcher activity if an account has been removed.
     */
    protected void startSwitcherActivityIfRequired() {

        // Clears cookies.
        CookieSyncManager.createInstance(context);
        CookieManager.getInstance().removeAllCookie();

        /*
         * If the number of accounts remaining is 0, shows the login page.
         * If the number of accounts remaining is 1, switches to that user
         * automatically. If there is more than 1 account logged in, shows
         * the account switcher screen, so that the user can pick which
         * account to switch to.
         */
        final UserAccountManager userAccMgr = getUserAccountManager();
        final List<UserAccount> accounts = userAccMgr.getAuthenticatedUsers();
        if (accounts == null || accounts.size() == 0) {
          startLoginPage();
        } else if (accounts.size() == 1) {
          userAccMgr.switchToUser(accounts.get(0));
        } else {
          final Intent i = new Intent(context, switcherActivityClass);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
        }
    }

    /**
     * Unregisters from push notifications (both GCM and SFDC), and waits for
     * it to complete or timeout.
     *
     * @param clientMgr ClientManager instance.
     * @param showLoginPage True - if the login page should be shown, False - otherwise.
     * @param refreshToken Refresh token.
     * @param clientId Client ID.
     * @param loginServer Login server.
     * @param account Account instance.
     * @param frontActivity Front activity.
     */
    private void unregisterPush(final ClientManager clientMgr, final boolean showLoginPage,
        final String refreshToken, final String clientId,
        final String loginServer, final Account account, final Activity frontActivity) {
        final IntentFilter intentFilter = new IntentFilter(PushMessaging.UNREGISTERED_ATTEMPT_COMPLETE_EVENT);
        final BroadcastReceiver pushUnregisterReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(PushMessaging.UNREGISTERED_ATTEMPT_COMPLETE_EVENT)) {
                    postPushUnregister(this, clientMgr, showLoginPage,
                        refreshToken, clientId, loginServer, account, frontActivity);
                }
            }
        };
        getAppContext().registerReceiver(pushUnregisterReceiver, intentFilter);

        // Unregisters from notifications on logout.
    final UserAccount userAcc = getUserAccountManager().buildUserAccount(account);
        PushMessaging.unregister(context, userAcc);

        /*
         * Starts a background thread to wait up to the timeout period. If
         * another thread has already performed logout, we exit immediately.
         */
        (new Thread() {
            public void run() {
                long startTime = System.currentTimeMillis();
                while ((System.currentTimeMillis() - startTime) < PUSH_UNREGISTER_TIMEOUT_MILLIS && !loggedOut) {

                    // Waits for half a second at a time.
                    SystemClock.sleep(500);
                }
                postPushUnregister(pushUnregisterReceiver, clientMgr, showLoginPage,
                    refreshToken, clientId, loginServer, account, frontActivity);
            };
        }).start();
    }

    /**
     * This method is called either when push un-registration is complete, or
     * a timeout occurred while waiting.
     *
     * @param pushReceiver Broadcast receiver.
     * @param clientMgr ClientManager instance.
     * @param showLoginPage True - if the login page should be shown, False - otherwise.
     * @param refreshToken Refresh token.
     * @param clientId Client ID.
     * @param loginServer Login server.
     * @param account Account instance.
     * @param frontActivity Front activity.
     */
    private synchronized void postPushUnregister(BroadcastReceiver pushReceiver,
        final ClientManager clientMgr, final boolean showLoginPage,
        final String refreshToken, final String clientId,
        final String loginServer, final Account account, Activity frontActivity) {
        if (!loggedOut) {
            try {
                context.unregisterReceiver(pushReceiver);
            } catch (Exception e) {
              Log.e("SalesforceSDKManager:postPushUnregister", "Exception occurred while un-registering.", e);
            }
        removeAccount(clientMgr, showLoginPage, refreshToken, clientId, loginServer, account, frontActivity);
        }
    }

    /**
     * Wipes out the stored authentication credentials (removes the account)
     * and restarts the app, if specified.
     *
     * @param frontActivity Front activity.
     */
    public void logout(Activity frontActivity) {
        logout(frontActivity, true);
    }

    /**
     * Wipes out the stored authentication credentials (removes the account)
     * and restarts the app, if specified.
     *
     * @param account Account.
     * @param frontActivity Front activity.
     */
    public void logout(Account account, Activity frontActivity) {
        logout(account, frontActivity, true);
    }

    /**
     * Wipes out the stored authentication credentials (removes the account)
     * and restarts the app, if specified.
     *
     * @param frontActivity Front activity.
     * @param showLoginPage True - if the login page should be shown, False - otherwise.
     */
    public void logout(Activity frontActivity, final boolean showLoginPage) {
        final ClientManager clientMgr = new ClientManager(context, getAccountType(),
            null, shouldLogoutWhenTokenRevoked());
    final Account account = clientMgr.getAccount();
    logout(account, frontActivity, showLoginPage);
    }

    /**
     * Wipes out the stored authentication credentials (removes the account)
     * and restarts the app, if specified.
     *
     * @param account Account.
     * @param frontActivity Front activity.
     * @param showLoginPage True - if the login page should be shown, False - otherwise.
     */
    public void logout(Account account, Activity frontActivity, final boolean showLoginPage) {
        final ClientManager clientMgr = new ClientManager(context, getAccountType(),
            null, shouldLogoutWhenTokenRevoked());
        isLoggingOut = true;
    final AccountManager mgr = AccountManager.get(context);
    String refreshToken = null;
    String clientId = null;
    String loginServer = null;
    if (account != null) {
      refreshToken = SalesforceSDKManager.decryptWithPasscode(mgr.getPassword(account),
              getPasscodeHash());
          clientId = SalesforceSDKManager.decryptWithPasscode(mgr.getUserData(account,
              AuthenticatorService.KEY_CLIENT_ID), getPasscodeHash());
          loginServer = SalesforceSDKManager.decryptWithPasscode(mgr.getUserData(account,
              AuthenticatorService.KEY_INSTANCE_URL), getPasscodeHash());  
    }

    /*
     * Makes a call to un-register from push notifications, only
     * if the refresh token is available.
     */
    final UserAccount userAcc = getUserAccountManager().buildUserAccount(account);
      if (PushMessaging.isRegistered(context, userAcc) && refreshToken != null) {
        loggedOut = false;
        unregisterPush(clientMgr, showLoginPage, refreshToken, clientId,
            loginServer, account, frontActivity);
      } else {
        removeAccount(clientMgr, showLoginPage, refreshToken, clientId,
            loginServer, account, frontActivity);
      }
    }

    /**
     * Removes the account upon logout.
     *
     * @param clientMgr ClientManager instance.
     * @param showLoginPage True - if the login page should be shown, False - otherwise.
     * @param refreshToken Refresh token.
     * @param clientId Client ID.
     * @param loginServer Login server.
     * @param account Account instance.
     * @param frontActivity Front activity.
     */
    private void removeAccount(ClientManager clientMgr, final boolean showLoginPage,
        String refreshToken, String clientId, String loginServer,
        Account account, Activity frontActivity) {
      loggedOut = true;
        if (accWatcher != null) {
        accWatcher.remove();
        accWatcher = null;
      }
      cleanUp(frontActivity, account);

      // Removes the existing account, if any.
      if (account == null) {
        EventsObservable.get().notifyEvent(EventType.LogoutComplete);
        if (showLoginPage) {
          startSwitcherActivityIfRequired();
        }
      } else {
        clientMgr.removeAccountAsync(account, new AccountManagerCallback<Boolean>() {

          @Override
          public void run(AccountManagerFuture<Boolean> arg0) {
            EventsObservable.get().notifyEvent(EventType.LogoutComplete);
            if (showLoginPage) {
              startSwitcherActivityIfRequired();
            }
          }
        });
      }
      isLoggingOut = false;

      // Revokes the existing refresh token.
        if (shouldLogoutWhenTokenRevoked() && account != null && refreshToken != null) {
          new RevokeTokenTask(refreshToken, clientId, loginServer).execute();
        }
    }

    /**
     * Returns a user agent string based on the mobile SDK version. We are building
     * a user agent of the form:
     *   SalesforceMobileSDK/<salesforceSDK version> android/<android OS version> appName/appVersion <Native|Hybrid>
     *
     * @return The user agent string to use for all requests.
     */
    public final String getUserAgent() {
        String appName = "";
        String appVersion = "";
        try {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            appName = context.getString(packageInfo.applicationInfo.labelRes);
            appVersion = packageInfo.versionName;
        } catch (NameNotFoundException e) {
            Log.w("SalesforceSDKManager:getUserAgent", e);
        } catch (Resources.NotFoundException nfe) {
            // if your application doesn't have a name (like a test harness from Gradle)
            Log.w("SalesforceSDKManager:getUserAgent", nfe);
        }
      String nativeOrHybrid = (isHybrid() ? "Hybrid" : "Native");
      return String.format("SalesforceMobileSDK/%s android mobile/%s (%s) %s/%s %s",
              SDK_VERSION, Build.VERSION.RELEASE, Build.MODEL, appName, appVersion, nativeOrHybrid);
  }

  /**
   * Returns whether the application is a hybrid application or not.
   *
   * @return True - if this is an hybrid application, False - otherwise.
   */
  public boolean isHybrid() {
    return SalesforceDroidGapActivity.class.isAssignableFrom(getMainActivityClass());
  }

    /**
     * Returns the authentication account type (should match authenticator.xml).
     *
     * @return Account type string.
     */
    public String getAccountType() {
        return context.getString(getSalesforceR().stringAccountType());
    }

    /**
     * Returns whether the app is running on a tablet or not.
     *
     * @return True - if application is running on a tablet, False - otherwise.
     */
    public static boolean isTablet() {
        if (Build.VERSION.SDK_INT <= GINGERBREAD_MR1) {
            return false;
        } else if ((INSTANCE.context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
            return true;
        }
        return false;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append(this.getClass()).append(": {\n")
          .append("   accountType: ").append(getAccountType()).append("\n")
          .append("   userAgent: ").append(getUserAgent()).append("\n")
          .append("   mainActivityClass: ").append(getMainActivityClass()).append("\n")
          .append("   isFileSystemEncrypted: ").append(Encryptor.isFileSystemEncrypted()).append("\n");
        if (passcodeManager != null) {

            // passcodeManager may be null at startup if the app is running in debug mode.
            sb.append("   hasStoredPasscode: ").append(passcodeManager.hasStoredPasscode(context)).append("\n");
        }
        sb.append("}\n");
        return sb.toString();
    }

    /**
     * Encrypts the data using the passcode as the encryption key.
     *
     * @param data Data to be encrypted.
     * @param passcode Encryption key.
     * @return Encrypted data.
     */
    public static String encryptWithPasscode(String data, String passcode) {
        return Encryptor.encrypt(data, SalesforceSDKManager.INSTANCE.getEncryptionKeyForPasscode(passcode));
    }

    /**
     * Decrypts the data using the passcode as the decryption key.
     *
     * @param data Data to be decrypted.
     * @param passcode Decryption key.
     * @return Decrypted data.
     */
    public static String decryptWithPasscode(String data, String passcode) {
        return Encryptor.decrypt(data, SalesforceSDKManager.INSTANCE.getEncryptionKeyForPasscode(passcode));
    }

    /**
     * Simple AsyncTask to handle revocation of refresh token upon logout.
     *
     * @author bhariharan
     */
    private class RevokeTokenTask extends AsyncTask<Void, Void, Void> {

      private String refreshToken;
      private String clientId;
      private String loginServer;

      public RevokeTokenTask(String refreshToken, String clientId, String loginServer) {
        this.refreshToken = refreshToken;
        this.clientId = clientId;
        this.loginServer = loginServer;
      }

    @Override
    protected Void doInBackground(Void... nothings) {
          try {
            OAuth2.revokeRefreshToken(HttpAccess.DEFAULT, new URI(loginServer), clientId, refreshToken);
          } catch (Exception e) {
            Log.w("SalesforceSDKManager:revokeToken", e);
          }
          return null;
    }
    }

    /**
     * Returns whether the current run is a test run.
     *
     * @return True - if it is a test run, False - otherwise.
     */
    public boolean getIsTestRun() {
      return INSTANCE.isTestRun;
    }

    /**
     * Specifies if the current run is a test run.
     *
     * @param isTestRun True - if it is a test run, False - otherwise.
     */
    public void setIsTestRun(boolean isTestRun) {
      INSTANCE.isTestRun = isTestRun;
      if (accWatcher != null) {
        accWatcher.remove();
      }
      accWatcher = null;
    }

    /**
     * Returns whether a logout is in progress or not.
     *
     * @return True - if a logout is in progress, False - otherwise.
     */
    public boolean isLoggingOut() {
      return isLoggingOut;
    }

    /**
     * Returns whether this instance is running in the auth process or not.
     *
     * @return True - if auth process, False - otherwise.
     */
    private boolean isRunningInAuthProcess() {
      try {
          String procName = "";
            int pid = android.os.Process.myPid();
            final ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            final List<RunningAppProcessInfo> processInfos = manager.getRunningAppProcesses();
            if (processInfos != null) {
                for (final RunningAppProcessInfo procInfo : processInfos) {
                    if (procInfo != null && procInfo.pid == pid) {
                      procName = procInfo.processName;
                      break;
                    }
                }
            }
            if (procName.endsWith(":auth")) {
              return true;
            }
      } catch (Exception e) {
        Log.e("SalesforceSDKManager:isRunningInAuthProcess",
            "Exception occurred while getting process name.", e);
      }
      return false;
    }
}




Java Source Code List

com.salesforce.androidsdk.accounts.UserAccountManagerWithSmartStore.java
com.salesforce.androidsdk.accounts.UserAccountManager.java
com.salesforce.androidsdk.accounts.UserAccount.java
com.salesforce.androidsdk.app.SalesforceSDKManager.java
com.salesforce.androidsdk.app.UUIDManager.java
com.salesforce.androidsdk.app.UpgradeManager.java
com.salesforce.androidsdk.auth.AccountWatcher.java
com.salesforce.androidsdk.auth.AuthenticatorService.java
com.salesforce.androidsdk.auth.HttpAccess.java
com.salesforce.androidsdk.auth.LoginServerManager.java
com.salesforce.androidsdk.auth.OAuth2.java
com.salesforce.androidsdk.phonegap.ForcePlugin.java
com.salesforce.androidsdk.phonegap.JavaScriptPluginVersion.java
com.salesforce.androidsdk.phonegap.SDKInfoPlugin.java
com.salesforce.androidsdk.phonegap.SFAccountManagerPlugin.java
com.salesforce.androidsdk.phonegap.SalesforceOAuthPlugin.java
com.salesforce.androidsdk.phonegap.TestRunnerPlugin.java
com.salesforce.androidsdk.push.PushBroadcastReceiver.java
com.salesforce.androidsdk.push.PushMessaging.java
com.salesforce.androidsdk.push.PushNotificationInterface.java
com.salesforce.androidsdk.push.PushService.java
com.salesforce.androidsdk.rest.AdminPrefsManager.java
com.salesforce.androidsdk.rest.ApiVersionStrings.java
com.salesforce.androidsdk.rest.BootConfig.java
com.salesforce.androidsdk.rest.ClientManager.java
com.salesforce.androidsdk.rest.RestClient.java
com.salesforce.androidsdk.rest.RestRequest.java
com.salesforce.androidsdk.rest.RestResponse.java
com.salesforce.androidsdk.rest.files.ApiRequests.java
com.salesforce.androidsdk.rest.files.ConnectUriBuilder.java
com.salesforce.androidsdk.rest.files.FileRequests.java
com.salesforce.androidsdk.rest.files.RenditionType.java
com.salesforce.androidsdk.security.Encryptor.java
com.salesforce.androidsdk.security.PRNGFixes.java
com.salesforce.androidsdk.security.PasscodeManager.java
com.salesforce.androidsdk.smartstore.app.SalesforceSDKManagerWithSmartStore.java
com.salesforce.androidsdk.smartstore.app.UpgradeManagerWithSmartStore.java
com.salesforce.androidsdk.smartstore.phonegap.SmartStorePlugin.java
com.salesforce.androidsdk.smartstore.phonegap.StoreCursor.java
com.salesforce.androidsdk.smartstore.store.DBHelper.java
com.salesforce.androidsdk.smartstore.store.DBOpenHelper.java
com.salesforce.androidsdk.smartstore.store.IndexSpec.java
com.salesforce.androidsdk.smartstore.store.QuerySpec.java
com.salesforce.androidsdk.smartstore.store.SmartSqlHelper.java
com.salesforce.androidsdk.smartstore.store.SmartStore.java
com.salesforce.androidsdk.ui.AccountSwitcherActivity.java
com.salesforce.androidsdk.ui.CustomServerUrlEditor.java
com.salesforce.androidsdk.ui.LoginActivity.java
com.salesforce.androidsdk.ui.ManageSpaceActivity.java
com.salesforce.androidsdk.ui.OAuthWebviewHelper.java
com.salesforce.androidsdk.ui.PasscodeActivity.java
com.salesforce.androidsdk.ui.SalesforceAccountRadioButton.java
com.salesforce.androidsdk.ui.SalesforceR.java
com.salesforce.androidsdk.ui.SalesforceServerRadioButton.java
com.salesforce.androidsdk.ui.ServerPickerActivity.java
com.salesforce.androidsdk.ui.sfhybrid.SalesforceDroidGapActivity.java
com.salesforce.androidsdk.ui.sfhybrid.SalesforceGapViewClient.java
com.salesforce.androidsdk.ui.sfnative.SalesforceActivity.java
com.salesforce.androidsdk.ui.sfnative.SalesforceExpandableListActivity.java
com.salesforce.androidsdk.ui.sfnative.SalesforceListActivity.java
com.salesforce.androidsdk.util.EventsListenerQueue.java
com.salesforce.androidsdk.util.EventsObservable.java
com.salesforce.androidsdk.util.EventsObserver.java
com.salesforce.androidsdk.util.ForceAppInstrumentationTestCase.java
com.salesforce.androidsdk.util.HybridInstrumentationTestCase.java
com.salesforce.androidsdk.util.JSTestCase.java
com.salesforce.androidsdk.util.JUnitReportTestRunner.java
com.salesforce.androidsdk.util.LogUtil.java
com.salesforce.androidsdk.util.NativeInstrumentationTestCase.java
com.salesforce.androidsdk.util.TimeLimitedTestRunner.java
com.salesforce.androidsdk.util.TokenRevocationReceiver.java
com.salesforce.androidsdk.util.UriFragmentParser.java
com.salesforce.androidsdk.util.UserSwitchReceiver.java
com.salesforce.samples.accounteditor.AccountEditorApp.java
com.salesforce.samples.accounteditor.KeyImpl.java
com.salesforce.samples.analyticsapp.AnalyticsApp.java
com.salesforce.samples.analyticsapp.GraphActivity.java
com.salesforce.samples.analyticsapp.KeyImpl.java
com.salesforce.samples.analyticsapp.MainActivity.java
com.salesforce.samples.analyticsapp.PieChart.java
com.salesforce.samples.contactexplorer.ContactExplorerApp.java
com.salesforce.samples.contactexplorer.KeyImpl.java
com.salesforce.samples.hybridfileexplorer.HybridFileExplorerApp.java
com.salesforce.samples.hybridfileexplorer.KeyImpl.java
com.salesforce.samples.smartstoreexplorer.KeyImpl.java
com.salesforce.samples.smartstoreexplorer.SmartStoreExplorerApp.java
com.salesforce.samples.vfconnector.KeyImpl.java
com.salesforce.samples.vfconnector.VFConnectorApp.java