/*
* Copyright 2011 Azwan Adli Abdullah
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gh4a.activities;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.design.widget.AppBarLayout;
import android.support.v4.util.Pair;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import com.gh4a.BackgroundTask;
import com.gh4a.BaseActivity;
import com.gh4a.BuildConfig;
import com.gh4a.DefaultClient;
import com.gh4a.Gh4Application;
import com.gh4a.R;
import com.gh4a.utils.IntentUtils;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.service.UserService;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* The Github4Android activity.
*/
public class Github4AndroidActivity extends BaseActivity implements View.OnClickListener {
private static final String OAUTH_URL = "https://github.com/login/oauth/authorize";
private static final String TOKEN_URL = "https://github.com/login/oauth/access_token";
private static final String PARAM_CLIENT_ID = "client_id";
private static final String PARAM_CLIENT_SECRET = "client_secret";
private static final String PARAM_CODE = "code";
private static final String PARAM_SCOPE = "scope";
private static final String PARAM_CALLBACK_URI = "redirect_uri";
private static final Uri CALLBACK_URI = Uri.parse("gh4a://oauth");
private static final String SCOPES = "user,repo,gist";
private static final int REQUEST_SETTINGS = 10000;
private View mContent;
private View mProgress;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Gh4Application app = Gh4Application.get();
if (app.isAuthorized()) {
if (!handleIntent(getIntent())) {
goToToplevelActivity();
}
finish();
} else {
setContentView(R.layout.main);
AppBarLayout abl = (AppBarLayout) findViewById(R.id.header);
abl.setEnabled(false);
FrameLayout contentContainer = (FrameLayout) findViewById(R.id.content).getParent();
contentContainer.setForeground(null);
findViewById(R.id.login_button).setOnClickListener(this);
mContent = findViewById(R.id.welcome_container);
mProgress = findViewById(R.id.login_progress_container);
handleIntent(getIntent());
}
}
@Override
protected void onNewIntent(Intent intent) {
if (!handleIntent(intent)) {
super.onNewIntent(intent);
}
}
private boolean handleIntent(Intent intent) {
Uri data = intent.getData();
if (data != null
&& data.getScheme().equals(CALLBACK_URI.getScheme())
&& data.getHost().equals(CALLBACK_URI.getHost())) {
Uri uri = Uri.parse(TOKEN_URL)
.buildUpon()
.appendQueryParameter(PARAM_CLIENT_ID, BuildConfig.CLIENT_ID)
.appendQueryParameter(PARAM_CLIENT_SECRET, BuildConfig.CLIENT_SECRET)
.appendQueryParameter(PARAM_CODE, data.getQueryParameter(PARAM_CODE))
.build();
new FetchTokenTask(uri).schedule();
return true;
}
return false;
}
@Override
protected int getLeftNavigationDrawerMenuResource() {
return R.menu.home_nav_drawer;
}
@IdRes
protected int getInitialLeftDrawerSelection(Menu menu) {
menu.setGroupCheckable(R.id.navigation, false, false);
menu.setGroupCheckable(R.id.explore, false, false);
menu.setGroupVisible(R.id.my_items, false);
return super.getInitialLeftDrawerSelection(menu);
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
super.onNavigationItemSelected(item);
switch (item.getItemId()) {
case R.id.settings:
startActivityForResult(new Intent(this, SettingsActivity.class), REQUEST_SETTINGS);
return true;
case R.id.search:
startActivity(SearchActivity.makeIntent(this));
return true;
case R.id.bookmarks:
startActivity(new Intent(this, BookmarkListActivity.class));
return true;
case R.id.pub_timeline:
startActivity(new Intent(this, TimelineActivity.class));
return true;
case R.id.blog:
startActivity(new Intent(this, BlogListActivity.class));
return true;
case R.id.trend:
startActivity(new Intent(this, TrendingActivity.class));
return true;
}
return false;
}
@Override
protected boolean canSwipeToRefresh() {
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_SETTINGS) {
if (data.getBooleanExtra(SettingsActivity.RESULT_EXTRA_THEME_CHANGED, false)) {
Intent intent = new Intent(getIntent());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.login_button) {
triggerLogin();
}
}
@Override
public void onRefresh() {
super.onRefresh();
triggerLogin();
}
public static void launchLogin(Activity activity) {
Uri uri = Uri.parse(OAUTH_URL)
.buildUpon()
.appendQueryParameter(PARAM_CLIENT_ID, BuildConfig.CLIENT_ID)
.appendQueryParameter(PARAM_SCOPE, SCOPES)
.appendQueryParameter(PARAM_CALLBACK_URI, CALLBACK_URI.toString())
.build();
IntentUtils.openInCustomTabOrBrowser(activity, uri);
}
private void triggerLogin() {
launchLogin(this);
mContent.setVisibility(View.GONE);
mProgress.setVisibility(View.VISIBLE);
}
private class FetchTokenTask extends BackgroundTask<Pair<User, String>> {
private Uri mUri;
public FetchTokenTask(Uri uri) {
super(Github4AndroidActivity.this);
mUri = uri;
}
@Override
protected Pair<User, String> run() throws Exception {
HttpURLConnection connection = null;
CharArrayWriter writer = null;
try {
URL url = new URL(mUri.toString());
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("HTTP failure");
}
InputStream in = new BufferedInputStream(connection.getInputStream());
InputStreamReader reader = new InputStreamReader(in, "UTF-8");
int length = connection.getContentLength();
writer = new CharArrayWriter(Math.max(0, length));
char[] tmp = new char[4096];
int l;
while ((l = reader.read(tmp)) != -1) {
writer.write(tmp, 0, l);
}
JSONObject response = new JSONObject(writer.toString());
String token = response.getString("access_token");
// fetch user information to get user name
DefaultClient client = new DefaultClient();
client.setOAuth2Token(token);
UserService userService = new UserService(client);
User user = userService.getUser();
return Pair.create(user, token);
} finally {
if (connection != null) {
connection.disconnect();
}
if (writer != null) {
writer.close();
}
}
}
@Override
protected void onError(Exception e) {
super.onError(e);
setErrorViewVisibility(true);
}
@Override
protected void onSuccess(Pair<User, String> result) {
Gh4Application.get().addAccount(result.first, result.second);
goToToplevelActivity();
finish();
}
}
}