5
5
import com .jpage4500 .devicemanager .data .LogEntry ;
6
6
import com .jpage4500 .devicemanager .ui .dialog .ConnectDialog ;
7
7
import com .jpage4500 .devicemanager .ui .dialog .SettingsDialog ;
8
- import com .jpage4500 .devicemanager .utils .Timer ;
9
8
import com .jpage4500 .devicemanager .utils .*;
9
+ import com .jpage4500 .devicemanager .utils .Timer ;
10
10
import se .vidstige .jadb .*;
11
11
import se .vidstige .jadb .managers .PackageManager ;
12
12
import se .vidstige .jadb .managers .PropertyManager ;
@@ -61,6 +61,8 @@ public class DeviceManager {
61
61
62
62
// how frequently to update logs
63
63
public static final int LOG_INTERVAL_MS = 100 ;
64
+ // how frequently to refresh device list
65
+ public static final int DEVICE_REFRESH_MINS = 60 ;
64
66
65
67
public static final String CUSTOM_KEY_VERSION = "VER" ;
66
68
public static final String CUSTOM_KEY_PROP = "PROP" ;
@@ -69,11 +71,14 @@ public class DeviceManager {
69
71
70
72
private static volatile DeviceManager instance ;
71
73
74
+ private DeviceListener deviceListener ;
72
75
private final List <Device > deviceList ;
73
76
private final String tempFolder ;
74
77
private final List <Process > processList ;
75
78
79
+ // thread pool for running commands
76
80
private final ExecutorService commandExecutorService ;
81
+ // thread pool for fetching device details
77
82
private final ScheduledExecutorService scheduledExecutorService ;
78
83
private ScheduledFuture <?> deviceRefreshRuture ;
79
84
@@ -97,12 +102,16 @@ private DeviceManager() {
97
102
processList = new ArrayList <>();
98
103
99
104
commandExecutorService = Executors .newFixedThreadPool (10 );
100
- scheduledExecutorService = Executors .newScheduledThreadPool (3 );
105
+ scheduledExecutorService = Executors .newScheduledThreadPool (1 );
101
106
102
107
tempFolder = Utils .getTempFolder ();
103
108
copyResourcesToFiles ();
104
109
}
105
110
111
+ public void setDeviceListener (DeviceListener listener ) {
112
+ this .deviceListener = listener ;
113
+ }
114
+
106
115
public interface DeviceListener {
107
116
// device list was refreshed
108
117
void handleDevicesUpdated (List <Device > deviceList );
@@ -116,7 +125,7 @@ public interface DeviceListener {
116
125
void handleException (Exception e );
117
126
}
118
127
119
- public void connectAdbServer (boolean allowRetry , DeviceManager . DeviceListener listener ) {
128
+ public void connectAdbServer (boolean allowRetry ) {
120
129
connection = new JadbConnection ();
121
130
commandExecutorService .submit (() -> {
122
131
try {
@@ -125,26 +134,26 @@ public void connectAdbServer(boolean allowRetry, DeviceManager.DeviceListener li
125
134
connection .createDeviceWatcher (new DeviceDetectionListener () {
126
135
@ Override
127
136
public void onDetect (List <JadbDevice > devices ) {
128
- handleDeviceUpdate (devices , listener );
137
+ handleDeviceUpdate (devices );
129
138
}
130
139
131
140
@ Override
132
141
public void onException (Exception e ) {
133
142
log .error ("connectAdbServer: onException: {}" , e .getMessage ());
134
143
// change all devices to offline
135
144
for (Device device : deviceList ) device .isOnline = false ;
136
- listener .handleException (e );
145
+ if ( deviceListener != null ) deviceListener .handleException (e );
137
146
}
138
147
}).run ();
139
148
} catch (Exception e ) {
140
149
log .error ("connectAdbServer: Exception: {}" , e .getMessage ());
141
150
// likley because adb server isn't running.. try to start it now
142
151
startServer ((isSuccess , error ) -> {
143
- if (isSuccess && allowRetry ) connectAdbServer (false , listener );
152
+ if (isSuccess && allowRetry ) connectAdbServer (false );
144
153
else {
145
154
// change all devices to offline
146
155
for (Device device : deviceList ) device .isOnline = false ;
147
- listener .handleException (e );
156
+ if ( deviceListener != null ) deviceListener .handleException (e );
148
157
}
149
158
});
150
159
}
@@ -155,7 +164,7 @@ public void onException(Exception e) {
155
164
* called when a device is added/updated/removed
156
165
* NOTE: run on background thread
157
166
*/
158
- private void handleDeviceUpdate (List <JadbDevice > devices , DeviceListener listener ) {
167
+ private void handleDeviceUpdate (List <JadbDevice > devices ) {
159
168
//log.debug("onDetect: GOT:{}, {}", devices.size(), GsonHelper.toJson(devices));
160
169
List <Device > addedDeviceList = new ArrayList <>();
161
170
@@ -195,13 +204,13 @@ private void handleDeviceUpdate(List<JadbDevice> devices, DeviceListener listene
195
204
// -- DEVICE REMOVED --
196
205
device .isOnline = false ;
197
206
device .lastUpdateMs = System .currentTimeMillis ();
198
- listener .handleDeviceRemoved (device );
207
+ if ( deviceListener != null ) deviceListener .handleDeviceRemoved (device );
199
208
}
200
209
}
201
210
202
211
if (!addedDeviceList .isEmpty ()) {
203
212
// notify listener that device list changed
204
- listener .handleDevicesUpdated (deviceList );
213
+ if ( deviceListener != null ) deviceListener .handleDevicesUpdated (deviceList );
205
214
206
215
for (Device addedDevice : addedDeviceList ) {
207
216
// fetch more details for these devices
@@ -212,12 +221,12 @@ private void handleDeviceUpdate(List<JadbDevice> devices, DeviceListener listene
212
221
addedDevice .isOnline = true ;
213
222
addedDevice .status = null ;
214
223
addedDevice .lastUpdateMs = System .currentTimeMillis ();
215
- listener . handleDeviceUpdated (addedDevice );
216
- fetchDeviceDetails (addedDevice , true , listener );
224
+ notifyDeviceUpdated (addedDevice );
225
+ fetchDeviceDetails (addedDevice , true );
217
226
} else {
218
227
log .debug ("handleDeviceUpdate: NOT_READY: {} -> {}" , addedDevice .serial , state );
219
228
addedDevice .status = state .name ();
220
- listener . handleDeviceUpdated (addedDevice );
229
+ notifyDeviceUpdated (addedDevice );
221
230
}
222
231
} catch (Exception e ) {
223
232
String errMsg = e .getMessage ();
@@ -231,26 +240,35 @@ private void handleDeviceUpdate(List<JadbDevice> devices, DeviceListener listene
231
240
addedDevice .status = errMsg ;
232
241
// TODO: check error message before setting device to offline?
233
242
addedDevice .isOnline = false ;
234
- listener . handleDeviceUpdated (addedDevice );
243
+ notifyDeviceUpdated (addedDevice );
235
244
}
236
245
}
237
246
238
- // run periodic task to update device state
239
247
if (deviceRefreshRuture == null ) {
240
- deviceRefreshRuture = scheduledExecutorService .scheduleWithFixedDelay (() -> {
241
- //log.trace("handleDeviceUpdate: REFRESH");
242
- for (Device device : deviceList ) {
243
- fetchDeviceDetails (device , false , listener );
244
- }
245
- }, 5 , 5 , TimeUnit .MINUTES );
248
+ updateRefreshTime ();
246
249
}
247
250
}
248
251
}
249
252
250
- public void refreshDevices (DeviceListener listener ) {
253
+ public void updateRefreshTime () {
254
+ if (deviceRefreshRuture != null ) {
255
+ deviceRefreshRuture .cancel (true );
256
+ }
257
+ int refreshTimeMins = PreferenceUtils .getPreference (PreferenceUtils .PrefInt .PREF_REFRESH_TIME_MINS , DeviceManager .DEVICE_REFRESH_MINS );
258
+ // run periodic task to update device state
259
+ log .debug ("updateRefreshTime: schedule refresh every {} mins" , refreshTimeMins );
260
+ deviceRefreshRuture = scheduledExecutorService .scheduleWithFixedDelay (() -> {
261
+ log .trace ("handleDeviceUpdate: REFRESH" );
262
+ for (Device device : deviceList ) {
263
+ fetchDeviceDetails (device , false );
264
+ }
265
+ }, refreshTimeMins , refreshTimeMins , TimeUnit .MINUTES );
266
+ }
267
+
268
+ public void refreshDevices () {
251
269
synchronized (deviceList ) {
252
270
for (Device device : deviceList ) {
253
- fetchDeviceDetails (device , true , listener );
271
+ fetchDeviceDetails (device , true );
254
272
}
255
273
}
256
274
}
@@ -260,24 +278,24 @@ public void refreshDevices(DeviceListener listener) {
260
278
*
261
279
* @param fullRefresh - true to fetch everythign; false to only fetch values that would change often (battery, disk)
262
280
*/
263
- private void fetchDeviceDetails (Device device , boolean fullRefresh , DeviceListener listener ) {
281
+ private void fetchDeviceDetails (Device device , boolean fullRefresh ) {
264
282
if (!device .isOnline ) return ;
265
- commandExecutorService .submit (() -> {
283
+ scheduledExecutorService .submit (() -> {
266
284
Timer timer = new Timer ();
267
285
// show device as 'busy'
268
286
device .setBusy (true );
269
- listener . handleDeviceUpdated (device );
287
+ notifyDeviceUpdated (device );
270
288
271
289
// check if device is fully booted
272
290
fetchDeviceBooted (device );
273
291
if (!device .isBooted ) {
274
292
boolean isBusy = device .setBusy (false );
275
- if (!isBusy ) listener . handleDeviceUpdated (device );
293
+ if (!isBusy ) notifyDeviceUpdated (device );
276
294
277
295
// if device isn't fully booted yet, schedule another refresh
278
296
scheduledExecutorService .schedule (() -> {
279
297
log .trace ("fetchDeviceDetails: try again for {}" , device .getDisplayName ());
280
- fetchDeviceDetails (device , true , listener );
298
+ fetchDeviceDetails (device , true );
281
299
}, 5 , TimeUnit .SECONDS );
282
300
return ;
283
301
}
@@ -309,7 +327,10 @@ private void fetchDeviceDetails(Device device, boolean fullRefresh, DeviceListen
309
327
310
328
// -- IMEI --
311
329
String imei = runShellServiceCall (device , COMMAND_SERVICE_IMEI );
312
- if (TextUtils .notEmpty (imei )) device .imei = imei ;
330
+ if (TextUtils .notEmpty (imei )) {
331
+ device .imei = imei ;
332
+ notifyDeviceUpdated (device );
333
+ }
313
334
} catch (Exception e ) {
314
335
// not a phone (tablet, TV, etc)
315
336
}
@@ -337,10 +358,16 @@ private void fetchDeviceDetails(Device device, boolean fullRefresh, DeviceListen
337
358
if (log .isTraceEnabled ()) log .trace ("fetchDeviceDetails: REFRESH:{}: {}" , timer , GsonHelper .toJson (device ));
338
359
}
339
360
boolean isBusy = device .setBusy (false );
340
- if (!isBusy ) listener . handleDeviceUpdated (device );
361
+ if (!isBusy ) notifyDeviceUpdated (device );
341
362
});
342
363
}
343
364
365
+ private void notifyDeviceUpdated (Device device ) {
366
+ if (deviceListener != null ) {
367
+ deviceListener .handleDeviceUpdated (device );
368
+ }
369
+ }
370
+
344
371
/**
345
372
* check if device is fully booted
346
373
*/
@@ -386,6 +413,7 @@ private void fetchBatteryInfo(Device device) {
386
413
break ;
387
414
}
388
415
}
416
+ notifyDeviceUpdated (device );
389
417
}
390
418
391
419
private void fetchCustomColumns (Device device ) {
@@ -438,6 +466,7 @@ private void fetchCustomColumns(Device device) {
438
466
if (value != null ) {
439
467
if (device .customAppVersionList == null ) device .customAppVersionList = new HashMap <>();
440
468
device .customAppVersionList .put (label , value );
469
+ notifyDeviceUpdated (device );
441
470
}
442
471
}
443
472
int afterSize = device .customAppVersionList != null ? device .customAppVersionList .size () : 0 ;
@@ -457,6 +486,7 @@ private void fetchFreeDiskSpace(Device device) {
457
486
try {
458
487
// size is in 1k blocks
459
488
device .freeSpace = Long .parseLong (size ) * 1000L ;
489
+ notifyDeviceUpdated (device );
460
490
return ;
461
491
} catch (Exception e ) {
462
492
log .trace ("fetchDeviceDetails: FREE_SPACE Exception:{}" , e .getMessage ());
@@ -500,6 +530,7 @@ private void fetchNickname(Device device) {
500
530
return ;
501
531
}
502
532
device .nickname = nickname ;
533
+ notifyDeviceUpdated (device );
503
534
}
504
535
}
505
536
0 commit comments