class SyncAsyncTask extends MessengerAsyncTask<Void, Void, Void> { private static final String TAG_TIME = App.newSubTag(App.TAG_TIME, "Async"); @Nonnull private final List<SyncTask> syncTasks; public SyncAsyncTask(@Nonnull List<SyncTask> syncTasks) { super(true); this.syncTasks = syncTasks; } @Override protected Void doWork(@Nonnull List<Void> voids) { for (Account account : getAccountService().getEnabledAccounts()) { final SyncData syncData = new SyncDataImpl(account.getId()); for (SyncTask syncTask : syncTasks) { final long start = currentTimeMillis(); syncTask.doTask(syncData); final long end = currentTimeMillis(); final long duration = end - start; if (duration > 1000) { Log.e( TAG_TIME, "Work time is too long for account: " + account + " and task: " + syncTask + ". Time: " + duration + "ms"); } } } return null; } @Override protected void onSuccessPostExecute(@Nullable Void result) {} @Override public String toString() { return "SyncAsyncTask{" + "syncTasks=" + syncTasks + '}'; } }
@Singleton public class VkRealm extends AbstractRealm<VkAccountConfiguration> { /* ********************************************************************** * * CONSTANTS * ********************************************************************** */ @Nonnull private static final String REALM_ID = "vk"; @Nonnull public static final String TAG = App.newTag("VK"); /* ********************************************************************** * * AUTO INJECTED FIELDS * ********************************************************************** */ @Inject @Nonnull private Application context; @Inject @Nonnull private ImageLoader imageLoader; @Inject @Nonnull private NotificationService notificationService; /* ********************************************************************** * * FIELDS * ********************************************************************** */ @Nonnull private final HttpRealmIconService.UrlGetter iconUrlGetter = new VkIconUrlGetter(); @Nonnull private final HttpRealmIconService.UrlGetter photoUrlGetter = new VkPhotoUrlGetter(); /*@Nonnull*/ private volatile HttpRealmIconService iconService; /* ********************************************************************** * * CONSTRUCTORS * ********************************************************************** */ public VkRealm() { super( REALM_ID, R.string.mpp_vk_realm_name, R.drawable.mpp_vk_icon, VkAccountConfigurationFragment.class, VkAccountConfiguration.class, true, null, true); } /* ********************************************************************** * * METHODS * ********************************************************************** */ @Nonnull @Override public Account<VkAccountConfiguration> newAccount( @Nonnull String accountId, @Nonnull User user, @Nonnull VkAccountConfiguration configuration, @Nonnull AccountState state, @Nonnull AccountSyncData syncData) { return new VkAccount(accountId, this, user, configuration, state, syncData); } @Nonnull @Override public AccountBuilder newAccountBuilder( @Nonnull VkAccountConfiguration configuration, @Nullable Account editedAccount) { return new VkAccountBuilder(this, (VkAccount) editedAccount, configuration); } @Nonnull @Override public List<AProperty> getUserDisplayProperties(@Nonnull User user, @Nonnull Context context) { final List<AProperty> result = super.getUserDisplayProperties(user, context); final String bdate = user.getPropertyValueByName("bdate"); if (!isEmpty(bdate)) { final String birthDate = formatBirthDate(bdate); if (birthDate != null) { result.add(newProperty(context.getString(R.string.mpp_birth_date), birthDate)); } } return result; } @Nullable private String formatBirthDate(@Nonnull String value) { int dateParts = 1; for (int i = 0; i < value.length(); i++) { if (value.charAt(i) == '.') { dateParts++; } } if (dateParts > 1) { final SimpleDateFormat dt; if (dateParts > 2) { dt = new SimpleDateFormat("dd.MM.yyyy"); } else { dt = new SimpleDateFormat("dd.MM"); } try { final DateFormat df; if (dateParts > 2) { df = SimpleDateFormat.getDateInstance(); } else { df = new SimpleDateFormat("dd.MM"); } return df.format(dt.parse(value)); } catch (ParseException e) { return null; } } else { return null; } } @Override public void init(@Nonnull Context context) { super.init(context); } @Nonnull @Override public synchronized RealmIconService getRealmIconService() { if (iconService == null) { iconService = new HttpRealmIconService( context, imageLoader, R.drawable.mpp_icon_user, R.drawable.mpp_icon_users, iconUrlGetter, photoUrlGetter); } return iconService; } @Nullable @Override public Cipherer<VkAccountConfiguration, VkAccountConfiguration> getCipherer() { return new VkRealmConfigurationCipherer( App.getSecurityService().getStringSecurityService().getCipherer()); } @Override public boolean handleException(@Nonnull Throwable e, @Nonnull Account account) { boolean handled = super.handleException(e, account); if (!handled) { if (e instanceof VkResponseErrorException) { final VkResponseErrorException cause = (VkResponseErrorException) e; if ("5".equals(cause.getError().getErrorId())) { notificationService.add( newNotification(R.string.mpp_vk_notification_auth_token_expired, MessageType.error) .solvedBy(newOpenAccountConfSolution(account))); } else { notificationService.add(newVkNotification(cause)); } handled = true; } } return handled; } @Nonnull private static Notification newVkNotification(@Nonnull VkResponseErrorException e) { return Notifications.newNotification( R.string.mpp_vk_notification_error, MessageType.error, e.getError().getErrorDescription()) .causedBy(e); } @Override public boolean isHtmlMessage() { return true; } /* ********************************************************************** * * STATIC * ********************************************************************** */ private static final class VkPhotoUrlGetter implements HttpRealmIconService.UrlGetter { @Nullable @Override public String getUrl(@Nonnull User user) { String result = user.getPropertyValueByName("photoRec"); if (result == null) { result = user.getPropertyValueByName("photoBig"); } if (result == null) { result = user.getPropertyValueByName("photo"); } return result; } } private static final class VkIconUrlGetter implements HttpRealmIconService.UrlGetter { @Nullable @Override public String getUrl(@Nonnull User user) { String result = user.getPropertyValueByName("photo"); if (result == null) { result = user.getPropertyValueByName("photoRec"); } if (result == null) { result = user.getPropertyValueByName("photoBig"); } return result; } } private static class VkRealmConfigurationCipherer implements Cipherer<VkAccountConfiguration, VkAccountConfiguration> { @Nonnull private final Cipherer<String, String> stringCipherer; private VkRealmConfigurationCipherer(@Nonnull Cipherer<String, String> stringCipherer) { this.stringCipherer = stringCipherer; } @Nonnull public VkAccountConfiguration encrypt( @Nonnull SecretKey secret, @Nonnull VkAccountConfiguration decrypted) throws CiphererException { final VkAccountConfiguration encrypted = decrypted.clone(); encrypted.setAccessParameters( stringCipherer.encrypt(secret, decrypted.getAccessToken()), decrypted.getUserId()); return encrypted; } @Nonnull public VkAccountConfiguration decrypt( @Nonnull SecretKey secret, @Nonnull VkAccountConfiguration encrypted) throws CiphererException { final VkAccountConfiguration decrypted = encrypted.clone(); decrypted.setAccessParameters( stringCipherer.decrypt(secret, encrypted.getAccessToken()), encrypted.getUserId()); return decrypted; } } private static class AuthTokenExpiredSolver implements Runnable { @Override public void run() {} } }
@Override public Account call() throws InvalidCredentialsException, AccountAlreadyExistsException { return App.getAccountService().saveAccount(accountBuilder); }
@Nullable @Override public Cipherer<VkAccountConfiguration, VkAccountConfiguration> getCipherer() { return new VkRealmConfigurationCipherer( App.getSecurityService().getStringSecurityService().getCipherer()); }