mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Handing authorisation issues with phone-to-Chrome.
Misc cleanup along the way.
This commit is contained in:
@@ -37,7 +37,8 @@
|
||||
android:label="@string/app_name">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ShareLinkActivity">
|
||||
<activity android:name=".ShareLinkActivity"
|
||||
android:theme="@style/Theme.Translucent">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
4
android/res/values/colors.xml
Normal file
4
android/res/values/colors.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<drawable name="translucent_background">#00000000</drawable>
|
||||
</resources>
|
||||
8
android/res/values/styles.xml
Normal file
8
android/res/values/styles.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.Translucent" parent="android:style/Theme.Translucent">
|
||||
<item name="android:windowBackground">@drawable/translucent_background</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:colorForeground">#fff</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -38,7 +38,6 @@ import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -46,15 +45,15 @@ import android.util.Log;
|
||||
* AppEngine client. Handles auth.
|
||||
*/
|
||||
public class AppEngineClient {
|
||||
private static final String TAG = "AppEngineClient";
|
||||
|
||||
static final String BASE_URL = "https://chrometophone.appspot.com";
|
||||
static final String BASE_URL = "https://9.chrometophone.appspot.com";
|
||||
private static final String AUTH_URL = BASE_URL + "/_ah/login";
|
||||
private static final String AUTH_TOKEN_TYPE = "ah";
|
||||
|
||||
private final Context mContext;
|
||||
private final String mAccountName;
|
||||
|
||||
private static final String TAG = "AppEngineClient";
|
||||
|
||||
public AppEngineClient(Context context, String accountName) {
|
||||
this.mContext = context;
|
||||
this.mAccountName = accountName;
|
||||
@@ -70,11 +69,10 @@ public class AppEngineClient {
|
||||
|
||||
private HttpResponse makeRequestNoRetry(String urlPath, List<NameValuePair> params, boolean newToken)
|
||||
throws Exception {
|
||||
|
||||
// Get auth token for account
|
||||
Account account = new Account(mAccountName, "com.google");
|
||||
String authToken = getAuthToken(mContext, account);
|
||||
if (authToken == null) throw new PendingAuthException(mAccountName);
|
||||
|
||||
if (newToken) { // invalidate the cached token
|
||||
AccountManager accountManager = AccountManager.get(mContext);
|
||||
accountManager.invalidateAuthToken(account.type, authToken);
|
||||
@@ -121,7 +119,7 @@ public class AppEngineClient {
|
||||
return res;
|
||||
}
|
||||
|
||||
private String getAuthToken(Context context, Account account) {
|
||||
private String getAuthToken(Context context, Account account) throws PendingAuthException {
|
||||
String authToken = null;
|
||||
AccountManager accountManager = AccountManager.get(context);
|
||||
try {
|
||||
@@ -129,12 +127,8 @@ public class AppEngineClient {
|
||||
accountManager.getAuthToken (account, AUTH_TOKEN_TYPE, false, null, null);
|
||||
Bundle bundle = future.getResult();
|
||||
authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
// User will be asked for "App Engine" permission.
|
||||
if (authToken == null) {
|
||||
// No auth token - will need to ask permission from user.
|
||||
Intent intent = new Intent(SetupActivity.AUTH_PERMISSION_ACTION);
|
||||
intent.putExtra("AccountManagerBundle", bundle);
|
||||
context.sendBroadcast(intent);
|
||||
throw new PendingAuthException(bundle);
|
||||
}
|
||||
} catch (OperationCanceledException e) {
|
||||
Log.w(TAG, e.getMessage());
|
||||
@@ -148,8 +142,14 @@ public class AppEngineClient {
|
||||
|
||||
public class PendingAuthException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
public PendingAuthException(String message) {
|
||||
super(message);
|
||||
private final Bundle mAccountManagerBundle;
|
||||
public PendingAuthException(Bundle accountManagerBundle) {
|
||||
super();
|
||||
mAccountManagerBundle = accountManagerBundle;
|
||||
}
|
||||
|
||||
public Bundle getAccountManagerBundle() {
|
||||
return mAccountManagerBundle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
/**
|
||||
* Register/unregister with the Chrome to Phone App Engine server.
|
||||
@@ -69,7 +67,10 @@ public class DeviceRegistrar {
|
||||
}
|
||||
context.sendBroadcast(updateUIIntent);
|
||||
} catch (AppEngineClient.PendingAuthException pae) {
|
||||
// Ignore - we'll reregister later
|
||||
// Get setup activity to ask permission from user.
|
||||
Intent intent = new Intent(SetupActivity.AUTH_PERMISSION_ACTION);
|
||||
intent.putExtra("AccountManagerBundle", pae.getAccountManagerBundle());
|
||||
context.sendBroadcast(intent);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Registration error " + e.getMessage());
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
|
||||
@@ -86,20 +87,19 @@ public class DeviceRegistrar {
|
||||
Intent updateUIIntent = new Intent("com.google.ctp.UPDATE_UI");
|
||||
try {
|
||||
HttpResponse res = makeRequest(context, deviceRegistrationID, UNREGISTER_PATH);
|
||||
if (res.getStatusLine().getStatusCode() == 200) {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.remove("deviceRegistrationID");
|
||||
editor.commit();
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, UNREGISTERED_STATUS);
|
||||
} else {
|
||||
if (res.getStatusLine().getStatusCode() != 200) {
|
||||
Log.w(TAG, "Unregistration error " +
|
||||
String.valueOf(res.getStatusLine().getStatusCode()));
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, ERROR_STATUS);
|
||||
Log.w(TAG, "Unegistration error " + e.getMessage());
|
||||
Log.w(TAG, "Unregistration error " + e.getMessage());
|
||||
} finally {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.remove("deviceRegistrationID");
|
||||
editor.remove("accountName");
|
||||
editor.commit();
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, UNREGISTERED_STATUS);
|
||||
}
|
||||
|
||||
// Update dialog activity
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.widget.ExpandableListView.OnChildClickListener;
|
||||
*/
|
||||
public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
private static final int DIALOG_LINK_ACTION = 1;
|
||||
private static final int SETUP_ACTIVITY_REQUEST_CODE = 1;
|
||||
|
||||
private ExpandableListView mList;
|
||||
private HistoryExpandableListAdapter mListAdapter;
|
||||
@@ -77,7 +78,8 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
return true;
|
||||
}
|
||||
case R.id.settings: {
|
||||
startActivity(new Intent(this, SetupActivity.class));
|
||||
startActivityForResult(new Intent(this, SetupActivity.class),
|
||||
SETUP_ACTIVITY_REQUEST_CODE);
|
||||
return true;
|
||||
}
|
||||
case R.id.help: {
|
||||
@@ -90,6 +92,16 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == SETUP_ACTIVITY_REQUEST_CODE) {
|
||||
SharedPreferences prefs = Prefs.get(this);
|
||||
if (prefs.getString("deviceRegistrationID", null) == null) {
|
||||
finish(); // user asked to exit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
|
||||
int childPosition, long id) {
|
||||
mSelectedLink = mListAdapter.getLinkAtPosition(groupPosition, childPosition);
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* 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.google.android.apps.chrometophone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ShareLink implements Handler.Callback {
|
||||
private static final String TOAST = "toast";
|
||||
private static final String SEND_PATH = "/send";
|
||||
private static ShareLink mInstance;
|
||||
private final Handler mHandler;
|
||||
private final Context mContext;
|
||||
|
||||
private ShareLink(Context context) {
|
||||
mContext = context;
|
||||
mHandler = new Handler(this);
|
||||
}
|
||||
|
||||
public static synchronized ShareLink getInstance(Context context) {
|
||||
if (mInstance == null) {
|
||||
mInstance = new ShareLink(context);
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public void send(final String link) {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
sendToast(mContext.getString(R.string.sending_link_toast));
|
||||
try {
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("url", link));
|
||||
params.add(new BasicNameValuePair("deviceName", "Chrome," +
|
||||
(DeviceRegistrar.isTablet(mContext) ? "Phone" : "Tablet")));
|
||||
|
||||
SharedPreferences settings = Prefs.get(mContext);
|
||||
final String accountName = settings.getString("accountName", null);
|
||||
|
||||
AppEngineClient client = new AppEngineClient(mContext, accountName);
|
||||
HttpResponse res = client.makeRequest(SEND_PATH, params);
|
||||
if (res.getStatusLine().getStatusCode() == 200) {
|
||||
sendToast(mContext.getString(R.string.link_sent_toast));
|
||||
} else {
|
||||
sendToast(mContext.getString(R.string.link_not_sent_toast));
|
||||
}
|
||||
} catch (AppEngineClient.PendingAuthException e) {
|
||||
sendToast(mContext.getString(R.string.link_not_sent_auth_toast));
|
||||
} catch (Exception e) {
|
||||
sendToast(mContext.getString(R.string.link_not_sent_toast));
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sendToast(String toastMessage) {
|
||||
Message msg = new Message();
|
||||
Bundle data = new Bundle();
|
||||
data.putString(TOAST, toastMessage);
|
||||
msg.setData(data);
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public boolean handleMessage(Message msg) {
|
||||
Toast.makeText(mContext, msg.getData().getString(TOAST), Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -16,18 +16,38 @@
|
||||
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Invoked when user selects "Share page" in the browser. Sends link
|
||||
* to AppEngine server.
|
||||
*/
|
||||
public class ShareLinkActivity extends Activity {
|
||||
public class ShareLinkActivity extends Activity implements Handler.Callback {
|
||||
private static final int TOAST_MSG = 0;
|
||||
private static final int START_ACTIVITY_MSG = 1;
|
||||
|
||||
private static final String SEND_PATH = "/send";
|
||||
|
||||
private boolean mPendingAuth = false;
|
||||
private String mPendingLink;
|
||||
private final Handler mHandler = new Handler(this);
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -37,10 +57,76 @@ public class ShareLinkActivity extends Activity {
|
||||
Pattern regex = Pattern.compile("http(s)?://.*"); // find the link
|
||||
Matcher matcher = regex.matcher(text);
|
||||
if (matcher.find()) {
|
||||
String link = matcher.group();
|
||||
ShareLink.getInstance(this).send(link);
|
||||
mPendingAuth = false;
|
||||
mPendingLink = matcher.group();
|
||||
sendLink();
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (mPendingAuth) {
|
||||
sendLink();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendLink() {
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
sendToast(getString(R.string.sending_link_toast));
|
||||
try {
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("url", mPendingLink));
|
||||
params.add(new BasicNameValuePair("deviceName", "Chrome," +
|
||||
(DeviceRegistrar.isTablet(ShareLinkActivity.this) ? "Phone" : "Tablet")));
|
||||
|
||||
SharedPreferences settings = Prefs.get(ShareLinkActivity.this);
|
||||
final String accountName = settings.getString("accountName", null);
|
||||
if (accountName == null) {
|
||||
sendToast(getString(R.string.link_not_sent_auth_toast));
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
AppEngineClient client = new AppEngineClient(ShareLinkActivity.this, accountName);
|
||||
HttpResponse res = client.makeRequest(SEND_PATH, params);
|
||||
if (res.getStatusLine().getStatusCode() == 200) {
|
||||
sendToast(getString(R.string.link_sent_toast));
|
||||
} else {
|
||||
sendToast(getString(R.string.link_not_sent_toast));
|
||||
}
|
||||
finish();
|
||||
} catch (AppEngineClient.PendingAuthException pae) {
|
||||
Intent authIntent = (Intent) pae.getAccountManagerBundle().get(AccountManager.KEY_INTENT);
|
||||
if (authIntent != null && !mPendingAuth) {
|
||||
mPendingAuth = true;
|
||||
mHandler.sendMessage(Message.obtain(mHandler, START_ACTIVITY_MSG, 0, 0, authIntent));
|
||||
} else {
|
||||
sendToast(getString(R.string.link_not_sent_auth_toast));
|
||||
finish();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sendToast(getString(R.string.link_not_sent_toast));
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sendToast(String toastMessage) {
|
||||
mHandler.sendMessage(Message.obtain(mHandler, TOAST_MSG, 0, 0, toastMessage));
|
||||
}
|
||||
|
||||
public boolean handleMessage(Message msg) {
|
||||
if (msg.what == TOAST_MSG) {
|
||||
Toast.makeText(this, (String) msg.obj, Toast.LENGTH_LONG).show();
|
||||
} else if (msg.what == START_ACTIVITY_MSG) {
|
||||
startActivity((Intent) msg.obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user