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" <activity android:name=".loc.LocItemEditActivity"
/> />
<service android:name="RelayService"/> <service android:name="RelayService"
<service android:name="BTService"/> 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"/> <service android:name="SMSService"/>
<receiver android:name=".MountEventReceiver"> <receiver android:name=".MountEventReceiver">

View file

@ -29,6 +29,7 @@ import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.JobIntentService;
import junit.framework.Assert; import junit.framework.Assert;
@ -228,6 +229,8 @@ public class BTService extends XWService {
{ {
if ( XWApp.BTSUPPORTED ) { if ( XWApp.BTSUPPORTED ) {
startService( context, new Intent( context, BTService.class ) ); 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 ) 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 ) 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() ); intent.putExtra( CMD_KEY, cmd.ordinal() );
return intent; return intent;
} }
@ -347,6 +357,11 @@ public class BTService extends XWService {
@Override @Override
public int onStartCommand( Intent intent, int flags, int startId ) public int onStartCommand( Intent intent, int flags, int startId )
{
return handleCommand( intent );
}
private int handleCommand( Intent intent )
{ {
int result; int result;
if ( XWApp.BTSUPPORTED && null != intent ) { if ( XWApp.BTSUPPORTED && null != intent ) {
@ -433,7 +448,14 @@ public class BTService extends XWService {
result = Service.START_STICKY_COMPATIBILITY; result = Service.START_STICKY_COMPATIBILITY;
} }
return result; 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 class BTListenerThread extends Thread {
private BluetoothServerSocket m_serverSocket; 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 float MIN_FONT_DIPS = 10.0f;
private static final int MULTI_INACTIVE = -1; 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 boolean s_isFirstDraw;
private static int s_curGameID; private static int s_curGameID;
@ -205,7 +204,7 @@ public class BoardView extends View implements BoardHandler, SyncedDraw {
synchronized( this ) { synchronized( this ) {
if ( layoutBoardOnce() && m_measuredFromDims ) { if ( layoutBoardOnce() && m_measuredFromDims ) {
Bitmap bitmap = s_bitmap; 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); bitmap = Bitmap.createBitmap(bitmap);
} }
canvas.drawBitmap( bitmap, 0, 0, new Paint() ); canvas.drawBitmap( bitmap, 0, 0, new Paint() );

View file

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

View file

@ -54,19 +54,23 @@ public class NetStateCache {
public static void register( Context context, StateChangedIf proc ) public static void register( Context context, StateChangedIf proc )
{ {
if ( Utils.isOnUIThread() ) {
initIfNot( context ); initIfNot( context );
synchronized( s_ifs ) { synchronized( s_ifs ) {
s_ifs.add( proc ); s_ifs.add( proc );
} }
} }
}
public static void unregister( Context context, StateChangedIf proc ) public static void unregister( Context context, StateChangedIf proc )
{ {
if ( Utils.isOnUIThread() ) {
initIfNot( context ); initIfNot( context );
synchronized( s_ifs ) { synchronized( s_ifs ) {
s_ifs.remove( proc ); s_ifs.remove( proc );
} }
} }
}
static long s_lastNetCheck = 0; static long s_lastNetCheck = 0;
public static boolean netAvail( Context context ) public static boolean netAvail( Context context )

View file

@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.support.v4.app.JobIntentService;
import android.text.TextUtils; import android.text.TextUtils;
import junit.framework.Assert; import junit.framework.Assert;
@ -192,13 +193,25 @@ public class RelayService extends XWService
{ {
Log.i( TAG, "startService()" ); Log.i( TAG, "startService()" );
Intent intent = getIntentTo( context, MsgCmds.UDP_CHANGED ); 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 ) private static void stopService( Context context )
{ {
Intent intent = getIntentTo( context, MsgCmds.STOP ); Intent intent = getIntentTo( context, MsgCmds.STOP );
context.startService( intent ); startService( context, intent );
} }
public static void inviteRemote( Context context, int destDevID, public static void inviteRemote( Context context, int destDevID,
@ -206,7 +219,7 @@ public class RelayService extends XWService
{ {
int myDevID = DevID.getRelayDevIDInt( context ); int myDevID = DevID.getRelayDevIDInt( context );
if ( 0 != myDevID ) { if ( 0 != myDevID ) {
context.startService( getIntentTo( context, MsgCmds.INVITE ) startService( context, getIntentTo( context, MsgCmds.INVITE )
.putExtra( DEV_ID_SRC, myDevID ) .putExtra( DEV_ID_SRC, myDevID )
.putExtra( DEV_ID_DEST, destDevID ) .putExtra( DEV_ID_DEST, destDevID )
.putExtra( RELAY_ID, relayID ) .putExtra( RELAY_ID, relayID )
@ -217,13 +230,13 @@ public class RelayService extends XWService
public static void reset( Context context ) public static void reset( Context context )
{ {
Intent intent = getIntentTo( context, MsgCmds.RESET ); Intent intent = getIntentTo( context, MsgCmds.RESET );
context.startService( intent ); startService( context, intent );
} }
public static void timerFired( Context context ) public static void timerFired( Context context )
{ {
Intent intent = getIntentTo( context, MsgCmds.TIMER_FIRED ); Intent intent = getIntentTo( context, MsgCmds.TIMER_FIRED );
context.startService( intent ); startService( context, intent );
} }
public static int sendPacket( Context context, long rowid, byte[] msg ) 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 ) Intent intent = getIntentTo( context, MsgCmds.SEND )
.putExtra( ROWID, rowid ) .putExtra( ROWID, rowid )
.putExtra( BINBUFFER, msg ); .putExtra( BINBUFFER, msg );
context.startService( intent ); startService( context, intent );
result = msg.length; result = msg.length;
} else { } else {
Log.w( TAG, "sendPacket: network down" ); Log.w( TAG, "sendPacket: network down" );
@ -251,7 +264,7 @@ public class RelayService extends XWService
.putExtra( ROWID, rowid ) .putExtra( ROWID, rowid )
.putExtra( RELAY_ID, relayID ) .putExtra( RELAY_ID, relayID )
.putExtra( BINBUFFER, msg ); .putExtra( BINBUFFER, msg );
context.startService( intent ); startService( context, intent );
result = msg.length; result = msg.length;
} }
return result; return result;
@ -287,7 +300,7 @@ public class RelayService extends XWService
Intent intent = getIntentTo( context, MsgCmds.RECEIVE ) Intent intent = getIntentTo( context, MsgCmds.RECEIVE )
.putExtra( ROWID, rowid ) .putExtra( ROWID, rowid )
.putExtra( BINBUFFER, msg ); .putExtra( BINBUFFER, msg );
context.startService( intent ); startService( context, intent );
} else { } else {
Log.w( TAG, "postData(): Dropping message for rowid %d:" Log.w( TAG, "postData(): Dropping message for rowid %d:"
+ " not on device", rowid ); + " not on device", rowid );
@ -305,14 +318,14 @@ public class RelayService extends XWService
Intent intent = getIntentTo( context, MsgCmds.PROCESS_GAME_MSGS ) Intent intent = getIntentTo( context, MsgCmds.PROCESS_GAME_MSGS )
.putExtra( MSGS_ARR, msgs64 ) .putExtra( MSGS_ARR, msgs64 )
.putExtra( RELAY_ID, relayId ); .putExtra( RELAY_ID, relayId );
context.startService( intent ); startService( context, intent );
} }
public static void processDevMsgs( Context context, String[] msgs64 ) public static void processDevMsgs( Context context, String[] msgs64 )
{ {
Intent intent = getIntentTo( context, MsgCmds.PROCESS_DEV_MSGS ) Intent intent = getIntentTo( context, MsgCmds.PROCESS_DEV_MSGS )
.putExtra( MSGS_ARR, msgs64 ); .putExtra( MSGS_ARR, msgs64 );
context.startService( intent ); startService( context, intent );
} }
private static Intent getIntentTo( Context context, MsgCmds cmd ) private static Intent getIntentTo( Context context, MsgCmds cmd )
@ -355,9 +368,45 @@ public class RelayService extends XWService
@Override @Override
public int onStartCommand( Intent intent, int flags, int startId ) public int onStartCommand( Intent intent, int flags, int startId )
{
Integer result = handleCommand( intent );
if ( null == result ) {
result = Service.START_STICKY_COMPATIBILITY;
}
NetStateCache.register( this, this );
resetExitTimer();
return result;
}
@Override
public void onDestroy()
{
if ( shouldMaintainConnection() ) {
long interval_millis = getMaxIntervalSeconds() * 1000;
RelayReceiver.setTimer( this, interval_millis );
}
stopThreads();
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; Integer result = null;
if ( null != intent ) {
MsgCmds cmd; MsgCmds cmd;
try { try {
cmd = MsgCmds.values()[intent.getIntExtra( CMD_STR, -1 )]; cmd = MsgCmds.values()[intent.getIntExtra( CMD_STR, -1 )];
@ -443,34 +492,9 @@ public class RelayService extends XWService
result = Service.START_STICKY; result = Service.START_STICKY;
} }
}
if ( null == result ) {
result = Service.START_STICKY_COMPATIBILITY;
}
NetStateCache.register( this, this );
resetExitTimer();
return result; return result;
} }
@Override
public void onDestroy()
{
if ( shouldMaintainConnection() ) {
long interval_millis = getMaxIntervalSeconds() * 1000;
RelayReceiver.setTimer( this, interval_millis );
}
stopThreads();
super.onDestroy();
}
// NetStateCache.StateChangedIf interface
public void onNetAvail( boolean nowAvailable )
{
startService( this ); // bad name: will *stop* threads too
}
private void setupNotifications( String[] relayIDs, BackMoveResult[] bmrs, private void setupNotifications( String[] relayIDs, BackMoveResult[] bmrs,
ArrayList<Boolean> locals ) ArrayList<Boolean> locals )
{ {

View file

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

View file

@ -23,7 +23,9 @@ package org.eehouse.android.xw4;
import android.app.Service; import android.app.Service;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.IBinder; import android.os.IBinder;
import android.support.v4.app.JobIntentService;
import junit.framework.Assert; import junit.framework.Assert;
@ -37,7 +39,7 @@ import org.eehouse.android.xw4.jni.UtilCtxtImpl;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
abstract class XWService extends Service { abstract class XWService extends JobIntentService {
private static final String TAG = XWService.class.getSimpleName(); private static final String TAG = XWService.class.getSimpleName();
public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED }; public static enum ReceiveResult { OK, GAME_GONE, UNCONSUMED };
@ -46,10 +48,21 @@ abstract class XWService extends Service {
private UtilCtxt m_utilCtxt; 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 @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 ) public final static void setListener( MultiService.MultiEventListener li )