001package com.gigya.android.sdk; 002 003import android.annotation.SuppressLint; 004import android.app.Application; 005import android.content.Context; 006import android.support.annotation.NonNull; 007import android.support.annotation.Nullable; 008 009import com.gigya.android.sdk.account.GigyaAccountClass; 010import com.gigya.android.sdk.account.IAccountService; 011import com.gigya.android.sdk.account.models.GigyaAccount; 012import com.gigya.android.sdk.api.GigyaApiResponse; 013import com.gigya.android.sdk.api.IBusinessApiService; 014import com.gigya.android.sdk.containers.GigyaContainer; 015import com.gigya.android.sdk.containers.IoCContainer; 016import com.gigya.android.sdk.interruption.IInterruptionResolverFactory; 017import com.gigya.android.sdk.network.GigyaError; 018import com.gigya.android.sdk.network.adapter.RestAdapter; 019import com.gigya.android.sdk.providers.IProviderFactory; 020import com.gigya.android.sdk.providers.provider.Provider; 021import com.gigya.android.sdk.session.ISessionService; 022import com.gigya.android.sdk.session.ISessionVerificationService; 023import com.gigya.android.sdk.session.SessionInfo; 024import com.gigya.android.sdk.ui.IPresenter; 025import com.gigya.android.sdk.ui.plugin.GigyaPluginFragment; 026import com.gigya.android.sdk.ui.plugin.IGigyaWebBridge; 027 028import java.util.Arrays; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032import java.util.TreeMap; 033 034/** 035 * Gigya SDK main interface. 036 * Provides access to the Gigya services. 037 * 038 * @param <T> Generic account scheme. Extended from base GigyaAccount model. 039 */ 040public class Gigya<T extends GigyaAccount> { 041 042 //region static 043 public static final String VERSION = "4.0.8"; 044 045 private static final String LOG_TAG = "Gigya"; 046 047 /** 048 * Gigya default api domain. 049 */ 050 private static final String DEFAULT_API_DOMAIN = "us1.gigya.com"; 051 052 private static IoCContainer CONTAINER; 053 054 public static IoCContainer getContainer() { 055 if (CONTAINER == null) { 056 CONTAINER = new GigyaContainer(); 057 } 058 return CONTAINER; 059 } 060 061 public static void setApplication(Application appContext) { 062 getContainer() 063 .bind(Application.class, appContext) 064 .bind(Context.class, appContext); 065 } 066 067 @SuppressLint("StaticFieldLeak") 068 private static Gigya INSTANCE; 069 070 /* 071 Simplified instance getter for use only after calling getInstance(Context context) at least once. 072 */ 073 @SuppressWarnings("unchecked") 074 public static synchronized Gigya<? extends GigyaAccount> getInstance() { 075 if (INSTANCE == null) { 076 return getInstance(GigyaAccount.class); 077 } 078 return INSTANCE; 079 } 080 081 /* 082 Generic account type instance getter. 083 */ 084 @SuppressWarnings("unchecked") 085 public static synchronized <V extends GigyaAccount> Gigya<V> getInstance(@NonNull Class<V> accountClazz) { 086 if (INSTANCE == null) { 087 IoCContainer container = getContainer(); 088 container.bind(GigyaAccountClass.class, new GigyaAccountClass(accountClazz)); 089 090 try { 091 INSTANCE = container.createInstance(Gigya.class); 092 } catch (Exception e) { 093 GigyaLogger.error(LOG_TAG, "Error creating Gigya SDK (did you forget to Gigya.setApplication or missing apiKey?)"); 094 e.printStackTrace(); 095 throw new RuntimeException("Error creating Gigya SDK (did you forget to Gigya.setApplication or missing apiKey?)Error creating Gigya SDK (did you forget to Gigya.setApplication or missing apiKey?)"); 096 } 097 } 098 // Check scheme. If already set log an error. 099 final Class schema = INSTANCE.getAccountSchema(); 100 if (schema != accountClazz) { 101 GigyaLogger.error(LOG_TAG, "Scheme already set in previous initialization.\nSDK does not allow to override a set scheme."); 102 throw new RuntimeException("Scheme already set in previous initialization.\nSDK does not allow to override a set scheme."); 103 } 104 return INSTANCE; 105 } 106 107 //endregion 108 109 final private Application _context; 110 /** 111 * SDK main configuration structure. 112 */ 113 final private Config _config; 114 final private ConfigFactory _configFactory; 115 final private ISessionService _sessionService; 116 final private IAccountService<T> _accountService; 117 final private IBusinessApiService<T> _businessApiService; 118 final private ISessionVerificationService _sessionVerificationService; 119 final private IInterruptionResolverFactory _interruptionResolverFactory; 120 final private IPresenter<T> _presenter; 121 final private IProviderFactory _providerFactory; 122 final private IoCContainer _container; 123 124 protected Gigya( 125 @NonNull Application context, 126 Config config, 127 ConfigFactory configFactory, 128 ISessionService sessionService, 129 IAccountService<T> accountService, 130 IBusinessApiService<T> businessApiService, 131 ISessionVerificationService sessionVerificationService, 132 IInterruptionResolverFactory interruptionsHandler, 133 IPresenter<T> presenter, 134 IProviderFactory providerFactory, 135 IoCContainer container) { 136 // Setup dependencies. 137 _context = context; 138 _config = config; 139 _configFactory = configFactory; 140 _sessionService = sessionService; 141 _accountService = accountService; 142 _businessApiService = businessApiService; 143 _sessionVerificationService = sessionVerificationService; 144 _interruptionResolverFactory = interruptionsHandler; 145 _presenter = presenter; 146 _providerFactory = providerFactory; 147 _container = container; 148 149 // Setup sdk 150 _sessionService.load(); 151 init(false); 152 153 // Must be registered following the init call. Dependent on full parsed config. 154 _sessionVerificationService.registerActivityLifecycleCallbacks(); 155 } 156 157 //region INITIALIZE 158 159 /** 160 * Explicitly initialize the SDK. 161 * Using this init() method will set the SDK domain to the default "us1.gigya.com" 162 * see {@link #init(String, String)} to explicitly set the required domain. 163 * 164 * @param apiKey Client API-KEY. 165 */ 166 @SuppressWarnings("unused") 167 public void init(@NonNull String apiKey) { 168 init(apiKey, DEFAULT_API_DOMAIN); 169 } 170 171 /** 172 * Explicitly initialize the SDK. 173 * 174 * @param apiKey Client API-KEY 175 * @param apiDomain Request Domain. 176 */ 177 public void init(@NonNull String apiKey, @NonNull String apiDomain) { 178 // Override existing configuration when applied explicitly. 179 _config.updateWith(apiKey, apiDomain); 180 init(true); 181 } 182 183 /** 184 * Implicitly initialize the SDK. 185 * Available Options: 186 * - read JSON assets file. 187 * - parse application manifest meta data tags. 188 * For explicit setting see {@link #init(String, String)} method. 189 */ 190 private void init(boolean explicit) { 191 // Will load configuration fields only if none have yet to be set. 192 if (_config.getApiKey() == null) { 193 // Try to from assets JSON file, 194 Config dynamicConfig = _configFactory.load(); 195 _config.updateWith(dynamicConfig); 196 } 197 198 // Set next account invalidation timestamp if available. 199 if (_config.getAccountCacheTime() != 0) { 200 _accountService.nextAccountInvalidationTimestamp(); 201 } 202 203 if (explicit) { 204 if (_config.getApiKey() == null || _config.getApiKey().isEmpty()) { 205 GigyaLogger.error(LOG_TAG, "Failed to set the SDK Api-Key. Please verify you have correctly initialized the SDK."); 206 throw new RuntimeException("Failed to set the SDK Api-Key. Please verify you have correctly initialized the SDK."); 207 } 208 } 209 } 210 211 //endregion 212 213 //region PUBLIC INTERFACING 214 215 public Class<T> getAccountSchema() { 216 return _accountService.getAccountSchema(); 217 } 218 219 public Context getContext() { 220 return _context; 221 } 222 223 /** 224 * Update interruption handling. 225 * By default, the Gigya SDK will handle various API interruptions to allow simple resolving of certain common errors. 226 * Setting interruptions to FALSE will force the end user to handle his own errors. 227 * 228 * @param sdkHandles False if manually handling all errors. 229 */ 230 public void handleInterruptions(boolean sdkHandles) { 231 _interruptionResolverFactory.setEnabled(sdkHandles); 232 } 233 234 /** 235 * Return SDK interruptions state. 236 * if TRUE, interruption handling will be optional via the GigyaLoginCallback. 237 */ 238 public boolean interruptionsEnabled() { 239 return _interruptionResolverFactory.isEnabled(); 240 } 241 242 //endregion 243 244 //region ANONYMOUS APIS 245 246 /** 247 * Send request to Gigya servers. 248 * 249 * @param api Request method identifier. 250 * @param params Additional parameters. 251 * @param gigyaCallback Response listener callback. 252 */ 253 public void send(String api, Map<String, Object> params, GigyaCallback<GigyaApiResponse> gigyaCallback) { 254 _businessApiService.send(api, params, RestAdapter.HttpMethod.GET.intValue(), GigyaApiResponse.class, gigyaCallback); 255 } 256 257 /** 258 * Send a generic type request to Gigya servers. 259 * 260 * @param api Request method identifier. 261 * @param params Additional parameters. 262 * @param requestMethod Request method (GET, POST). 263 * @param clazz Response class scheme. 264 * @param gigyaCallback Response listener callback. 265 */ 266 public <V> void send(String api, Map<String, Object> params, int requestMethod, Class<V> clazz, GigyaCallback<V> gigyaCallback) { 267 _businessApiService.send(api, params, requestMethod, clazz, gigyaCallback); 268 } 269 270 //endregion 271 272 //region GIGYA ACCOUNT & SESSION 273 274 /** 275 * Get current session. 276 * 277 * @return SessionInfo instance. 278 */ 279 @Nullable 280 public SessionInfo getSession() { 281 return _sessionService.getSession(); 282 } 283 284 /** 285 * Manually set the current session. 286 * Setting a session manually will update the current session persistence state and login state. 287 * 288 * @param session SessionInfo instance. 289 */ 290 public void setSession(@NonNull SessionInfo session) { 291 _sessionService.setSession(session); 292 } 293 294 /** 295 * Check if we currently have a valid session. 296 */ 297 public boolean isLoggedIn() { 298 return _sessionService.isValid(); 299 } 300 301 /** 302 * Logout of Gigya services. 303 * This will clean all session related data persistence. 304 */ 305 public void logout() { 306 logout(null); 307 } 308 309 /** 310 * Logout of Gigya services. 311 * This will clean all session related data persistence. 312 * 313 * @param gigyaCallback Response listener callback. 314 */ 315 public void logout(GigyaCallback<GigyaApiResponse> gigyaCallback) { 316 GigyaLogger.debug(LOG_TAG, "logout: "); 317 318 _businessApiService.logout(gigyaCallback); 319 320 _sessionService.clear(true); 321 322 _sessionVerificationService.stop(); 323 324 // Clear presenter related data (cookies). 325 _presenter.clearOnLogout(); 326 327 _providerFactory.logoutFromUsedSocialProviders(); 328 } 329 330 //endregion 331 332 //region BUSINESS APIS 333 334 /** 335 * Login with provided id and password. 336 * 337 * @param loginId LoginID. 338 * @param password Login password. 339 * @param gigyaCallback Response listener callback. 340 */ 341 public void login(String loginId, String password, GigyaLoginCallback<T> gigyaCallback) { 342 GigyaLogger.debug(LOG_TAG, "login: with loginId = " + loginId); 343 final Map<String, Object> params = new TreeMap<>(); 344 params.put("loginID", loginId); 345 params.put("password", password); 346 login(params, gigyaCallback); 347 } 348 349 /** 350 * Login with given parameters. 351 * 352 * @param params parameters map. 353 * @param gigyaLoginCallback Login response callback. 354 */ 355 public void login(@NonNull Map<String, Object> params, final GigyaLoginCallback<T> gigyaLoginCallback) { 356 GigyaLogger.debug(LOG_TAG, "login: with params = " + params.toString()); 357 _businessApiService.login(params, gigyaLoginCallback); 358 } 359 360 /** 361 * Login given a specific 3rd party provider. 362 * 363 * @param socialProvider Selected providers {@link GigyaDefinitions.Providers.SocialProvider}. 364 * @param params Parameters map. 365 * @param gigyaLoginCallback Login response callback. 366 */ 367 public void login(@GigyaDefinitions.Providers.SocialProvider String socialProvider, Map<String, Object> params, GigyaLoginCallback<T> gigyaLoginCallback) { 368 GigyaLogger.debug(LOG_TAG, "login: with provider = " + socialProvider); 369 _businessApiService.login(socialProvider, params, gigyaLoginCallback); 370 } 371 372 /** 373 * Request account info. 374 * 375 * @param gigyaCallback Response listener callback. 376 */ 377 public void getAccount(@NonNull GigyaCallback<T> gigyaCallback) { 378 GigyaLogger.debug(LOG_TAG, "getAccount: "); 379 getAccount(false, gigyaCallback); 380 } 381 382 /** 383 * Request account info. 384 * 385 * @param invalidateCache Should override the account caching option. When set to true, the SDK will not cache the account object. 386 * @param gigyaCallback Response listener callback. 387 */ 388 @SuppressWarnings("unused") 389 public void getAccount(final boolean invalidateCache, GigyaCallback<T> gigyaCallback) { 390 GigyaLogger.debug(LOG_TAG, "getAccount: overrideCache = " + invalidateCache); 391 if (invalidateCache) { 392 _accountService.invalidateAccount(); 393 } 394 395 _businessApiService.getAccount(gigyaCallback); 396 } 397 398 /** 399 * Request account info given parameters map. 400 * 401 * @param params Request parameter map. 402 * @param gigyaCallback Response listener callback. 403 */ 404 public void getAccount(@NonNull final Map<String, Object> params, @NonNull GigyaCallback<T> gigyaCallback) { 405 GigyaLogger.debug(LOG_TAG, "getAccount with params:\n" + params.toString()); 406 _businessApiService.getAccount(params, gigyaCallback); 407 } 408 409 /** 410 * Request account info given comma separated array of include parameters & comma separated array of profile extra fields. 411 * 412 * @param include String[] array. 413 * @param profileExtraFields String[] array. 414 * @param gigyaCallback Response listener callback. 415 */ 416 public void getAccount(@NonNull final String[] include, @NonNull final String[] profileExtraFields, @NonNull GigyaCallback<T> gigyaCallback) { 417 GigyaLogger.debug(LOG_TAG, "getAccount with include:\n" + Arrays.toString(include) 418 + "\nand profileExtraFields:\n" + Arrays.toString(profileExtraFields)); 419 _businessApiService.getAccount(include, profileExtraFields, gigyaCallback); 420 } 421 422 /** 423 * Set account info 424 * 425 * @param account Updated account object. 426 * @param gigyaCallback Response listener callback. 427 */ 428 public void setAccount(T account, GigyaCallback<T> gigyaCallback) { 429 GigyaLogger.debug(LOG_TAG, "setAccount: "); 430 _businessApiService.setAccount(account, gigyaCallback); 431 } 432 433 /** 434 * Set account info given update parameters. 435 * 436 * @param params Updated account parameters. 437 * @param gigyaCallback Response listener callback. 438 */ 439 public void setAccount(Map<String, Object> params, GigyaCallback<T> gigyaCallback) { 440 GigyaLogger.debug(LOG_TAG, "setAccount: with params"); 441 _businessApiService.setAccount(params, gigyaCallback); 442 } 443 444 /** 445 * Request verify login given account UID/ 446 * 447 * @param UID Account UID identifier. 448 * @param gigyaCallback Response listener callback. 449 */ 450 public void verifyLogin(String UID, GigyaCallback<T> gigyaCallback) { 451 GigyaLogger.debug(LOG_TAG, "verifyLogin: for UID = " + UID); 452 _businessApiService.verifyLogin(UID, gigyaCallback); 453 } 454 455 /** 456 * Register account using email and password combination. 457 * Additional parameters are included to allow additional parameters to be added such as profile. 458 * 459 * @param email User email identifier. 460 * @param password User password. 461 * @param params Additional parameters. 462 * @param callback Response listener callback. 463 */ 464 public void register(String email, String password, @NonNull Map<String, Object> params, GigyaLoginCallback<T> callback) { 465 GigyaLogger.debug(LOG_TAG, "register: with email: " + email + " and params: " + params.toString()); 466 params.put("email", email); 467 params.put("password", password); 468 _businessApiService.register(params, callback); 469 } 470 471 /** 472 * Register account using email and password combination. 473 * 474 * @param email User email identifier. 475 * @param password User password. 476 * @param callback Response listener callback. 477 */ 478 public void register(String email, String password, GigyaLoginCallback<T> callback) { 479 GigyaLogger.debug(LOG_TAG, "register: with email: " + email); 480 final Map<String, Object> params = new HashMap<>(); 481 register(email, password, params, callback); 482 } 483 484 /** 485 * Send a reset email password to verified email attached to the users loginId. 486 * 487 * @param loginId User login id. 488 * @param gigyaCallback Response listener callback. 489 */ 490 public void forgotPassword(String loginId, GigyaCallback<GigyaApiResponse> gigyaCallback) { 491 final Map<String, Object> params = new HashMap<>(); 492 params.put("loginID", loginId); 493 forgotPassword(params, gigyaCallback); 494 } 495 496 /** 497 * Send a reset email password to verified email attached to the users loginId. 498 * 499 * @param params Parameter map. 500 * @param gigyaCallback Response listener callback. 501 * @see <a href="https://developers.gigya.com/display/GD/accounts.resetPassword+REST">accounts.resetPassword REST</a> for available parameters. 502 */ 503 public void forgotPassword(@NonNull Map<String, Object> params, GigyaCallback<GigyaApiResponse> gigyaCallback) { 504 GigyaLogger.debug(LOG_TAG, "forgotPassword: with given parameters " + params.toString()); 505 _businessApiService.forgotPassword(params, gigyaCallback); 506 } 507 508 /** 509 * Add a social connection to existing account. 510 * 511 * @param socialProvider Social provider identifier. 512 * @param loginCallback Response listener callback. 513 */ 514 public void addConnection(@GigyaDefinitions.Providers.SocialProvider String socialProvider, GigyaLoginCallback<T> loginCallback) { 515 GigyaLogger.debug(LOG_TAG, "addConnection: with " + socialProvider); 516 _businessApiService.addConnection(socialProvider, loginCallback); 517 } 518 519 /** 520 * Remove a social connection from an existing account. 521 * 522 * @param socialProvider Social provider identifier. 523 * @param gigyaCallback Response listener callback. 524 */ 525 public void removeConnection(@GigyaDefinitions.Providers.SocialProvider String socialProvider, GigyaCallback<GigyaApiResponse> gigyaCallback) { 526 GigyaLogger.debug(LOG_TAG, "removeConnection: with " + socialProvider); 527 _businessApiService.removeConnection(socialProvider, gigyaCallback); 528 } 529 530 /** 531 * Login to with social provider when the provider session is available (obtained via specific provider login process). 532 * 533 * @param params Parameter map. 534 * @param gigyaLoginCallback Response listener callback. 535 */ 536 public void notifySocialLogin(@NonNull Map<String, Object> params, GigyaLoginCallback<T> gigyaLoginCallback) { 537 GigyaLogger.debug(LOG_TAG, "notifySocialLogin: with parameters: " + params.toString()); 538 _businessApiService.notifyNativeSocialLogin(params, gigyaLoginCallback, null); 539 } 540 541 //endregion 542 543 //region NATIVE LOGIN 544 545 /** 546 * Request reference to used Gigya social provider. 547 * Currently supported provider (GOOGLE, FACEBOOK, LINE, WECHAT). 548 * 549 * @param name Provider name. 550 * @return Provider reference or null if not available. 551 */ 552 @Nullable 553 public Provider getUsedSocialProvider(String name) { 554 return _providerFactory.usedProviderFor(name); 555 } 556 557 /** 558 * Present social login selection list. 559 * 560 * @param providers List of selected social providers {@link GigyaDefinitions.Providers.SocialProvider}. 561 * @param params Request parameters. 562 * @param gigyaLoginCallback Login response callback. 563 */ 564 public void socialLoginWith(@GigyaDefinitions.Providers.SocialProvider List<String> providers, 565 @NonNull Map<String, Object> params, final GigyaLoginCallback<T> gigyaLoginCallback) { 566 GigyaLogger.debug(LOG_TAG, "socialLoginWith: with parameters:\n" + params.toString()); 567 _presenter.showNativeLoginProviders(providers, _businessApiService, params, gigyaLoginCallback); 568 } 569 570 //endregion 571 572 //region PLUGINS 573 574 /** 575 * Show Gigya ScreenSets flow using the PluginFragment. 576 * UI will be presented via WebView. 577 * 578 * @param screensSet Main ScreensSet group identifier 579 * @param fullScreen Show in fullscreen mode. 580 * @param params ScreensSet flow parameters. 581 * @param gigyaPluginCallback Plugin callback. 582 */ 583 public void showScreenSet(final String screensSet, boolean fullScreen, @NonNull final Map<String, Object> params, final GigyaPluginCallback<T> gigyaPluginCallback) { 584 params.put("screenSet", screensSet); 585 GigyaLogger.debug(LOG_TAG, "showPlugin: " + GigyaPluginFragment.PLUGIN_SCREENSETS + ", with parameters:\n" + params.toString()); 586 _presenter.showPlugin(false, GigyaPluginFragment.PLUGIN_SCREENSETS, fullScreen, params, gigyaPluginCallback); 587 } 588 589 /** 590 * Update device information in server. 591 * Device information includes: platform, manufacturer, os & push token. 592 * Use this method manually if your flow requires to update the push service token. 593 * Additional device info is generated at runtime. 594 * 595 * @param newPushToken New provided push token. 596 */ 597 public void updateDeviceInfo(@NonNull final String newPushToken) { 598 _businessApiService.updateDevice(newPushToken, new GigyaCallback<GigyaApiResponse>() { 599 @Override 600 public void onSuccess(GigyaApiResponse obj) { 601 GigyaLogger.debug(LOG_TAG, "Successfully update push token. Persisting new token"); 602 } 603 604 @Override 605 public void onError(GigyaError error) { 606 GigyaLogger.debug(LOG_TAG, "Failed to update device info."); 607 } 608 }); 609 } 610 611 /** 612 * Create an new instance of the GigyaWebBridge. 613 * 614 * @return GigyaWebBridge instance. 615 */ 616 @SuppressWarnings("unchecked") 617 public IGigyaWebBridge<T> createWebBridge() { 618 try { 619 return _container.get(IGigyaWebBridge.class); 620 } catch (Exception ex) { 621 ex.printStackTrace(); 622 GigyaLogger.error(LOG_TAG, "Exception creating new WebBridge instance"); 623 } 624 return null; 625 } 626 627 //endregion 628}