001package com.gigya.android.sdk.providers.provider;
002
003import android.content.Context;
004import android.content.Intent;
005import android.os.AsyncTask;
006import android.os.Bundle;
007import android.support.annotation.Nullable;
008import android.support.v7.app.AppCompatActivity;
009
010import com.gigya.android.sdk.GigyaLogger;
011import com.gigya.android.sdk.api.IBusinessApiService;
012import com.gigya.android.sdk.persistence.IPersistenceService;
013import com.gigya.android.sdk.ui.HostActivity;
014import com.gigya.android.sdk.utils.FileUtils;
015import com.linecorp.linesdk.LineApiResponse;
016import com.linecorp.linesdk.Scope;
017import com.linecorp.linesdk.api.LineApiClient;
018import com.linecorp.linesdk.api.LineApiClientBuilder;
019import com.linecorp.linesdk.auth.LineAuthenticationParams;
020import com.linecorp.linesdk.auth.LineLoginApi;
021import com.linecorp.linesdk.auth.LineLoginResult;
022
023import org.json.JSONObject;
024
025import java.util.Arrays;
026import java.util.Map;
027
028import static com.gigya.android.sdk.GigyaDefinitions.Providers.LINE;
029
030public class LineProvider extends Provider {
031
032    private static final String LOG_TAG = "LineLoginProvider";
033
034    private static final int REQUEST_CODE = 1;
035
036    private FileUtils _fileUtils;
037
038    public LineProvider(Context context,
039                        IPersistenceService persistenceService,
040                        IBusinessApiService businessApiService,
041                        FileUtils fileUtils,
042                        ProviderCallback providerCallback) {
043        super(context, persistenceService, businessApiService, providerCallback);
044        _fileUtils = fileUtils;
045    }
046
047    @Override
048    public String getName() {
049        return LINE;
050    }
051
052    public static boolean isAvailable(FileUtils fileUtils) {
053        try {
054            String lineChannelID = fileUtils.stringFromMetaData("lineChannelID");
055            Class.forName("com.linecorp.linesdk.auth.LineLoginApi");
056            return lineChannelID != null;
057        } catch (Throwable t) {
058            return false;
059        }
060    }
061
062    @Override
063    public void login(final Map<String, Object> loginParams, final String loginMode) {
064        if (_connecting) {
065            return;
066        }
067        _connecting = true;
068        _loginMode = loginMode;
069        HostActivity.present(_context, new HostActivity.HostActivityLifecycleCallbacks() {
070            @Override
071            public void onCreate(AppCompatActivity activity, @Nullable Bundle savedInstanceState) {
072                // Fetch channel Id from meta-data.
073                final String lineChannelID = _fileUtils.stringFromMetaData("lineChannelID");
074                if (lineChannelID == null) {
075                    // Fail login.
076                    onLoginFailed("Channel Id not available");
077                    activity.finish();
078                    return;
079                }
080
081                Intent loginIntent = LineLoginApi.getLoginIntent(
082                        activity,
083                        lineChannelID,
084                        new LineAuthenticationParams.Builder()
085                                .scopes(Arrays.asList(Scope.PROFILE))
086                                .build());
087                activity.startActivityForResult(loginIntent, REQUEST_CODE);
088            }
089
090            @Override
091            public void onActivityResult(AppCompatActivity activity, int requestCode, int resultCode, @Nullable Intent data) {
092                if (requestCode == REQUEST_CODE) {
093                    LineLoginResult result = LineLoginApi.getLoginResultFromIntent(data);
094                    switch (result.getResponseCode()) {
095                        case SUCCESS:
096                            if (result.getLineCredential() == null) {
097                                // Fail login.
098                                return;
099                            }
100                            final String accessToken = result.getLineCredential().getAccessToken().getTokenString();
101                            onLoginSuccess(loginParams, getProviderSessions(accessToken, -1, null), loginMode);
102                            break;
103                        case CANCEL:
104                            onCanceled();
105                            break;
106                        default:
107                            // Any other is an error.
108                            onLoginFailed(result.getErrorData().getMessage());
109                            break;
110                    }
111                    activity.finish();
112                }
113            }
114        });
115    }
116
117    @Override
118    public void logout() {
119        super.logout();
120        final String lineChannelID = _fileUtils.stringFromMetaData("lineChannelID");
121        if (lineChannelID == null) {
122            return;
123        }
124        LineApiClientBuilder builder = new LineApiClientBuilder(_context, lineChannelID);
125        LineApiClient client = builder.build();
126        new LogoutTask(client).execute();
127    }
128
129    @Override
130    public String getProviderSessions(String tokenOrCode, long expiration, String uid) {
131        // Only token is relevant.
132        try {
133            return new JSONObject()
134                    .put(getName(), new JSONObject()
135                            .put("authToken", tokenOrCode)).toString();
136        } catch (Exception ex) {
137            _connecting = false;
138            ex.printStackTrace();
139        }
140        return null;
141    }
142
143    @Override
144    public boolean supportsTokenTracking() {
145        return false;
146    }
147
148    @Override
149    public void trackTokenChange() {
150        // Stub.
151    }
152
153    private static class LogoutTask extends AsyncTask<Void, Void, LineApiResponse> {
154
155        private LineApiClient _client;
156
157        LogoutTask(LineApiClient client) {
158            _client = client;
159        }
160
161        @Override
162        protected LineApiResponse doInBackground(Void... voids) {
163            return _client.logout();
164        }
165
166        @Override
167        protected void onPostExecute(LineApiResponse lineApiResponse) {
168            if (lineApiResponse.isSuccess()) {
169                /* Logout success. */
170                GigyaLogger.debug(LOG_TAG, "Line logout success");
171            } else {
172                /* Logout error. */
173                GigyaLogger.error(LOG_TAG, "Line logout error");
174            }
175            _client = null;
176        }
177    }
178}