Skip to content

Commit

Permalink
getting programmatic timeout working
Browse files Browse the repository at this point in the history
  • Loading branch information
emilesvt committed Nov 12, 2011
1 parent 3f02e66 commit 146fbeb
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 42 deletions.
10 changes: 7 additions & 3 deletions AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<uses-sdk android:minSdkVersion="7" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="me.ericmiles.mobiletrans.USES_REST" />

<permission
Expand All @@ -21,7 +22,8 @@
<activity
android:label="@string/app_name"
android:name=".activities.MainActivity"
android:theme="@android:style/Theme.NoTitleBar" >
android:theme="@android:style/Theme.NoTitleBar"
android:launchMode="singleTask">
<intent-filter >
<action android:name="android.intent.action.MAIN" />

Expand All @@ -35,11 +37,13 @@
android:theme="@android:style/Theme.NoTitleBar" >
</activity>
<activity
android:name="me.ericmiles.mobiletrans.activities.TimeoutWarningActivity"
android:name=".activities.TimeoutWarningActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" >
</activity>

<service android:name="me.ericmiles.mobiletrans.rest.RestDelegateService" >
<service android:name=".rest.RestDelegateService" >
</service>
<service android:name=".rest.SendFailedMessageService" >
</service>

<receiver
Expand Down
9 changes: 9 additions & 0 deletions Mockey/mockey_def_depot/TimeoutService.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<mockservice version="1.0" xml:lang="en-US">
<service default_real_url_index="0" default_scenario_id="1" description="" hang_time="0" http_content_type="application/json;" name="TimeoutService" service_response_type="1" url="TimeoutService">
<scenario id="1" name="Default">
<scenario_match/>
<scenario_response><![CDATA[{"status":"SUCCESS"}]]></scenario_response>
</scenario>
</service>
</mockservice>
17 changes: 17 additions & 0 deletions res/layout/notification.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="3dp"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#000"
/>
</LinearLayout>
43 changes: 18 additions & 25 deletions src/me/ericmiles/mobiletrans/activities/ErrorActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@
import me.ericmiles.mobiletrans.Constants;
import me.ericmiles.mobiletrans.operations.Operation;
import me.ericmiles.mobiletrans.operations.Operation.OperationRequest;
import me.ericmiles.mobiletrans.operations.Operation.OperationResponse.Status;
import me.ericmiles.mobiletrans.operations.OperationIntentFactory;
import me.ericmiles.mobiletrans.operations.TimeoutOperation;
import me.ericmiles.mobiletrans.rest.SendFailedMessageService;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

/**
* @author emiles
*
*/
public class ErrorActivity extends Activity {

private static final String TAG = ErrorActivity.class.getSimpleName();

private Bundle extras;

@Override
Expand All @@ -42,33 +40,28 @@ protected Dialog onCreateDialog(int id) {
"A error occurred while attempting to communicate with the backend. Do you want to attempt again?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Operation.OperationRequest request = (OperationRequest) extras
.getParcelable(Constants.REST_REQUEST);
Intent intent = OperationIntentFactory.getInstance(getApplicationContext()).createIntent(
(OperationRequest) extras.getParcelable(Constants.REST_REQUEST));
request);

// this is a cheat, but trying to show that a subsequent
// retry CAN work (i can't do this programmatically in
// the backend
// with mocky
if (request instanceof TimeoutOperation.Request) {
((TimeoutOperation.Request) request).retry = true;
}

startService(intent);
finish();
}
}).setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
try {

// we could do all sorts of things here, but all we're going to do is notify
// the calling activity that the call failed
Class<? extends Operation.OperationResponse> clazz = ((Operation.OperationRequest) extras
.getParcelable(Constants.REST_REQUEST)).getResponseType();
Operation.OperationResponse response = clazz.newInstance();
response.status = Status.FAILED;
response.errorMsg = "Sorry! Something went terribly wrong";

// create the response broadcast and send on
Intent forward = OperationIntentFactory.getInstance(getApplicationContext()).createIntent(
response);
sendOrderedBroadcast(forward, Constants.PERMISSION);
finish();
} catch (IllegalAccessException e) {
Log.e(TAG, "oops", e);
} catch (InstantiationException e) {
Log.e(TAG, "oops", e);
}
Intent forward = new Intent(ErrorActivity.this, SendFailedMessageService.class);
forward.putExtras(extras);
startService(forward);
finish();
}
}).create();
}
Expand Down
11 changes: 10 additions & 1 deletion src/me/ericmiles/mobiletrans/activities/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ protected void onPause() {
unregisterReceiver(receiver);
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
login.setText(null);
userId.setText(null);
login.setEnabled(true);
userId.setEnabled(true);
password.setEnabled(true);
}

class MyReceiver extends BroadcastReceiver {

@Override
Expand All @@ -115,7 +125,6 @@ public void onClick(DialogInterface dialog, int which) {
if (response.status == LoginOperation.Response.Status.SUCCESS) {
Intent forward = new Intent(MainActivity.this, SecondaryActivity.class);
startActivity(forward);
finish();
}
}
});
Expand Down
23 changes: 14 additions & 9 deletions src/me/ericmiles/mobiletrans/activities/SecondaryActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class SecondaryActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondary);

final OperationIntentFactory factory = OperationIntentFactory.getInstance(getApplicationContext());

