Android Open Source - force_analytics_example Salesforce Droid Gap Activity






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) 2011-12, salesforce.com, inc.
 * All rights reserved./* w  w  w  .j  a v a 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.ui.sfhybrid;

import java.net.URI;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.cordova.CordovaChromeClient;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewClient;
import org.apache.cordova.DroidGap;
import org.apache.cordova.api.CallbackContext;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;

import android.annotation.TargetApi;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.salesforce.androidsdk.accounts.UserAccountManager;
import com.salesforce.androidsdk.app.SalesforceSDKManager;
import com.salesforce.androidsdk.auth.HttpAccess.NoNetworkException;
import com.salesforce.androidsdk.rest.ApiVersionStrings;
import com.salesforce.androidsdk.rest.BootConfig;
import com.salesforce.androidsdk.rest.ClientManager;
import com.salesforce.androidsdk.rest.ClientManager.AccountInfoNotFoundException;
import com.salesforce.androidsdk.rest.ClientManager.RestClientCallback;
import com.salesforce.androidsdk.rest.RestClient;
import com.salesforce.androidsdk.rest.RestClient.AsyncRequestCallback;
import com.salesforce.androidsdk.rest.RestClient.ClientInfo;
import com.salesforce.androidsdk.rest.RestRequest;
import com.salesforce.androidsdk.rest.RestResponse;
import com.salesforce.androidsdk.security.PasscodeManager;
import com.salesforce.androidsdk.util.EventsObservable;
import com.salesforce.androidsdk.util.EventsObservable.EventType;
import com.salesforce.androidsdk.util.TokenRevocationReceiver;
import com.salesforce.androidsdk.util.UserSwitchReceiver;

/**
 * Class that defines the main activity for a PhoneGap-based application.
 */
public class SalesforceDroidGapActivity extends DroidGap {

    // Keys in credentials map
    private static final String USER_AGENT = "userAgent";
    private static final String INSTANCE_URL = "instanceUrl";
    private static final String LOGIN_URL = "loginUrl";
    private static final String IDENTITY_URL = "identityUrl";
    private static final String CLIENT_ID = "clientId";
    private static final String ORG_ID = "orgId";
    private static final String USER_ID = "userId";
    private static final String REFRESH_TOKEN = "refreshToken";
    private static final String ACCESS_TOKEN = "accessToken";
    private static final String COMMUNITY_ID = "communityId";
    private static final String COMMUNITY_URL = "communityUrl";
  
    // Used in refresh REST call
    private static final String API_VERSION = ApiVersionStrings.VERSION_NUMBER;
  
  // Rest client
    private RestClient client;
  private ClientManager clientManager;
    
    // Config
  private BootConfig bootconfig;
    private PasscodeManager passcodeManager;
    private TokenRevocationReceiver tokenRevocationReceiver;
    private UserSwitchReceiver userSwitchReceiver;
    private boolean tokenRevocationRegistered;

  // Web app loaded?
  private boolean webAppLoaded = false;  
  
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
      Log.i("SalesforceDroidGapActivity.onCreate", "onCreate called");
        super.onCreate(savedInstanceState);

    // Get bootconfig
    bootconfig = BootConfig.getBootConfig(this);

        // Get clientManager
        clientManager = buildClientManager();

        // Passcode manager
        passcodeManager = SalesforceSDKManager.getInstance().getPasscodeManager();
        tokenRevocationReceiver = new TokenRevocationReceiver(this);
        userSwitchReceiver = new DroidGapUserSwitchReceiver();
        registerReceiver(userSwitchReceiver, new IntentFilter(UserAccountManager.USER_SWITCH_INTENT_ACTION));

        // Ensure we have a CookieSyncManager
        CookieSyncManager.createInstance(this);

