Use WorkManager in the create account flow

This commit is contained in:
Alex Crown 2019-01-09 16:52:18 -08:00
Родитель e74243ad5b
Коммит 6424978a23
6 изменённых файлов: 78 добавлений и 66 удалений

Просмотреть файл

@ -23,12 +23,6 @@ public final class ActionsLauncher {
private ActionsLauncher() {
}
public static Action createAccount(Context context, CreateAccountData createAccountData) {
return ActionIntentBuilder.forActionWithTag(Action.Tags.CREATE_ACCOUNT)
.setCreateAccountData(createAccountData)
.launch(context, ServiceAction.CREATE_ACCOUNT);
}
public static Action updateAccount(Context context, AccountDataDifference difference) {
return ActionIntentBuilder.forActionWithTag(Action.Tags.UPDATE_ACCOUNT)
.setAccountDataDifference(difference)

Просмотреть файл

@ -11,14 +11,18 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
/**
* Information needed to create an account.
*/
public class CreateAccountData implements Parcelable {
public class CreateAccountData implements Parcelable, Serializable {
private static final long serialVersionUID = 6172725706417779546L;
private String firstName;
private String lastName;
private String bio;
private Uri photoUri;
private String photoUri;
private IdentityProvider identityProvider;
private String thirdPartyAccessToken;
private String thirdPartyRequestToken;
@ -50,11 +54,11 @@ public class CreateAccountData implements Parcelable {
}
public Uri getPhotoUri() {
return photoUri;
return Uri.parse(photoUri);
}
public void setPhotoUri(Uri photoUri) {
this.photoUri = photoUri;
this.photoUri = photoUri.toString();
}
public IdentityProvider getIdentityProvider() {
@ -101,7 +105,7 @@ public class CreateAccountData implements Parcelable {
dest.writeString(this.firstName);
dest.writeString(this.lastName);
dest.writeString(this.bio);
dest.writeParcelable(this.photoUri, 0);
dest.writeString(this.photoUri);
dest.writeString(this.identityProvider.toValue());
dest.writeString(this.thirdPartyAccessToken);
dest.writeString(this.thirdPartyRequestToken);

Просмотреть файл

@ -7,7 +7,6 @@ package com.microsoft.embeddedsocial.service;
import com.microsoft.embeddedsocial.base.service.IServiceIntentProcessor;
import com.microsoft.embeddedsocial.base.service.IntentProcessor;
import com.microsoft.embeddedsocial.service.handler.CreateAccountHandler;
import com.microsoft.embeddedsocial.service.handler.LinkUserThirdPartyAccountHandler;
import com.microsoft.embeddedsocial.service.handler.UnlinkUserThirdPartyAccountHandler;
import com.microsoft.embeddedsocial.service.handler.UpdateAccountHandler;
@ -31,7 +30,6 @@ public class IntentProcessorFactory {
IServiceIntentProcessor createIntentProcessor() {
IntentProcessor<ServiceAction> processor = new IntentProcessor<>(context, ServiceAction.class, WORKER_THREADS);
processor.registerIntentHandler(ServiceAction.CREATE_ACCOUNT, new CreateAccountHandler(context));
processor.registerIntentHandler(ServiceAction.UPDATE_ACCOUNT, new UpdateAccountHandler(context));
processor.registerIntentHandler(ServiceAction.UPDATE_NOTIFICATION_COUNT, new UpdateNotificationCountHandler());
processor.registerIntentHandler(ServiceAction.LINK_USER_THIRD_PARTY_ACCOUNT, new LinkUserThirdPartyAccountHandler());

Просмотреть файл

@ -10,8 +10,6 @@ package com.microsoft.embeddedsocial.service;
*/
public enum ServiceAction {
CREATE_ACCOUNT,
UPDATE_ACCOUNT,
UPDATE_NOTIFICATION_COUNT,

Просмотреть файл

@ -3,10 +3,9 @@
* Licensed under the MIT License. See LICENSE in the project root for license information.
*/
package com.microsoft.embeddedsocial.service.handler;
package com.microsoft.embeddedsocial.service.worker;
import com.microsoft.embeddedsocial.account.UserAccount;
import com.microsoft.embeddedsocial.actions.Action;
import com.microsoft.embeddedsocial.actions.ActionsLauncher;
import com.microsoft.embeddedsocial.base.GlobalObjectRegistry;
import com.microsoft.embeddedsocial.base.utils.debug.DebugLog;
@ -16,91 +15,92 @@ import com.microsoft.embeddedsocial.data.model.CreateAccountData;
import com.microsoft.embeddedsocial.sdk.R;
import com.microsoft.embeddedsocial.server.EmbeddedSocialServiceProvider;
import com.microsoft.embeddedsocial.server.IAccountService;
import com.microsoft.embeddedsocial.server.IAuthenticationService;
import com.microsoft.embeddedsocial.server.exception.NetworkRequestException;
import com.microsoft.embeddedsocial.server.model.UserRequest;
import com.microsoft.embeddedsocial.server.model.account.CreateUserRequest;
import com.microsoft.embeddedsocial.server.model.account.GetUserAccountRequest;
import com.microsoft.embeddedsocial.server.model.account.GetUserAccountResponse;
import com.microsoft.embeddedsocial.server.model.auth.AuthenticationResponse;
import com.microsoft.embeddedsocial.service.IntentExtras;
import com.microsoft.embeddedsocial.service.ServiceAction;
import com.microsoft.embeddedsocial.service.worker.GetFcmIdWorker;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
/**
* Sends a create account request to the server.
*/
public class CreateAccountHandler extends ActionHandler {
public class CreateAccountWorker extends Worker {
public static final String CREATE_ACCOUNT_DATA = "createAccountData";
private final Context context;
private final IAccountService accountService = GlobalObjectRegistry
.getObject(EmbeddedSocialServiceProvider.class)
.getAccountService();
private final IAuthenticationService authenticationService = GlobalObjectRegistry
.getObject(EmbeddedSocialServiceProvider.class)
.getAuthenticationService();
private final Context context;
public CreateAccountHandler(Context context) {
public CreateAccountWorker(Context context, WorkerParameters workerParameters) {
super(context, workerParameters);
this.context = context;
}
@Override
protected void handleAction(Action action, ServiceAction serviceAction, Intent intent) {
Bundle extras = intent.getExtras();
CreateAccountData createAccountData = extras.getParcelable(IntentExtras.CREATE_ACCOUNT_DATA);
public Result doWork() {
String serializedAccountData = getInputData().getString(CREATE_ACCOUNT_DATA);
if (serializedAccountData == null) {
return Result.failure();
}
InputStream inputStream = new ByteArrayInputStream(
Base64.decode(serializedAccountData, Base64.DEFAULT));
CreateUserRequest createUserRequest = new CreateUserRequest.Builder()
.setFirstName(createAccountData.getFirstName())
.setLastName(createAccountData.getLastName())
.setBio(createAccountData.getBio())
.setIdentityProvider(createAccountData.getIdentityProvider())
.setAccessToken(createAccountData.getThirdPartyAccessToken())
.setRequestToken(createAccountData.getThirdPartyRequestToken())
.build();
try {
AuthenticationResponse createUserResponse = accountService.createUser(createUserRequest);
handleSuccessfulResult(action, createUserResponse);
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
CreateAccountData createAccountData = (CreateAccountData) objectInputStream.readObject();
CreateUserRequest createUserRequest = new CreateUserRequest.Builder()
.setFirstName(createAccountData.getFirstName())
.setLastName(createAccountData.getLastName())
.setBio(createAccountData.getBio())
.setIdentityProvider(createAccountData.getIdentityProvider())
.setAccessToken(createAccountData.getThirdPartyAccessToken())
.setRequestToken(createAccountData.getThirdPartyRequestToken())
.build();
AuthenticationResponse createUserResponse = accountService.createUser(createUserRequest);
handleSuccessfulResult(createUserResponse);
uploadPhoto(createAccountData.getPhotoUri());
} catch (IOException | NetworkRequestException e) {
} catch (ClassNotFoundException|IOException|NetworkRequestException e) {
DebugLog.logException(e);
UserAccount.getInstance().onCreateUserFailed();
action.fail();
return Result.failure();
}
return Result.success();
}
private void handleSuccessfulResult(Action action, AuthenticationResponse response)
throws NetworkRequestException {
private void handleSuccessfulResult(AuthenticationResponse response) throws NetworkRequestException {
String userHandle = response.getUserHandle();
String sessionToken = UserRequest.createSessionAuthorization(response.getSessionToken());
GetUserAccountRequest getUserRequest = new GetUserAccountRequest(sessionToken);
GetUserAccountResponse userAccount = accountService.getUserAccount(getUserRequest);
AccountData accountData = AccountData.fromServerResponse(userAccount.getUser());
if (!action.isCompleted()) {
int messageId = R.string.es_msg_general_create_user_success;
UserAccount.getInstance().onSignedIn(userHandle, sessionToken, accountData, messageId);
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(GetFcmIdWorker.class).build();
WorkManager.getInstance().enqueue(workRequest);
}
int messageId = R.string.es_msg_general_create_user_success;
UserAccount.getInstance().onSignedIn(userHandle, sessionToken, accountData, messageId);
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(GetFcmIdWorker.class).build();
WorkManager.getInstance().enqueue(workRequest);
}
/**
* Uploads the profile photo
*/
private void uploadPhoto(Uri photoUri) throws IOException, NetworkRequestException {
private void uploadPhoto(Uri photoUri) {
// TODO this is a separate call which could fail and leave the wrong public access
if (photoUri != null) {
AccountDataDifference difference = new AccountDataDifference();
@ -108,9 +108,4 @@ public class CreateAccountHandler extends ActionHandler {
ActionsLauncher.updateAccount(context, difference);
}
}
@Override
public void dispose() {
}
}

Просмотреть файл

@ -7,10 +7,10 @@ package com.microsoft.embeddedsocial.ui.fragment;
import com.microsoft.embeddedsocial.account.UserAccount;
import com.microsoft.embeddedsocial.actions.Action;
import com.microsoft.embeddedsocial.actions.ActionsLauncher;
import com.microsoft.embeddedsocial.actions.OngoingActions;
import com.microsoft.embeddedsocial.base.utils.BitmapUtils;
import com.microsoft.embeddedsocial.base.utils.ViewUtils;
import com.microsoft.embeddedsocial.base.utils.debug.DebugLog;
import com.microsoft.embeddedsocial.data.model.AccountData;
import com.microsoft.embeddedsocial.data.model.CreateAccountData;
import com.microsoft.embeddedsocial.event.signin.CreateUserFailedEvent;
@ -22,6 +22,7 @@ import com.microsoft.embeddedsocial.image.ImageViewContentLoader;
import com.microsoft.embeddedsocial.image.UserPhotoLoader;
import com.microsoft.embeddedsocial.sdk.R;
import com.microsoft.embeddedsocial.service.IntentExtras;
import com.microsoft.embeddedsocial.service.worker.CreateAccountWorker;
import com.microsoft.embeddedsocial.ui.fragment.base.BaseFragmentWithProgress;
import com.microsoft.embeddedsocial.ui.fragment.module.PhotoProviderModule;
import com.microsoft.embeddedsocial.ui.theme.ThemeAttributes;
@ -39,10 +40,16 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import androidx.annotation.Nullable;
import androidx.work.Data;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
/**
* Fragment to create profile.
@ -125,7 +132,23 @@ public class CreateProfileFragment extends BaseFragmentWithProgress {
.build();
thirdPartyAccount.clearTokens();
ActionsLauncher.createAccount(getContext(), createAccountData);
String serializedData = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(createAccountData);
serializedData = android.util.Base64.encodeToString(bos.toByteArray(), android.util.Base64.DEFAULT);
os.close();
} catch (IOException e) {
DebugLog.logException(e);
}
Data inputData = new Data.Builder()
.putString(CreateAccountWorker.CREATE_ACCOUNT_DATA, serializedData).build();
OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(CreateAccountWorker.class)
.setInputData(inputData).build();
WorkManager.getInstance().enqueue(workRequest);
}
}