show = (Button) findViewById(R.id.show);
Expand Down Expand Up @@ -103,13 +103,17 @@ class LogoutBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
LogoutOperation.Response response = intent.getParcelableExtra(Constants.REST_RESPONSE);
if (response.status == Status.SUCCESS) {
Intent forward = new Intent(SecondaryActivity.this, MainActivity.class);
startActivity(forward);
SecondaryActivity.this.finish();
} else {
logout.setEnabled(true);
// for demo purposes, i want to ignore programmatic logouts
// so the user can check the session value
if (!logout.isEnabled()) {
LogoutOperation.Response response = intent.getParcelableExtra(Constants.REST_RESPONSE);
if (response.status == Status.SUCCESS) {
Intent forward = new Intent(SecondaryActivity.this, MainActivity.class);
startActivity(forward);
SecondaryActivity.this.finish();
} else {
logout.setEnabled(true);
}
}
}

Expand All @@ -119,7 +123,8 @@ class TimeoutBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO: what was i going to do here?
TimeoutOperation.Response response = intent.getExtras().getParcelable(Constants.REST_RESPONSE);
Toast.makeText(SecondaryActivity.this, "Operation result: " + response.status, Toast.LENGTH_LONG).show();
timeout.setEnabled(true);
}

Expand Down
58 changes: 58 additions & 0 deletions src/me/ericmiles/mobiletrans/rest/SendFailedMessageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
*
*/
package me.ericmiles.mobiletrans.rest;

import me.ericmiles.mobiletrans.Constants;
import me.ericmiles.mobiletrans.operations.Operation;
import me.ericmiles.mobiletrans.operations.Operation.OperationResponse.Status;
import me.ericmiles.mobiletrans.operations.OperationIntentFactory;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

/**
* @author emiles
*
*/
public class SendFailedMessageService extends IntentService {

private static final String TAG = SendFailedMessageService.class.getSimpleName();

public SendFailedMessageService() {
super("SendFailedMessageService");
}

/*
* (non-Javadoc)
*
* @see android.app.IntentService#onHandleIntent(android.content.Intent)
*/
@Override
protected void onHandleIntent(Intent intent) {
// we could do all sorts of things here, but all we're going to do is
// notify
// the calling activity that the call failed
try {

// we're gonna cheat massively here, but I want to ensure that the
// error activity has finished up before we send this result
// broadcast
Thread.sleep(1000);

Class<? extends Operation.OperationResponse> clazz = ((Operation.OperationRequest) intent
.getParcelableExtra(Constants.REST_REQUEST)).getResponseType();
Operation.OperationResponse response = clazz.newInstance();
response.status = Status.FAILED;
response.errorMsg = "Sorry! Something went terribly wrong";

// create the response broadcast and send on
final Intent forward = OperationIntentFactory.getInstance(getApplicationContext()).createIntent(response);
sendOrderedBroadcast(forward, Constants.PERMISSION);
} catch (Exception e) {
Log.e(TAG, "oops", e);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
package me.ericmiles.mobiletrans.session;

import me.ericmiles.mobiletrans.Constants;
import me.ericmiles.mobiletrans.R;
import me.ericmiles.mobiletrans.activities.MainActivity;
import me.ericmiles.mobiletrans.operations.LoginOperation;
import me.ericmiles.mobiletrans.operations.LogoutOperation;
import me.ericmiles.mobiletrans.operations.OperationIntentFactory;
import me.ericmiles.mobiletrans.util.Utils;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;

/**
* @author 94728
Expand Down Expand Up @@ -62,7 +67,7 @@ public void onReceive(Context context, Intent intent) {
killSessionTriggers(context);
// let's also notify the user via a status bar notification they've
// been logged out
// TODO:
notifyOfLogout(context);
}

// if we're authenticated and there was a response object
Expand All @@ -73,6 +78,27 @@ public void onReceive(Context context, Intent intent) {
}
}

private void notifyOfLogout(Context context) {
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(android.R.drawable.stat_sys_warning, "You have been logged out",
System.currentTimeMillis());
notification.defaults |= Notification.DEFAULT_ALL;
notification.flags |= Notification.FLAG_AUTO_CANCEL;

// forward to login
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.notification);
contentView.setImageViewResource(R.id.image, R.drawable.ic_launcher);
contentView.setTextViewText(R.id.text, "You have been logged out, please log back in");
notification.contentView = contentView;
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
mNotificationManager.notify(1, notification);
}

private void killSessionTriggers(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(getLogoutIntent(context));
Expand All @@ -81,17 +107,17 @@ private void killSessionTriggers(Context context) {
private void resetSessionTriggers(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

// arbitrarily setting session timeout to 2 mins
// arbitrarily setting session timeout to 1 mins
// should get this from the server, but we're doing this for ease of
// demonstration
long logoutTimeMillis = System.currentTimeMillis() + (2 * 60 * 1000);
long logoutTimeMillis = System.currentTimeMillis() + (1 * 60 * 1000);

// create one intent for eventual logout broadcast
alarmManager.set(AlarmManager.RTC, logoutTimeMillis, getLogoutIntent(context));
}

private PendingIntent getLogoutIntent(Context context) {
return PendingIntent.getBroadcast(
return PendingIntent.getService(
context,
0,
OperationIntentFactory.getInstance(context.getApplicationContext()).createIntent(
Expand Down

0 comments on commit 146fbeb

Please sign in to comment.