com.linecorp.linesdk.auth.LineLoginResult Java Examples

The following examples show how to use com.linecorp.linesdk.auth.LineLoginResult. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LineAuthenticationController.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@MainThread
void handleIntentFromLineApp(@NonNull Intent intent) {
    authenticationStatus.authenticationIntentReceived();
    BrowserAuthenticationApi.Result authResult =
            browserAuthenticationApi.getAuthenticationResultFrom(intent);
    if (!authResult.isSuccess()) {
        authenticationStatus.authenticationIntentHandled();
        final LineLoginResult errorResult =
                authResult.isAuthenticationAgentError()
                ? LineLoginResult.authenticationAgentError(authResult.getLineApiError())
                : LineLoginResult.internalError(authResult.getLineApiError());
        activity.onAuthenticationFinished(errorResult);
        return;
    }
    new AccessTokenRequestTask().execute(authResult);
}
 
Example #2
Source File: LineAuthenticationController.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@MainThread
@Override
public void run() {
    if (authenticationStatus.getStatus() == LineAuthenticationStatus.Status.INTENT_RECEIVED
            || activity.isFinishing()) {
        return;
    }
    // before returning "cancel" result to app, check whether intent is already
    // returned from LINE app. If so, handle it.
    if (intentResultFromLineAPP != null) {
        handleIntentFromLineApp(intentResultFromLineAPP);
        intentResultFromLineAPP = null;
        return;
    }

    activity.onAuthenticationFinished(LineLoginResult.canceledError());
}
 
Example #3
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testInternalErrorOfGettingAccessToken() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsSuccess(REQUEST_TOKEN_STR, null))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);
    doReturn(LineApiResponse.createAsError(LineApiResponseCode.INTERNAL_ERROR, LineApiError.DEFAULT))
            .when(authApiClient)
            .issueAccessToken(CHANNEL_ID, REQUEST_TOKEN_STR, PKCE_CODE, REDIRECT_URI);

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.handleIntentFromLineApp(newIntentData);

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(
            LineLoginResult.error(LineApiResponseCode.INTERNAL_ERROR, LineApiError.DEFAULT));
}
 
Example #4
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testNetworkErrorOfGettingAccessToken() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsSuccess(REQUEST_TOKEN_STR, false))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);
    doReturn(LineApiResponse.createAsError(LineApiResponseCode.NETWORK_ERROR, LineApiError.DEFAULT))
            .when(authApiClient)
            .issueAccessToken(CHANNEL_ID, REQUEST_TOKEN_STR, PKCE_CODE, REDIRECT_URI);

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.handleIntentFromLineApp(newIntentData);

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(
            LineLoginResult.error(LineApiResponseCode.NETWORK_ERROR, LineApiError.DEFAULT));
}
 
Example #5
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@Test
public void testErrorOfRequestTokenProvider() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsInternalError("internalErrorMessage"))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.handleIntentFromLineApp(newIntentData);

    verify(activity, times(1)).onAuthenticationFinished(
            LineLoginResult.error(LineApiResponseCode.INTERNAL_ERROR, any()));
}
 
Example #6
Source File: LoginHandler.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
boolean onActivityResult(int requestCode, int resultCode, Intent data) {
    if (!isLoginRequestCode(requestCode)) {
        Log.w(TAG, "Unexpected login request code");
        return false;
    }

    if (isLoginCanceled(resultCode, data)) {
        Log.w(TAG, "Login failed");
        return false;
    }

    LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);
    if (isLoginSuccess(result)) {
        onLoginSuccess(result);
    } else {
        onLoginFailure(result);
    }
    return true;
}
 
Example #7
Source File: LineAuthenticationActivity.java    From line-sdk-android with Apache License 2.0 6 votes vote down vote up
@MainThread
void onAuthenticationFinished(@NonNull LineLoginResult lineLoginResult) {
    // During LINE app agreement screen pops up, if user presses home and goes back to app (integrating loginsdk),
    // onAuthenticationFinished will be called with CANCEL status.
    // If user goes to LINE app again, and interact with agreement, it will bring user back to here again,
    // but authenticationStatus is already gone. In this case, we should just ignore the result,
    // and finish the Activity
    if(authenticationStatus == null) {
        finish();
        return;
    }

    // STARTED: no intent comes back. if the activity is not stopped, need to finish the authentication activity
    // INTENT_HANDLED: the intent is back and handled, need to finish the activity with result
    if((authenticationStatus.getStatus() == STARTED && !isActivityStopped) ||
               authenticationStatus.getStatus() == INTENT_HANDLED) {
        Intent resultData = new Intent();
        resultData.putExtra(RESPONSE_DATA_KEY_AUTHENTICATION_RESULT, lineLoginResult);
        setResult(Activity.RESULT_OK, resultData);
        finish();
    }
}
 