    // Let observers know
    EventsObservable.get().notifyEvent(EventType.MainActivityCreateComplete, this);
    }

  protected ClientManager buildClientManager() {
    return new ClientManager(this, SalesforceSDKManager.getInstance().getAccountType(),
        SalesforceSDKManager.getInstance().getLoginOptions(),
        SalesforceSDKManager.getInstance().shouldLogoutWhenTokenRevoked());
  }

    @Override
    public void init(CordovaWebView webView, CordovaWebViewClient webViewClient, CordovaChromeClient webChromeClient) {
      Log.i("SalesforceDroidGapActivity.init", "init called");
        super.init(webView, new SalesforceGapViewClient(this, webView), webChromeClient);
        final String uaStr = SalesforceSDKManager.getInstance().getUserAgent();
        if (null != this.appView) {
            WebSettings webSettings = this.appView.getSettings();
            String origUserAgent = webSettings.getUserAgentString();
            final String extendedUserAgentString = uaStr + " Hybrid " + (origUserAgent == null ? "" : origUserAgent);
            webSettings.setUserAgentString(extendedUserAgentString);

            // Configure HTML5 cache support.
            webSettings.setDomStorageEnabled(true);
            String cachePath = getApplicationContext().getCacheDir().getAbsolutePath();
            webSettings.setAppCachePath(cachePath);
            webSettings.setAppCacheEnabled(true);
            webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
            webSettings.setAllowFileAccess(true);
            webSettings.setSavePassword(false);
            webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
            EventsObservable.get().notifyEvent(EventType.GapWebViewCreateComplete, appView);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!tokenRevocationRegistered) {
            registerReceiver(tokenRevocationReceiver, new IntentFilter(ClientManager.ACCESS_TOKEN_REVOKE_INTENT));
        }
      if (passcodeManager.onResume(this)) {

            // Get client (if already logged in)
            try {
          client = clientManager.peekRestClient();
        } catch (AccountInfoNotFoundException e) {
          client = null;
        }

        // Not logged in
          if (client == null) {
            onResumeNotLoggedIn();
          }

          // Logged in
          else {

            // Web app never loaded
            if (!webAppLoaded) {
              onResumeLoggedInNotLoaded();
            }

            // Web app already loaded
            else {
                  Log.i("SalesforceDroidGapActivity.onResume", "Already logged in / web app already loaded");
            }
              CookieSyncManager.getInstance().startSync();
          }
        }
    }

    /**
     * Restarts the activity if the user has been switched.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  private void restartIfUserSwitched() {
    if (client != null) {
            try {
          RestClient currentClient = clientManager.peekRestClient();
          if (currentClient != null && !currentClient.getClientInfo().userId.equals(client.getClientInfo().userId)) {
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
                this.recreate();
                } else {
                  this.onDestroy();
                  this.onCreate(null);
                }
          }
        } catch (AccountInfoNotFoundException e) {
              Log.i("SalesforceDroidGapActivity.restartIfUserSwitched", "No user account found");
        }
        }
  }

  /**
   * Called when resuming activity and user is not authenticated
   */
  private void onResumeNotLoggedIn() {

    // Need to be authenticated
    if (bootconfig.shouldAuthenticate()) {

      // Online
      if (SalesforceSDKManager.getInstance().hasNetwork()) {
          Log.i("SalesforceDroidGapActivity.onResumeNotLoggedIn", "Should authenticate / online - authenticating");
        authenticate(null);
      }

      // Offline
      else {
        Log.w("SalesforceDroidGapActivity.onResumeNotLoggedIn", "Should authenticate / offline - cannot proceed");
        loadErrorPage();
      }
    }

    // Does not need to be authenticated
    else {

      // Local
      if (bootconfig.isLocal()) {
        Log.i("SalesforceDroidGapActivity.onResumeNotLoggedIn", "Should not authenticate / local start page - loading web app");
        loadLocalStartPage();
      }

      // Remote
      else {
        Log.w("SalesforceDroidGapActivity.onResumeNotLoggedIn", "Should not authenticate / remote start page - cannot proceed");
        loadErrorPage();
      }
    }
  }

  /**
   * Called when resuming activity and user is authenticated but webview has not been loaded yet
   */
  private void onResumeLoggedInNotLoaded() {

    // Local
    if (bootconfig.isLocal()) {
      Log.i("SalesforceDroidGapActivity.onResumeLoggedInNotLoaded", "Local start page - loading web app");
      loadLocalStartPage();
    }

    // Remote
    else {

      // Online
      if (SalesforceSDKManager.getInstance().hasNetwork()) {
          Log.i("SalesforceDroidGapActivity.onResumeLoggedInNotLoaded", "Remote start page / online - loading web app");
          loadRemoteStartPage();
      }

      // Offline
      else {
        // Has cached version
        if (SalesforceGapViewClient.hasCachedAppHome(this)) {
              Log.i("SalesforceDroidGapActivity.onResumeLoggedInNotLoaded", "Remote start page / offline / cached - loading cached web app");
          loadCachedStartPage();
        }

        // No cached version
        else {
              Log.w("SalesforceDroidGapActivity.onResumeLoggedInNotLoaded", "Remote start page / offline / not cached - cannot proceed");
              loadErrorPage();
        }
      }
    }
  }

    @Override
    public void onPause() {
        super.onPause();
        passcodeManager.onPause(this);
        CookieSyncManager.getInstance().stopSync();
        if (tokenRevocationRegistered) {
          unregisterReceiver(tokenRevocationReceiver);
        }
    }

    @Override
    public void onDestroy() {
      unregisterReceiver(userSwitchReceiver);
      super.onDestroy();
    }

    @Override
    public void onUserInteraction() {
        passcodeManager.recordUserInteraction();
    }
    
  public BootConfig getBootConfig() {
    return bootconfig;
  }
    
    /**
     * Get a RestClient and refresh the auth token
     * @param callbackContext when not null credentials/errors are sent through to callbackContext.success()/error()
     */
    public void authenticate(final CallbackContext callbackContext) {
      Log.i("SalesforceDroidGapActivity.authenticate", "authenticate called");
      clientManager.getRestClient(this, new RestClientCallback() {

      @Override
      public void authenticatedRestClient(RestClient client) {
        if (client == null) {
            Log.i("SalesforceDroidGapActivity.authenticate", "authenticatedRestClient called with null client");
          SalesforceSDKManager.getInstance().logout(SalesforceDroidGapActivity.this);
              } else {
            Log.i("SalesforceDroidGapActivity.authenticate", "authenticatedRestClient called with actual client");
                  SalesforceDroidGapActivity.this.client = client;

                  /*
                     * Do a cheap REST call to refresh the access token if needed.
                     * If the login took place a while back (e.g. the already logged
                     * in application was restarted), then the returned session ID
                     * (access token) might be stale. This is not an issue if one
                     * uses exclusively RestClient for calling the server because
                     * it takes care of refreshing the access token when needed,
                     * but a stale session ID will cause the WebView to redirect
                     * to the web login.
                     */
                  SalesforceDroidGapActivity.this.client.sendAsync(RestRequest.getRequestForResources(API_VERSION), new AsyncRequestCallback() {

                        @Override
                        public void onSuccess(RestRequest request, RestResponse response) {
                            setSidCookies();
                            loadVFPingPage();
                            if (callbackContext != null) {
                                callbackContext.success(getJSONCredentials());
                            }
                        }

                        @Override
                        public void onError(Exception exception) {
                          if (callbackContext != null) {
                              callbackContext.error(exception.getMessage());
                          }
                        }
                    });
              }
      }
      });
    }
    
    /**
     * If an action causes a redirect to the login page, this method will be called.
     * It causes the session to be refreshed and reloads url through the front door.
     * @param url the page to load once the session has been refreshed.
     */
    public void refresh(final String url) {
        Log.i("SalesforceDroidGapActivity.refresh", "refresh called");
        client.sendAsync(RestRequest.getRequestForResources(API_VERSION), new AsyncRequestCallback() {
    
          @Override
                public void onSuccess(RestRequest request, RestResponse response) {
                    Log.i("SalesforceOAuthPlugin.refresh", "Refresh succeeded");
                    setSidCookies();
                    loadVFPingPage();
                    String frontDoorUrl = getFrontDoorUrl(url);
                    loadUrl(frontDoorUrl);
                }

                @Override
                public void onError(Exception exception) {
                    Log.w("SalesforceDroidGapActivity.refresh", "Refresh failed - " + exception);

                    // Only logout if we are NOT offline
                    if (!(exception instanceof NoNetworkException)) {
                        SalesforceSDKManager.getInstance().logout(SalesforceDroidGapActivity.this);
                    }
                }
            });
    }        

    /**
     * Loads the VF ping page and sets cookies.
     */
    private void loadVFPingPage() {
      if (!bootconfig.isLocal()) {
          final ClientInfo clientInfo = SalesforceDroidGapActivity.this.client.getClientInfo();
            URI instanceUrl = null;
            if (clientInfo != null) {
              instanceUrl = clientInfo.getInstanceUrl();
            }
            setVFCookies(instanceUrl);
      }
    }

    /**
     * Sets VF domain cookies by loading the VF ping page on an invisible WebView.
     *
     * @param instanceUrl Instance URL.
     */
    private static void setVFCookies(URI instanceUrl) {
      if (instanceUrl != null) {
          final WebView view = new WebView(SalesforceSDKManager.getInstance().getAppContext());
          view.setVisibility(View.GONE);
          view.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  final CookieSyncManager cookieSyncMgr = CookieSyncManager.getInstance();
                    final CookieManager cookieMgr = CookieManager.getInstance();
                    cookieMgr.setAcceptCookie(true);
                    cookieSyncMgr.sync();
              return true;
            }
          });
          view.loadUrl(instanceUrl.toString() + "/visualforce/session?url=/apexpages/utils/ping.apexp&autoPrefixVFDomain=true");
      }
    }

    /**
     * Load local start page
     */
    public void loadLocalStartPage() {
      assert bootconfig.isLocal();
      String startPage = bootconfig.getStartPage();
      Log.i("SalesforceDroidGapActivity.loadLocalStartPage", "loading: " + startPage);
      loadUrl("file:///android_asset/www/" + startPage);
      webAppLoaded = true;
    }    

    /**
     * Load remote start page (front-doored)
     */
    public void loadRemoteStartPage() {
      assert !bootconfig.isLocal();
      String startPage = bootconfig.getStartPage();
      Log.i("SalesforceDroidGapActivity.loadRemoteStartPage", "loading: " + startPage);
    String url = getFrontDoorUrl(startPage);
    loadUrl(url);
      webAppLoaded = true;
    }
    
    /**
     * @param url
     * @return front-door url
     */
    public String getFrontDoorUrl(String url) {
    String frontDoorUrl = client.getClientInfo().getInstanceUrlAsString() + "/secur/frontdoor.jsp?";
    List<NameValuePair> params = new LinkedList<NameValuePair>();
    params.add(new BasicNameValuePair("sid", client.getAuthToken()));
    params.add(new BasicNameValuePair("retURL", client.getClientInfo().resolveUrl(url).toString()));
    params.add(new BasicNameValuePair("display", "touch"));
    frontDoorUrl += URLEncodedUtils.format(params, "UTF-8");
      return frontDoorUrl;
    }

  /**
   * Load cached start page
   */
  private void loadCachedStartPage() {
    String url = SalesforceGapViewClient.getAppHomeUrl(this);
    loadUrl(url);
      webAppLoaded = true;
  }
    
    /**
     * Load error page 
     */
    public void loadErrorPage() {
      Log.i("SalesforceDroidGapActivity.getErrorPageUrl", "getErrorPageUrl called");
      String errorPage = bootconfig.getErrorPage();
      Log.i("SalesforceDroidGapActivity.getErrorPageUrl", "local error page: " + errorPage);
    loadUrl("file:///android_asset/www/" + errorPage);
    }
    
   /**
    * Set cookies on cookie manager
    * @param client
    */
   private void setSidCookies() {
       Log.i("SalesforceDroidGapActivity.setSidCookies", "setting cookies");
       CookieSyncManager cookieSyncMgr = CookieSyncManager.getInstance();
       CookieManager cookieMgr = CookieManager.getInstance();
       cookieMgr.setAcceptCookie(true);  // Required to set additional cookies that the auth process will return.
       cookieMgr.removeSessionCookie();
       SystemClock.sleep(250); // removeSessionCookies kicks out a thread - let it finish
       String accessToken = client.getAuthToken();

       // Android 3.0+ clients want to use the standard .[domain] format. Earlier clients will only work
       // with the [domain] format.  Set them both; each platform will leverage its respective format.
       addSidCookieForInstance(cookieMgr,"salesforce.com", accessToken);
       addSidCookieForInstance(cookieMgr,".salesforce.com", accessToken);

       // Log.i("SalesforceOAuthPlugin.setSidCookies", "accessToken=" + accessToken);
       cookieSyncMgr.sync();
   }

   private void addSidCookieForInstance(CookieManager cookieMgr, String domain, String sid) {
     final ClientInfo clientInfo = SalesforceDroidGapActivity.this.client.getClientInfo();
       URI instanceUrl = null;
       if (clientInfo != null) {
         instanceUrl = clientInfo.getInstanceUrl();
       }
       String host = null;
       if (instanceUrl != null) {
         host = instanceUrl.getHost();
       }
       if (host != null) {
         addSidCookieForDomain(cookieMgr, host, sid);
       }
   }

   private void addSidCookieForDomain(CookieManager cookieMgr, String domain, String sid) {
     String cookieStr = "sid=" + sid;
       cookieMgr.setCookie(domain, cookieStr);
   }    
    
   /**
    * @return credentials as JSONObject
    */
   public JSONObject getJSONCredentials() {
     if (client != null) {
         ClientInfo clientInfo = client.getClientInfo();
         Map<String, String> data = new HashMap<String, String>();
         data.put(ACCESS_TOKEN, client.getAuthToken());
         data.put(REFRESH_TOKEN, client.getRefreshToken());
         data.put(USER_ID, clientInfo.userId);
         data.put(ORG_ID, clientInfo.orgId);
         data.put(CLIENT_ID, clientInfo.clientId);
         data.put(LOGIN_URL, clientInfo.loginUrl.toString());
         data.put(IDENTITY_URL, clientInfo.identityUrl.toString());
         data.put(INSTANCE_URL, clientInfo.instanceUrl.toString());
         data.put(USER_AGENT, SalesforceSDKManager.getInstance().getUserAgent());
         data.put(COMMUNITY_ID, clientInfo.communityId);
         data.put(COMMUNITY_URL, clientInfo.communityUrl);
         return new JSONObject(data);
     } else {
       return null;
     }
   }

    /**
     * Exception thrown if initial web page load fails.
     */
    public static class HybridAppLoadException extends RuntimeException {

    public HybridAppLoadException(String msg) {
      super(msg);
    }

    private static final long serialVersionUID = 1L;
    }

    /**
     * Acts on the user switch event.
     *
     * @author bhariharan
     */
    private class DroidGapUserSwitchReceiver extends UserSwitchReceiver {

    @Override
    protected void onUserSwitch() {
      restartIfUserSwitched();
    }
    }
}




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