mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-07 05:24:46 +01:00
Recast BTService as a JobIntentService
Got tired of the space the forground-service notification icons were taking. So now BT sends and receives are done via static threads and onHandleWork(). The send thread times itself out quickly. The receive thread doesn't yet. We'll see how long the OS lets it run and what needs to be done to deal with that.
This commit is contained in:
parent
438e134870
commit
7ccb576214
10 changed files with 577 additions and 713 deletions
|
@ -212,9 +212,6 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="org.eehouse.android.ACTION_STOP_BT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="SMSReceiver" >
|
||||
|
|
|
@ -29,9 +29,6 @@ import android.content.Intent;
|
|||
public class BTReceiver extends BroadcastReceiver {
|
||||
private static final String TAG = BTReceiver.class.getSimpleName();
|
||||
|
||||
// This string is also used in AndroidManifest (as a string literal)
|
||||
static final String ACTION_STOP_BT = "org.eehouse.android.ACTION_STOP_BT";
|
||||
|
||||
@Override
|
||||
public void onReceive( Context context, Intent intent )
|
||||
{
|
||||
|
@ -41,9 +38,6 @@ public class BTReceiver extends BroadcastReceiver {
|
|||
action, intent.toString() );
|
||||
|
||||
switch (action ) {
|
||||
case ACTION_STOP_BT:
|
||||
BTService.stopBackground( context );
|
||||
break;
|
||||
case BluetoothDevice.ACTION_ACL_CONNECTED:
|
||||
BTService.onACLConnected( context );
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -85,7 +85,6 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
|
||||
private static final String RELAYIDS_EXTRA = "relayids";
|
||||
private static final String ROWID_EXTRA = "rowid";
|
||||
private static final String BACKGROUND_EXTRA = "bkgrnd";
|
||||
private static final String GAMEID_EXTRA = "gameid";
|
||||
private static final String REMATCH_ROWID_EXTRA = "rm_rowid";
|
||||
private static final String REMATCH_DICT_EXTRA = "rm_dict";
|
||||
|
@ -2289,14 +2288,6 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
private void tryBackgroundIntent( Intent intent )
|
||||
{
|
||||
if ( intent.getBooleanExtra( BACKGROUND_EXTRA, false ) ) {
|
||||
makeOkOnlyBuilder( R.string.btservice_expl )
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void askDefaultName()
|
||||
{
|
||||
String name = CommonPrefs.getDefaultPlayerName( m_activity, 0, true );
|
||||
|
@ -2511,7 +2502,6 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
startRematch( intent );
|
||||
tryAlert( intent );
|
||||
tryNFCIntent( intent );
|
||||
tryBackgroundIntent( intent );
|
||||
}
|
||||
|
||||
private void doOpenGame( Object[] params )
|
||||
|
@ -2704,12 +2694,6 @@ public class GamesListDelegate extends ListDelegateBase
|
|||
;
|
||||
}
|
||||
|
||||
public static Intent makeBackgroundIntent( Context context )
|
||||
{
|
||||
return makeSelfIntent( context )
|
||||
.putExtra( BACKGROUND_EXTRA, true );
|
||||
}
|
||||
|
||||
public static Intent makeRowidIntent( Context context, long rowid )
|
||||
{
|
||||
Intent intent = makeSelfIntent( context )
|
||||
|
|
|
@ -26,7 +26,6 @@ import android.content.Intent;
|
|||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.JobIntentService;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.eehouse.android.xw4.FBMService;
|
||||
|
@ -64,7 +63,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
public class RelayService extends JobIntentService
|
||||
public class RelayService extends XWJIService
|
||||
implements NetStateCache.StateChangedIf {
|
||||
private static final String TAG = RelayService.class.getSimpleName();
|
||||
private static final int MAX_SEND = 1024;
|
||||
|
@ -82,24 +81,21 @@ public class RelayService extends JobIntentService
|
|||
// One day, in seconds. Probably should be configurable.
|
||||
private static final long MAX_KEEPALIVE_SECS = 24 * 60 * 60;
|
||||
|
||||
private static final String CMD_KEY = "CMD";
|
||||
private static final String TIMESTAMP = "TIMESTAMP";
|
||||
|
||||
private static enum MsgCmds { INVALID,
|
||||
DO_WORK,
|
||||
PROCESS_GAME_MSGS,
|
||||
PROCESS_DEV_MSGS,
|
||||
UDP_CHANGED,
|
||||
SEND,
|
||||
SENDNOCONN,
|
||||
RECEIVE,
|
||||
TIMER_FIRED,
|
||||
RESET,
|
||||
UPGRADE,
|
||||
INVITE,
|
||||
GOT_INVITE,
|
||||
GOT_PACKET,
|
||||
STOP,
|
||||
private static enum MsgCmds implements XWJICmds { INVALID,
|
||||
DO_WORK,
|
||||
PROCESS_GAME_MSGS,
|
||||
PROCESS_DEV_MSGS,
|
||||
UDP_CHANGED,
|
||||
SEND,
|
||||
SENDNOCONN,
|
||||
RECEIVE,
|
||||
TIMER_FIRED,
|
||||
RESET,
|
||||
UPGRADE,
|
||||
INVITE,
|
||||
GOT_INVITE,
|
||||
GOT_PACKET,
|
||||
STOP,
|
||||
}
|
||||
|
||||
private static final String MSGS_ARR = "MSGS_ARR";
|
||||
|
@ -222,18 +218,7 @@ public class RelayService extends JobIntentService
|
|||
private static void enqueueWork( Context context, Intent intent )
|
||||
{
|
||||
enqueueWork( context, RelayService.class, sJobID, intent );
|
||||
Log.d( TAG, "called enqueueWork(cmd=%s)", cmdFrom( intent ) );
|
||||
}
|
||||
|
||||
private static MsgCmds cmdFrom( Intent intent )
|
||||
{
|
||||
MsgCmds cmd;
|
||||
try {
|
||||
cmd = MsgCmds.values()[intent.getIntExtra( CMD_KEY, -1 )];
|
||||
} catch (Exception ex) { // OOB most likely
|
||||
cmd = null;
|
||||
}
|
||||
return cmd;
|
||||
Log.d( TAG, "called enqueueWork(cmd=%s)", cmdFrom( intent, MsgCmds.values() ) );
|
||||
}
|
||||
|
||||
private static void stopService( Context context )
|
||||
|
@ -353,10 +338,7 @@ public class RelayService extends JobIntentService
|
|||
|
||||
private static Intent getIntentTo( Context context, MsgCmds cmd )
|
||||
{
|
||||
Intent intent = new Intent( context, RelayService.class )
|
||||
.putExtra( CMD_KEY, cmd.ordinal() )
|
||||
.putExtra( TIMESTAMP, System.currentTimeMillis() );
|
||||
return intent;
|
||||
return getIntentTo( context, RelayService.class, cmd );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -391,15 +373,15 @@ public class RelayService extends JobIntentService
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onHandleWork( Intent intent )
|
||||
void onHandleWorkImpl( Intent intent, XWJICmds jicmd, long timestamp )
|
||||
{
|
||||
DbgUtils.assertOnUIThread( false );
|
||||
Log.d( TAG, "%s.onHandleWork(cmd=%s)", this, cmdFrom( intent ) );
|
||||
// Log.d( TAG, "%s.onHandleWork(cmd=%s)", this, cmdFrom( intent ) );
|
||||
|
||||
try {
|
||||
connectSocketOnce(); // must not be on UI thread
|
||||
|
||||
handleCommand( intent );
|
||||
handleCommand( intent, jicmd, timestamp );
|
||||
|
||||
boolean goOn = serviceQueue();
|
||||
if ( !goOn ) {
|
||||
|
@ -438,6 +420,9 @@ public class RelayService extends JobIntentService
|
|||
Log.d( TAG, "%s.onDestroy() DONE", this );
|
||||
}
|
||||
|
||||
@Override
|
||||
XWJICmds[] getCmds() { return MsgCmds.values(); }
|
||||
|
||||
// NetStateCache.StateChangedIf interface
|
||||
@Override
|
||||
public void onNetAvail( boolean nowAvailable )
|
||||
|
@ -445,94 +430,89 @@ public class RelayService extends JobIntentService
|
|||
startService( this ); // bad name: will *stop* threads too
|
||||
}
|
||||
|
||||
private void handleCommand( Intent intent )
|
||||
private void handleCommand( Intent intent, XWJICmds jicmd, long timestamp )
|
||||
{
|
||||
MsgCmds cmd = cmdFrom( intent );
|
||||
if ( null != cmd ) {
|
||||
long timestamp = intent.getLongExtra( TIMESTAMP, 0 );
|
||||
Log.d( TAG, "handleCommand(): cmd=%s (age=%dms)", cmd.toString(),
|
||||
System.currentTimeMillis() - timestamp );
|
||||
switch( cmd ) {
|
||||
case DO_WORK: // exists only to launch service
|
||||
break;
|
||||
case PROCESS_GAME_MSGS:
|
||||
String[] relayIDs = new String[1];
|
||||
relayIDs[0] = intent.getStringExtra( RELAY_ID );
|
||||
long[] rowIDs = DBUtils.getRowIDsFor( this, relayIDs[0] );
|
||||
if ( 0 < rowIDs.length ) {
|
||||
byte[][][] msgs = expandMsgsArray( intent );
|
||||
process( msgs, rowIDs, relayIDs );
|
||||
}
|
||||
break;
|
||||
case PROCESS_DEV_MSGS:
|
||||
byte[][][] msgss = expandMsgsArray( intent );
|
||||
for ( byte[][] msgs : msgss ) {
|
||||
for ( byte[] msg : msgs ) {
|
||||
gotPacket( msg, true, false, timestamp );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UDP_CHANGED:
|
||||
startThreads();
|
||||
break;
|
||||
case RESET:
|
||||
stopThreads();
|
||||
startThreads();
|
||||
break;
|
||||
case UPGRADE:
|
||||
UpdateCheckReceiver.checkVersions( this, false );
|
||||
break;
|
||||
case GOT_INVITE:
|
||||
int srcDevID = intent.getIntExtra( INVITE_FROM, 0 );
|
||||
NetLaunchInfo nli
|
||||
= NetLaunchInfo.makeFrom( this, intent.getStringExtra(NLI_DATA) );
|
||||
receiveInvitation( srcDevID, nli );
|
||||
break;
|
||||
case GOT_PACKET:
|
||||
byte[] msg = intent.getByteArrayExtra( BINBUFFER );
|
||||
gotPacket( msg, false, true );
|
||||
break;
|
||||
case SEND:
|
||||
case RECEIVE:
|
||||
case SENDNOCONN:
|
||||
startUDPReadThreadOnce();
|
||||
long rowid = intent.getLongExtra( ROWID, -1 );
|
||||
msg = intent.getByteArrayExtra( BINBUFFER );
|
||||
if ( MsgCmds.SEND == cmd ) {
|
||||
sendMessage( rowid, msg, timestamp );
|
||||
} else if ( MsgCmds.SENDNOCONN == cmd ) {
|
||||
String relayID = intent.getStringExtra( RELAY_ID );
|
||||
String msgNo = intent.getStringExtra( MSGNUM );
|
||||
sendNoConnMessage( rowid, relayID, msg, msgNo, timestamp );
|
||||
} else {
|
||||
mHelper.receiveMessage( this, rowid, null, msg, s_addr );
|
||||
}
|
||||
break;
|
||||
case INVITE:
|
||||
startUDPReadThreadOnce();
|
||||
srcDevID = intent.getIntExtra( DEV_ID_SRC, 0 );
|
||||
int destDevID = intent.getIntExtra( DEV_ID_DEST, 0 );
|
||||
String relayID = intent.getStringExtra( RELAY_ID );
|
||||
String nliData = intent.getStringExtra( NLI_DATA );
|
||||
sendInvitation( srcDevID, destDevID, relayID, nliData, timestamp );
|
||||
break;
|
||||
case TIMER_FIRED:
|
||||
if ( !NetStateCache.netAvail( this ) ) {
|
||||
Log.w( TAG, "not connecting: no network" );
|
||||
} else if ( startFetchThreadIfNotUDP() ) {
|
||||
// do nothing
|
||||
} else if ( registerWithRelayIfNot( timestamp ) ) {
|
||||
requestMessages( timestamp );
|
||||
}
|
||||
RelayReceiver.setTimer( this );
|
||||
break;
|
||||
case STOP:
|
||||
stopThreads();
|
||||
stopSelf();
|
||||
break;
|
||||
default:
|
||||
Assert.assertFalse( BuildConfig.DEBUG );
|
||||
MsgCmds cmd = (MsgCmds)jicmd;
|
||||
switch( cmd ) {
|
||||
case DO_WORK: // exists only to launch service
|
||||
break;
|
||||
case PROCESS_GAME_MSGS:
|
||||
String[] relayIDs = new String[1];
|
||||
relayIDs[0] = intent.getStringExtra( RELAY_ID );
|
||||
long[] rowIDs = DBUtils.getRowIDsFor( this, relayIDs[0] );
|
||||
if ( 0 < rowIDs.length ) {
|
||||
byte[][][] msgs = expandMsgsArray( intent );
|
||||
process( msgs, rowIDs, relayIDs );
|
||||
}
|
||||
break;
|
||||
case PROCESS_DEV_MSGS:
|
||||
byte[][][] msgss = expandMsgsArray( intent );
|
||||
for ( byte[][] msgs : msgss ) {
|
||||
for ( byte[] msg : msgs ) {
|
||||
gotPacket( msg, true, false, timestamp );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UDP_CHANGED:
|
||||
startThreads();
|
||||
break;
|
||||
case RESET:
|
||||
stopThreads();
|
||||
startThreads();
|
||||
break;
|
||||
case UPGRADE:
|
||||
UpdateCheckReceiver.checkVersions( this, false );
|
||||
break;
|
||||
case GOT_INVITE:
|
||||
int srcDevID = intent.getIntExtra( INVITE_FROM, 0 );
|
||||
NetLaunchInfo nli
|
||||
= NetLaunchInfo.makeFrom( this, intent.getStringExtra(NLI_DATA) );
|
||||
receiveInvitation( srcDevID, nli );
|
||||
break;
|
||||
case GOT_PACKET:
|
||||
byte[] msg = intent.getByteArrayExtra( BINBUFFER );
|
||||
gotPacket( msg, false, true );
|
||||
break;
|
||||
case SEND:
|
||||
case RECEIVE:
|
||||
case SENDNOCONN:
|
||||
startUDPReadThreadOnce();
|
||||
long rowid = intent.getLongExtra( ROWID, -1 );
|
||||
msg = intent.getByteArrayExtra( BINBUFFER );
|
||||
if ( MsgCmds.SEND == cmd ) {
|
||||
sendMessage( rowid, msg, timestamp );
|
||||
} else if ( MsgCmds.SENDNOCONN == cmd ) {
|
||||
String relayID = intent.getStringExtra( RELAY_ID );
|
||||
String msgNo = intent.getStringExtra( MSGNUM );
|
||||
sendNoConnMessage( rowid, relayID, msg, msgNo, timestamp );
|
||||
} else {
|
||||
mHelper.receiveMessage( this, rowid, null, msg, s_addr );
|
||||
}
|
||||
break;
|
||||
case INVITE:
|
||||
startUDPReadThreadOnce();
|
||||
srcDevID = intent.getIntExtra( DEV_ID_SRC, 0 );
|
||||
int destDevID = intent.getIntExtra( DEV_ID_DEST, 0 );
|
||||
String relayID = intent.getStringExtra( RELAY_ID );
|
||||
String nliData = intent.getStringExtra( NLI_DATA );
|
||||
sendInvitation( srcDevID, destDevID, relayID, nliData, timestamp );
|
||||
break;
|
||||
case TIMER_FIRED:
|
||||
if ( !NetStateCache.netAvail( this ) ) {
|
||||
Log.w( TAG, "not connecting: no network" );
|
||||
} else if ( startFetchThreadIfNotUDP() ) {
|
||||
// do nothing
|
||||
} else if ( registerWithRelayIfNot( timestamp ) ) {
|
||||
requestMessages( timestamp );
|
||||
}
|
||||
RelayReceiver.setTimer( this );
|
||||
break;
|
||||
case STOP:
|
||||
stopThreads();
|
||||
stopSelf();
|
||||
break;
|
||||
default:
|
||||
Assert.assertFalse( BuildConfig.DEBUG );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -99,16 +99,12 @@ public class XWApp extends Application implements LifecycleObserver {
|
|||
Log.d( TAG, "onAny(%s)", event );
|
||||
switch( event ) {
|
||||
case ON_RESUME:
|
||||
BTService.onAppToForeground( this );
|
||||
// Do here what checkForMoves does
|
||||
if ( null != DBUtils.getRelayIDs( this, null ) ) {
|
||||
RelayService.timerFired( this );
|
||||
}
|
||||
GameUtils.resendAllIf( this, null );
|
||||
break;
|
||||
case ON_STOP:
|
||||
BTService.onAppToBackground( this );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh insXw4Deb"; -*- */
|
||||
/*
|
||||
* Copyright 2010 - 2015 by Eric House (xwords@eehouse.org). All
|
||||
* rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
|
||||
import android.support.v4.app.JobIntentService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
abstract class XWJIService extends JobIntentService {
|
||||
static final String CMD_KEY = "CMD";
|
||||
private static final String TIMESTAMP = "TIMESTAMP";
|
||||
|
||||
public interface XWJICmds {
|
||||
public int ordinal();
|
||||
}
|
||||
|
||||
abstract void onHandleWorkImpl( Intent intent, XWJICmds cmd, long timestamp );
|
||||
abstract XWJICmds[] getCmds();
|
||||
|
||||
@Override
|
||||
public final void onHandleWork( Intent intent )
|
||||
{
|
||||
long timestamp = getTimestamp(intent);
|
||||
XWJICmds cmd = cmdFrom( intent );
|
||||
Log.d( getClass().getSimpleName(),
|
||||
"onHandleWork(): cmd=%s; age=%dms; threadCount: %d)",
|
||||
cmd, System.currentTimeMillis() - timestamp,
|
||||
Thread.activeCount() );
|
||||
|
||||
onHandleWorkImpl( intent, cmd, timestamp );
|
||||
}
|
||||
|
||||
static XWJICmds cmdFrom( Intent intent, XWJICmds[] values )
|
||||
{
|
||||
int ord = intent.getIntExtra( CMD_KEY, -1 );
|
||||
return values[ord];
|
||||
}
|
||||
|
||||
XWJICmds cmdFrom( Intent intent )
|
||||
{
|
||||
int ord = intent.getIntExtra( CMD_KEY, -1 );
|
||||
return getCmds()[ord];
|
||||
}
|
||||
|
||||
long getTimestamp( Intent intent )
|
||||
{
|
||||
long result = intent.getLongExtra( TIMESTAMP, 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
static Intent getIntentTo( Context context, Class clazz, XWJICmds cmd )
|
||||
{
|
||||
Intent intent = new Intent( context, clazz )
|
||||
.putExtra( CMD_KEY, cmd.ordinal() )
|
||||
.putExtra( TIMESTAMP, System.currentTimeMillis() );
|
||||
return intent;
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 308 B |
|
@ -2056,10 +2056,6 @@
|
|||
<string name="title_enable_p2p">Enable WiFi Direct</string>
|
||||
<string name="summary_enable_p2p">Experimental, uses lots of battery</string>
|
||||
|
||||
<string name="bkng_notify_text">Accepting Bluetooth messages…</string>
|
||||
<string name="bkng_stop_text">Stop</string>
|
||||
<string name="bkng_settings_text">Settings</string>
|
||||
|
||||
<!-- -->
|
||||
<string name="confirm_sms_title">Confirm your SMS plan</string>
|
||||
<!-- -->
|
||||
|
@ -2678,12 +2674,6 @@
|
|||
player name \"%1$s\". Would you like to personalize with your own
|
||||
name before you create this game?</string>
|
||||
|
||||
<string name="btservice_expl">This notification is present whenever
|
||||
CrossWords is running in the background to accept Bluetooth
|
||||
messages. It usually runs for about 15 minutes after CrossWords
|
||||
starts or a Bluetooth message is received.
|
||||
</string>
|
||||
|
||||
<string name="no_invites">This game has sent no invitations</string>
|
||||
|
||||
<string name="disable_dualpane">Disable side-by-side</string>
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 471 B |
Loading…
Reference in a new issue