Example #8
Source File: MainActivity.java    From line-sdk-starter-android-v2 with MIT License 5 votes vote down vote up
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode != REQUEST_CODE) {
        Log.e("ERROR", "Unsupported Request");
        return;
    }

    LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);

    switch (result.getResponseCode()) {

        case SUCCESS:

            Intent transitionIntent = new Intent(this, PostLoginActivity.class);
            transitionIntent.putExtra("line_profile", result.getLineProfile());
            transitionIntent.putExtra("line_credential", result.getLineCredential());
            startActivity(transitionIntent);
            break;

        case CANCEL:
            Log.e("ERROR", "LINE Login Canceled by user!!");
            break;

        default:
            Log.e("ERROR", "Login FAILED!");
            Log.e("ERROR", result.getErrorData().toString());
    }
}
 
Example #9
Source File: LineSDKUITestingActivity.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode != REQUEST_CODE_LINE_SIGN_IN) { return; }

    LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);
    Log.i("LineSDKUITesting", result.toString());

    if (activityActionDelegate != null) {
        activityActionDelegate.onActivityResult(requestCode, resultCode, data);
    }
}
 
Example #10
Source File: LineLogin.java    From cordova-line-login-plugin with Apache License 2.0 5 votes vote down vote up
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode != REQUEST_CODE) {
        return;
    }

    LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);
    if (result.getResponseCode() == LineApiResponseCode.SUCCESS) {
        JSONObject json = new JSONObject();
        try {
            LineProfile profile = result.getLineProfile();
            json.put("userID", profile.getUserId());
            json.put("displayName", profile.getDisplayName());
            if (profile.getPictureUrl() != null) {
                json.put("pictureURL", profile.getPictureUrl().toString());
            }

            LineIdToken lineIdToken = result.getLineIdToken();
            json.put("email", lineIdToken.getEmail());

            callbackContext.success(json);
        } catch (JSONException e) {
            this.UnknownError(e.toString());
        }
    } else if (result.getResponseCode() == LineApiResponseCode.CANCEL) {
        this.SDKError(result.getResponseCode().toString(), "user cancel");
    } else {
        this.SDKError(result.getResponseCode().toString(), result.toString());
    }
}
 
Example #11
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@Test
public void testInternalErrorOfGettingAccountInfo() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsSuccess(REQUEST_TOKEN_STR, null))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);
    doReturn(LineApiResponse.createAsSuccess(ISSUE_ACCESS_TOKEN_RESULT))
            .when(authApiClient)
            .issueAccessToken(CHANNEL_ID, REQUEST_TOKEN_STR, PKCE_CODE, REDIRECT_URI);
    doReturn(LineApiResponse.createAsError(LineApiResponseCode.INTERNAL_ERROR, LineApiError.DEFAULT))
            .when(talkApiClient)
            .getProfile(ACCESS_TOKEN);

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.handleIntentFromLineApp(newIntentData);

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(
            LineLoginResult.error(LineApiResponseCode.INTERNAL_ERROR, LineApiError.DEFAULT));
}
 
Example #12
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@Test
public void testNetworkErrorOfGettingAccountInfo() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsSuccess(REQUEST_TOKEN_STR, null))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);
    doReturn(LineApiResponse.createAsSuccess(ISSUE_ACCESS_TOKEN_RESULT))
            .when(authApiClient)
            .issueAccessToken(CHANNEL_ID, REQUEST_TOKEN_STR, PKCE_CODE, REDIRECT_URI);
    doReturn(LineApiResponse.createAsError(LineApiResponseCode.NETWORK_ERROR, LineApiError.DEFAULT))
            .when(talkApiClient)
            .getProfile(ACCESS_TOKEN);

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.handleIntentFromLineApp(newIntentData);

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(
            LineLoginResult.error(LineApiResponseCode.NETWORK_ERROR, LineApiError.DEFAULT));
}
 
Example #13
Source File: LineAuthenticationActivity.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.linesdk_activity_lineauthentication);

    Intent intent = getIntent();

    // When launched from LINE app, LineAuthenticationActivity will be created twice.
    // The result should be kept so that it can be processed in correct Controller
    Uri uri = intent.getData();
    if(uri != null && uri.getScheme().equals(SUPPORTED_SCHEME)) {
        LineAuthenticationController.setIntent(intent);
        finish();
        return;
    }

    LineAuthenticationConfig config =
            intent.getParcelableExtra(PARAM_KEY_AUTHENTICATION_CONFIG);
    LineAuthenticationParams params =
            intent.getParcelableExtra(PARAM_KEY_AUTHENTICATION_PARAMS);
    if (config == null || params == null) {
        onAuthenticationFinished(
                LineLoginResult.internalError("The requested parameter is illegal.")
        );
        return;
    }
    authenticationStatus = getAuthenticationStatus(savedInstanceState);
    authenticationController = new LineAuthenticationController(
            this,
            config,
            authenticationStatus,
            params);
}
 
