@Override
 public void onPerformSync(
     Account account,
     Bundle extras,
     String authority,
     ContentProviderClient provider,
     SyncResult syncResult) {
   // If the account is hidden and the user enables syncing for it via system
   // then this could get called. Check account state and only sync
   // if not hidden.
   DeveloperAccount developerAccount =
       DeveloperAccountManager.getInstance(mContext).findDeveloperAccountByName(account.name);
   if (developerAccount != null && developerAccount.isVisible()) {
     try {
       SyncAdapterService.performSync(
           mContext, account, extras, authority, provider, syncResult);
     } catch (OperationCanceledException e) {
       Log.w(TAG, "operation canceled", e);
     }
   }
 }
  private static void performSync(
      Context context,
      Account account,
      Bundle extras,
      String authority,
      ContentProviderClient provider,
      SyncResult syncResult)
      throws OperationCanceledException {
    try {
      DevConsoleV2 console = DevConsoleRegistry.getInstance().get(account.name);

      if (console != null) {
        List<AppInfo> appDownloadInfos = console.getAppInfo(null);
        // this can also happen if authentication fails and the user
        // need to click on a notification to confirm or re-enter
        // password (e.g., if password changed or 2FA enabled)
        if (appDownloadInfos.isEmpty()) {
          return;
        }

        Log.d(TAG, "andlytics from sync adapter, size: " + appDownloadInfos.size());

        List<AppStatsDiff> diffs = new ArrayList<AppStatsDiff>();
        Map<String, List<String>> admobAccountSiteMap = new HashMap<String, List<String>>();

        db = ContentAdapter.getInstance(AndlyticsApp.getInstance());
        for (AppInfo appDownloadInfo : appDownloadInfos) {
          // update in database
          diffs.add(db.insertOrUpdateStats(appDownloadInfo));
          String[] admobDetails =
              AndlyticsDb.getInstance(context).getAdmobDetails(appDownloadInfo.getPackageName());
          if (admobDetails != null) {
            String admobAccount = admobDetails[0];
            String admobSiteId = admobDetails[1];
            if (admobAccount != null) {
              List<String> siteList = admobAccountSiteMap.get(admobAccount);
              if (siteList == null) {
                siteList = new ArrayList<String>();
              }
              siteList.add(admobSiteId);
              admobAccountSiteMap.put(admobAccount, siteList);
            }
          }
          // update app details
          AndlyticsDb.getInstance(context).insertOrUpdateAppDetails(appDownloadInfo);
        }
        Log.d(TAG, "sucessfully synced andlytics");

        // check for notifications
        NotificationHandler.handleNotificaions(context, diffs, account.name);

        if (!admobAccountSiteMap.isEmpty()) {
          Log.d(TAG, "Syncing AdMob stats");
          // sync admob accounts
          Set<String> admobAccuntKeySet = admobAccountSiteMap.keySet();
          for (String admobAccount : admobAccuntKeySet) {

            AdmobRequest.syncSiteStats(
                admobAccount, context, admobAccountSiteMap.get(admobAccount), null);
          }
          Log.d(TAG, "Sucessfully synced AdMob stats");
        }

        DeveloperAccountManager.getInstance(context)
            .saveLastStatsRemoteUpdateTime(account.name, System.currentTimeMillis());
      }
    } catch (DevConsoleException e) {
      Log.e(TAG, "error during sync", e);
    } catch (AdmobException e) {
      Log.e(TAG, "error during Admob sync", e);
    }
  }