toward service working on Oreo

Did a bunch of stuff to inherit from JobIntentService and use enqueue(),
but doesn't work yet. OS is unable to bind, with this error:
09-21 17:20:51.678  3050  3050 W JobServiceContext: Time-out while trying to bind 2edee28 #u0a277/1111 org.eehouse.android.xw4dbg/org.eehouse.android.xw4.BTService, dropping.
This commit is contained in:
Eric House 2018-09-22 09:22:37 -07:00
parent 24440230ba
commit 6bafbecd75
8 changed files with 189 additions and 116 deletions

View file

@ -179,8 +179,14 @@
<activity android:name=".loc.LocItemEditActivity"
/>
<service android:name="RelayService"/>
<service android:name="BTService"/>
<service android:name="RelayService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"
/>
<service android:name="BTService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"
/>
<service android:name="SMSService"/>
<receiver android:name=".MountEventReceiver">

View file

@ -29,6 +29,7 @@ import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.JobIntentService;
import junit.framework.Assert;
@ -228,6 +229,8 @@ public class BTService extends XWService {
{
if ( XWApp.BTSUPPORTED ) {
startService( context, new Intent( context, BTService.class ) );
// didn't help
// startService( context, new Intent( /*context, BTService.class*/ ) );
}
}
@ -317,12 +320,19 @@ public class BTService extends XWService {
private static void startService( Context context, Intent intent )
{
context.startService( intent );
Log.d( TAG, "startService(%s)", intent );
if ( false ) {
// requires asking for Manifest.permission.FOREGROUND_SERVICE
context.startForegroundService( intent );
} else {
JobIntentService.enqueueWork( context, BTService.class, 1111, intent );
}
}
private static Intent getIntentTo( Context context, BTAction cmd )
{
Intent intent = new Intent( context, BTService.class );
Intent intent = new Intent( /*context, BTService.class*/ );
intent.putExtra( CMD_KEY, cmd.ordinal() );
return intent;
}
@ -347,6 +357,11 @@ public class BTService extends XWService {
@Override
public int onStartCommand( Intent intent, int flags, int startId )
{
return handleCommand( intent );
}
private int handleCommand( Intent intent )
{
int result;
if ( XWApp.BTSUPPORTED && null != intent ) {
@ -433,7 +448,14 @@ public class BTService extends XWService {
result = Service.START_STICKY_COMPATIBILITY;
}
return result;
} // onStartCommand()
} // handleCommand()
@Override
protected void onHandleWork( Intent intent )
{
Log.e( TAG, "onHandleWork(%s)", intent );
/*(void)*/handleCommand( intent );
}
private class BTListenerThread extends Thread {
private BluetoothServerSocket m_serverSocket;

View file

@ -46,7 +46,6 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
private static final float MIN_FONT_DIPS = 10.0f;
private static final int MULTI_INACTIVE = -1;
private static final int VERSION_CODES_N = 24; // until we're building on SDK 24...
private static boolean s_isFirstDraw;
private static int s_curGameID;
@ -205,7 +204,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
synchronized( this ) {
if ( layoutBoardOnce() && m_measuredFromDims ) {
Bitmap bitmap = s_bitmap;
if ( Build.VERSION.SDK_INT >= VERSION_CODES_N ) {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) {
bitmap = Bitmap.createBitmap(bitmap);
}
canvas.drawBitmap( bitmap, 0, 0, new Paint() );

View file

@ -25,7 +25,6 @@ import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.Bundle;
import android.os.Looper;
import android.text.TextUtils;
import android.text.format.Time;
@ -103,7 +102,7 @@ public class DbgUtils {
public static void assertOnUIThread()
{
Assert.assertTrue( Looper.getMainLooper().equals(Looper.myLooper()) );
Assert.assertTrue( Utils.isOnUIThread() );
}
public static void printStack( String tag, StackTraceElement[] trace )

View file

@ -54,17 +54,21 @@ public class NetStateCache {
public static void register( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.add( proc );
if ( Utils.isOnUIThread() ) {
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.add( proc );
}
}
}
public static void unregister( Context context, StateChangedIf proc )
{
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.remove( proc );
if ( Utils.isOnUIThread() ) {
initIfNot( context );
synchronized( s_ifs ) {
s_ifs.remove( proc );
}
}
}

View file

@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.JobIntentService;
import android.text.TextUtils;
import junit.framework.Assert;
@ -192,13 +193,25 @@ public class RelayService extends XWService
{
Log.i( TAG, "startService()" );
Intent intent = getIntentTo( context, MsgCmds.UDP_CHANGED );
context.startService( intent );
startService( context, intent );
}
private static void startService( Context context, Intent intent )
{
Log.d( TAG, "startService(%s)", intent );
if ( false ) {
// requires asking for Manifest.permission.FOREGROUND_SERVICE
context.startForegroundService( intent );
} else {
JobIntentService.enqueueWork( context, RelayService.class, 1112, intent );
}
}
private static void stopService( Context context )
{
Intent intent = getIntentTo( context, MsgCmds.STOP );
context.startService( intent );
startService( context, intent );
}
public static void inviteRemote( Context context, int destDevID,
@ -206,7 +219,7 @@ public class RelayService extends XWService
{
int myDevID = DevID.getRelayDevIDInt( context );
if ( 0 != myDevID ) {
context.startService( getIntentTo( context, MsgCmds.INVITE )
startService( context, getIntentTo( context, MsgCmds.INVITE )
.putExtra( DEV_ID_SRC, myDevID )
.putExtra( DEV_ID_DEST, destDevID )
.putExtra( RELAY_ID, relayID )
@ -217,13 +230,13 @@ public class RelayService extends XWService
public static void reset( Context context )
{
Intent intent = getIntentTo( context, MsgCmds.RESET );
context.startService( intent );
startService( context, intent );
}
public static void timerFired( Context context )
{
Intent intent = getIntentTo( context, MsgCmds.TIMER_FIRED );
context.startService( intent );
startService( context, intent );
}
public static int sendPacket( Context context, long rowid, byte[] msg )
@ -234,7 +247,7 @@ public class RelayService extends XWService
Intent intent = getIntentTo( context, MsgCmds.SEND )
.putExtra( ROWID, rowid )
.putExtra( BINBUFFER, msg );
context.startService( intent );
startService( context, intent );
result = msg.length;
} else {
Log.w( TAG, "sendPacket: network down" );
@ -251,7 +264,7 @@ public class RelayService extends XWService
.putExtra( ROWID, rowid )
.putExtra( RELAY_ID, relayID )
.putExtra( BINBUFFER, msg );
context.startService( intent );
startService( context, intent );
result = msg.length;
}
return result;
@ -287,7 +300,7 @@ public class RelayService extends XWService
Intent intent = getIntentTo( context, MsgCmds.RECEIVE )
.putExtra( ROWID, rowid )
.putExtra( BINBUFFER, msg );
context.startService( intent );
startService( context, intent );
} else {
Log.w( TAG, "postData(): Dropping message for rowid %d:"
+ " not on device", rowid );
@ -305,14 +318,14 @@ public class RelayService extends XWService
Intent intent = getIntentTo( context, MsgCmds.PROCESS_GAME_MSGS )
.putExtra( MSGS_ARR, msgs64 )
.putExtra( RELAY_ID, relayId );
context.startService( intent );
startService( context, intent );
}
public static void processDevMsgs( Context context, String[] msgs64 )
{
Intent intent = getIntentTo( context, MsgCmds.PROCESS_DEV_MSGS )
.putExtra( MSGS_ARR, msgs64 );
context.startService( intent );
startService( context, intent );
}
private static Intent getIntentTo( Context context, MsgCmds cmd )
@ -356,94 +369,7 @@ public class RelayService extends XWService
@Override
public int onStartCommand( Intent intent, int flags, int startId )
{
Integer result = null;
if ( null != intent ) {
MsgCmds cmd;
try {
cmd = MsgCmds.values()[intent.getIntExtra( CMD_STR, -1 )];
} catch (Exception ex) { // OOB most likely
cmd = null;
}
if ( null != cmd ) {
// Log.d( TAG, "onStartCommand(): cmd=%s", cmd.toString() );
switch( cmd ) {
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 );
}
}
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 SEND:
case RECEIVE:
case SENDNOCONN:
startUDPThreadsIfNot();
long rowid = intent.getLongExtra( ROWID, -1 );
byte[] msg = intent.getByteArrayExtra( BINBUFFER );
if ( MsgCmds.SEND == cmd ) {
sendMessage( rowid, msg );
} else if ( MsgCmds.SENDNOCONN == cmd ) {
String relayID = intent.getStringExtra( RELAY_ID );
sendNoConnMessage( rowid, relayID, msg );
} else {
receiveMessage( this, rowid, null, msg, s_addr );
}
break;
case INVITE:
startUDPThreadsIfNot();
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 );
break;
case TIMER_FIRED:
if ( !NetStateCache.netAvail( this ) ) {
Log.w( TAG, "not connecting: no network" );
} else if ( startFetchThreadIfNotUDP() ) {
// do nothing
} else if ( registerWithRelayIfNot() ) {
requestMessages();
}
RelayReceiver.setTimer( this );
break;
case STOP:
stopThreads();
stopSelf();
break;
default:
Assert.fail();
}
result = Service.START_STICKY;
}
}
Integer result = handleCommand( intent );
if ( null == result ) {
result = Service.START_STICKY_COMPATIBILITY;
@ -465,12 +391,110 @@ public class RelayService extends XWService
super.onDestroy();
}
@Override
protected void onHandleWork( Intent intent )
{
Log.e( TAG, "onHandleWork(%s)", intent );
handleCommand( intent );
}
// NetStateCache.StateChangedIf interface
public void onNetAvail( boolean nowAvailable )
{
startService( this ); // bad name: will *stop* threads too
}
private Integer handleCommand( Intent intent )
{
Integer result = null;
MsgCmds cmd;
try {
cmd = MsgCmds.values()[intent.getIntExtra( CMD_STR, -1 )];
} catch (Exception ex) { // OOB most likely
cmd = null;
}
if ( null != cmd ) {
// Log.d( TAG, "onStartCommand(): cmd=%s", cmd.toString() );
switch( cmd ) {
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 );
}
}
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 SEND:
case RECEIVE:
case SENDNOCONN:
startUDPThreadsIfNot();
long rowid = intent.getLongExtra( ROWID, -1 );
byte[] msg = intent.getByteArrayExtra( BINBUFFER );
if ( MsgCmds.SEND == cmd ) {
sendMessage( rowid, msg );
} else if ( MsgCmds.SENDNOCONN == cmd ) {
String relayID = intent.getStringExtra( RELAY_ID );
sendNoConnMessage( rowid, relayID, msg );
} else {
receiveMessage( this, rowid, null, msg, s_addr );
}
break;
case INVITE:
startUDPThreadsIfNot();
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 );
break;
case TIMER_FIRED:
if ( !NetStateCache.netAvail( this ) ) {
Log.w( TAG, "not connecting: no network" );
} else if ( startFetchThreadIfNotUDP() ) {
// do nothing
} else if ( registerWithRelayIfNot() ) {
requestMessages();
}
RelayReceiver.setTimer( this );
break;
case STOP:
stopThreads();
stopSelf();
break;
default:
Assert.fail();
}
result = Service.START_STICKY;
}
return result;
}
private void setupNotifications( String[] relayIDs, BackMoveResult[] bmrs,
ArrayList<Boolean> locals )
{

View file

@ -40,6 +40,7 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Looper;
import android.provider.ContactsContract.PhoneLookup;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.FileProvider;
@ -533,6 +534,11 @@ public class Utils {
return result;
}
public static boolean isOnUIThread()
{
return Looper.getMainLooper().equals(Looper.myLooper());
}
public static String base64Encode( byte[] in )
{
return Base64.encodeToString( in, Base64.NO_WRAP );

View file

@ -23,7 +23,9 @@ package org.eehouse.android.xw4;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.JobIntentService;
import junit.framework.Assert;
@ -37,7 +39,7 @@ import org.eehouse.android.xw4.jni.UtilCtxtImpl;
import java.util.HashSet;
import java.util.Set;
abstract class XWService extends Service {
abstract class XWService extends JobIntentService {
private static final String TAG = XWService.class.getSimpleName();
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
@ -46,10 +48,21 @@ abstract class XWService extends Service {
private UtilCtxt m_utilCtxt;
// @Override
// public IBinder onBind( Intent intent )
// {
// IBinder result = null;
// if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ) {
// result = super.onBind( intent );
// }
// return result;
// }
@Override
public IBinder onBind( Intent intent )
protected void onHandleWork(Intent intent)
{
return null;
Log.e( TAG, "%s.onHandleWork(%s); dropping!!!", getClass().getSimpleName(),
intent );
}
public final static void setListener( MultiService.MultiEventListener li )