Example #14
Source File: LineAuthenticationActivity.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@NonNull
public static LineLoginResult getResultFromIntent(@NonNull Intent intent) {
    LineLoginResult lineLoginResult =
            intent.getParcelableExtra(RESPONSE_DATA_KEY_AUTHENTICATION_RESULT);
    return lineLoginResult == null
           ? LineLoginResult.internalError("Authentication result is not found.")
           : lineLoginResult;
}
 
Example #15
Source File: LineAuthenticationController.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@MainThread
void startLineAuthentication() {
    authenticationStatus.authenticationStarted();

    final PKCECode pkceCode = createPKCECode();
    authenticationStatus.setPKCECode(pkceCode);
    try {
        BrowserAuthenticationApi.Request request = browserAuthenticationApi
                .getRequest(activity, config, pkceCode, params);
        if (request.isLineAppAuthentication()) {
            // "launchMode" of the activity launched by the follows is "singleInstance".
            // So, we must not use startActivityForResult.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                activity.startActivity(
                        request.getIntent(),
                        request.getStartActivityOptions());
            } else {
                activity.startActivity(request.getIntent());
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                activity.startActivityForResult(
                        request.getIntent(),
                        REQUEST_CODE,
                        request.getStartActivityOptions());
            } else {
                activity.startActivityForResult(
                        request.getIntent(),
                        REQUEST_CODE);
            }
        }
        authenticationStatus.setSentRedirectUri(request.getRedirectUri());
    } catch (ActivityNotFoundException e) {
        authenticationStatus.authenticationIntentHandled();
        activity.onAuthenticationFinished(LineLoginResult.internalError(e));
    }
}
 
Example #16
Source File: SignInFragment.java    From line-sdk-android with Apache License 2.0 5 votes vote down vote up
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == Activity.RESULT_OK) {
        LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);
        addLog("===== Login result =====");
        addLog(result.toString());
        addLog("==========================");
    } else {
        addLog("Illegal response : onActivityResult("
                + requestCode + ", " + resultCode + ", " + data + ")");
    }
}
 
Example #17
Source File: LoginHandler.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
private boolean isLoginSuccess(@Nullable LineLoginResult result) {
    return result != null && result.getResponseCode() == LineApiResponseCode.SUCCESS;
}
 
Example #18
Source File: LoginHandler.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
private void onLoginFailure(@Nullable LineLoginResult result) {
    for (LoginListener loginListener : loginListeners) {
        loginListener.onLoginFailure(result);
    }
}
 
Example #19
Source File: LoginHandler.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
private void onLoginSuccess(LineLoginResult result) {
    for (LoginListener loginListener : loginListeners) {
        loginListener.onLoginSuccess(result);
    }
}
 
Example #20
Source File: LineAuthenticationController.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
@Override
protected void onPostExecute(@NonNull LineLoginResult lineLoginResult) {
    authenticationStatus.authenticationIntentHandled();
    activity.onAuthenticationFinished(lineLoginResult);
}
 
Example #21
Source File: LineAuthenticationController.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
@Override
protected LineLoginResult doInBackground(@Nullable BrowserAuthenticationApi.Result... params) {
    BrowserAuthenticationApi.Result authResult = params[0];
    String requestToken = authResult.getRequestToken();
    PKCECode pkceCode = authenticationStatus.getPKCECode();
    String sentRedirectUri = authenticationStatus.getSentRedirectUri();
    if (TextUtils.isEmpty(requestToken)
            || pkceCode == null
            || TextUtils.isEmpty(sentRedirectUri)) {
        return LineLoginResult.internalError("Requested data is missing.");
    }

    // Acquire access token
    LineApiResponse<IssueAccessTokenResult> accessTokenResponse =
            authApiClient.issueAccessToken(
                    config.getChannelId(), requestToken, pkceCode, sentRedirectUri);
    if (!accessTokenResponse.isSuccess()) {
        return LineLoginResult.error(accessTokenResponse);
    }

    IssueAccessTokenResult issueAccessTokenResult = accessTokenResponse.getResponseData();
    InternalAccessToken accessToken = issueAccessTokenResult.getAccessToken();
    List<Scope> scopes = issueAccessTokenResult.getScopes();

    LineProfile lineProfile = null;
    String userId = null;
    if (scopes.contains(Scope.PROFILE)) {
        // Acquire account information
        LineApiResponse<LineProfile> profileResponse = talkApiClient.getProfile(accessToken);
        if (!profileResponse.isSuccess()) {
            return LineLoginResult.error(profileResponse);
        }
        lineProfile = profileResponse.getResponseData();
        userId = lineProfile.getUserId();
    }

    // Cache the acquired access token
    accessTokenCache.saveAccessToken(accessToken);

    final LineIdToken idToken = issueAccessTokenResult.getIdToken();
    if (idToken != null) {
        try {
            validateIdToken(idToken, userId);
        } catch (final Exception e) {
            return LineLoginResult.internalError(e.getMessage());
        }
    }

    return new LineLoginResult.Builder()
            .nonce(authenticationStatus.getOpenIdNonce())
            .lineProfile(lineProfile)
            .lineIdToken(idToken)
            .friendshipStatusChanged(authResult.getFriendshipStatusChanged())
            .lineCredential(new LineCredential(
                    new LineAccessToken(
                            accessToken.getAccessToken(),
                            accessToken.getExpiresInMillis(),
                            accessToken.getIssuedClientTimeMillis()),
                    scopes
            ))
            .build();
}
 
Example #22
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
@Test
public void testSuccess() throws Exception {
    Intent newIntentData = new Intent();
    doReturn(BrowserAuthenticationApi.Result.createAsSuccess(REQUEST_TOKEN_STR, null))
            .when(browserAuthenticationApi)
            .getAuthenticationResultFrom(newIntentData);
    doReturn(LineApiResponse.createAsSuccess(ISSUE_ACCESS_TOKEN_RESULT))
            .when(authApiClient)
            .issueAccessToken(CHANNEL_ID, REQUEST_TOKEN_STR, PKCE_CODE, REDIRECT_URI);
    doReturn(LineApiResponse.createAsSuccess(ACCOUNT_INFO))
            .when(talkApiClient)
            .getProfile(ACCESS_TOKEN);
    doReturn(LineApiResponse.createAsSuccess(OPEN_ID_DISCOVERY_DOCUMENT))
            .when(authApiClient)
            .getOpenIdDiscoveryDocument();

    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.onActivityResult(3 /* requestCode */, 0 /* resultCode */, null /* data */);
    target.handleIntentFromLineApp(newIntentData);

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(
            new LineLoginResult.Builder()
                    .responseCode(LineApiResponseCode.SUCCESS)
                    .nonce(NONCE)
                    .lineProfile(new LineProfile(USER_ID, DISPLAY_NAME, PICTURE_URL, STATUS_MESSAGE))
                    .lineIdToken(ID_TOKEN)
                    .friendshipStatusChanged(null)
                    .lineCredential(new LineCredential(
                            new LineAccessToken(ACCESS_TOKEN_STR, EXPIRES_IN, ISSUED_CLIENT_TIME),
                            SCOPE_LIST))
                    .errorData(LineApiError.DEFAULT)
                    .build()
    );

    assertEquals(ACCESS_TOKEN, accessTokenCache.getAccessToken());
}
 
Example #23
Source File: LineAuthenticationControllerTest.java    From line-sdk-android with Apache License 2.0 4 votes vote down vote up
@Test
public void testCancel() throws Exception {
    target.startLineAuthentication();

    Robolectric.getBackgroundThreadScheduler().runOneTask();
    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(browserAuthenticationApi, times(1))
            .getRequest(activity, config, PKCE_CODE, LINE_AUTH_PARAMS);

    target.onActivityResult(3 /* requestCode */, 0 /* resultCode */, null /* data */);

    verify(activity, never()).onAuthenticationFinished(any(LineLoginResult.class));

    Robolectric.getForegroundThreadScheduler().runOneTask();

    verify(activity, times(1)).onAuthenticationFinished(LineLoginResult.canceledError());
}
 
Example #24
Source File: LoginListener.java    From line-sdk-android with Apache License 2.0 2 votes vote down vote up
/**
 * Called by {@link com.linecorp.linesdk.internal.LoginHandler} if the login fails.
 *
 * @param result The login result for a failed login. It contains error information that can be used to diagnose the failure. <code>Null</code> if
 *               the login is cancelled.
 * */
void onLoginFailure(@Nullable LineLoginResult result);
 
Example #25
Source File: LoginListener.java    From line-sdk-android with Apache License 2.0 2 votes vote down vote up
/**
 * Called by {@link com.linecorp.linesdk.internal.LoginHandler} if the login succeeds.
 *
 * @param result The login result for a successful login. It contains information about the login.
 * */
void onLoginSuccess(@NonNull LineLoginResult result);