2
2
3
3
import com .jpage4500 .devicemanager .MainApplication ;
4
4
import com .jpage4500 .devicemanager .data .Device ;
5
+ import com .jpage4500 .devicemanager .data .DeviceFile ;
5
6
import com .jpage4500 .devicemanager .data .GithubRelease ;
6
7
import com .jpage4500 .devicemanager .logging .AppLoggerFactory ;
7
8
import com .jpage4500 .devicemanager .manager .DeviceManager ;
@@ -51,6 +52,7 @@ public class DeviceScreen extends BaseScreen implements DeviceManager.DeviceList
51
52
// update check for github releases
52
53
public static final String UPDATE_SOURCE_GITHUB = "https://api.github.com/repos/jpage4500/AndroidDeviceManager/releases" ;
53
54
public static final String URL_GITHUB = "https://github.com/jpage4500/AndroidDeviceManager/releases" ;
55
+ public static final String PACKAGE_PREFIX = "package:" ;
54
56
55
57
public CustomTable table ;
56
58
public DeviceTableModel model ;
@@ -276,17 +278,19 @@ public void setupTable() {
276
278
model = new DeviceTableModel ();
277
279
278
280
// restore previous settings
279
- List <String > appList = SettingsDialog .getCustomApps ();
280
- model .setAppList (appList );
281
+ setCustomColumns ();
281
282
282
283
List <String > hiddenColList = SettingsDialog .getHiddenColumnList ();
283
284
model .setHiddenColumns (hiddenColList );
284
285
285
- //table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
286
286
table .setModel (model );
287
287
table .setDefaultRenderer (Device .class , new DeviceCellRenderer ());
288
288
table .setEmptyText ("No Connected Devices!" );
289
289
290
+ boolean autoResize = PreferenceUtils .getPreference (PreferenceUtils .PrefBoolean .PREF_DEVICE_AUTO_RESIZE , true );
291
+ int flag = autoResize ? JTable .AUTO_RESIZE_ALL_COLUMNS : JTable .AUTO_RESIZE_OFF ;
292
+ table .setAutoResizeMode (flag );
293
+
290
294
// restore user-defined column sizes
291
295
if (!table .restoreTable ()) {
292
296
// use some default column sizes
@@ -346,6 +350,18 @@ public void setupTable() {
346
350
filterTextField .setupSearch (table );
347
351
}
348
352
353
+ public void setCustomColumns () {
354
+ List <String > entryList = SettingsDialog .getCustomColumns ();
355
+ List <String > nameList = new ArrayList <>();
356
+ for (String entry : entryList ) {
357
+ if (TextUtils .isEmpty (entry ) || TextUtils .startsWithAny (entry , false , "#" , "//" )) continue ;
358
+ String [] entryArr = entry .split (":" );
359
+ String label = entryArr .length >= 1 ? entryArr [0 ].trim () : entry ;
360
+ nameList .add (label );
361
+ }
362
+ model .setCustomColumnList (nameList );
363
+ }
364
+
349
365
/**
350
366
* @return PopupMenu to display or null
351
367
*/
@@ -355,15 +371,33 @@ private JPopupMenu getPopupMenu(int row, int column) {
355
371
JPopupMenu popupMenu = new JPopupMenu ();
356
372
DeviceTableModel .Columns columnType = model .getColumnType (column );
357
373
if (columnType != null ) {
374
+ // standard columns (all others are custom)
358
375
UiUtils .addPopupMenuItem (popupMenu , "Hide " + columnType .name (), actionEvent -> handleHideColumn (column ));
359
- UiUtils .addPopupMenuItem (popupMenu , "Size to Fit" , actionEvent -> {
376
+ }
377
+ UiUtils .addPopupMenuItem (popupMenu , "Size to Fit" , actionEvent -> {
378
+ TableColumnAdjuster adjuster = new TableColumnAdjuster (table , 0 );
379
+ adjuster .adjustColumn (column );
380
+ });
381
+
382
+ popupMenu .addSeparator ();
383
+
384
+ UiUtils .addPopupMenuItem (popupMenu , "Manage Columns" , actionEvent -> SettingsDialog .showManageDeviceColumnsDialog (this ));
385
+
386
+ boolean autoResize = PreferenceUtils .getPreference (PreferenceUtils .PrefBoolean .PREF_DEVICE_AUTO_RESIZE , true );
387
+ String resizeDesc = autoResize ? "ON" : "OFF" ;
388
+ UiUtils .addPopupMenuItem (popupMenu , "Auto Resize: " + resizeDesc , actionEvent -> {
389
+ boolean update = !autoResize ;
390
+ PreferenceUtils .setPreference (PreferenceUtils .PrefBoolean .PREF_DEVICE_AUTO_RESIZE , update );
391
+ int flag = update ? JTable .AUTO_RESIZE_ALL_COLUMNS : JTable .AUTO_RESIZE_OFF ;
392
+ table .setAutoResizeMode (flag );
393
+ });
394
+ if (!autoResize ) {
395
+ UiUtils .addPopupMenuItem (popupMenu , "Size ALL to Fit" , actionEvent -> {
360
396
TableColumnAdjuster adjuster = new TableColumnAdjuster (table , 0 );
361
- adjuster .adjustColumn ( column );
397
+ adjuster .adjustColumns ( );
362
398
});
363
- UiUtils .addPopupMenuItem (popupMenu , "Manage Columns" , actionEvent -> SettingsDialog .showManageDeviceColumnsDialog (this ));
364
- return popupMenu ;
365
399
}
366
- return null ;
400
+ return popupMenu ;
367
401
}
368
402
Device device = model .getDeviceAtRow (row );
369
403
if (device == null ) return null ;
@@ -485,7 +519,6 @@ public void handleDeviceRemoved(Device device) {
485
519
updateDeviceState (device );
486
520
sorter .sort ();
487
521
});
488
-
489
522
}
490
523
491
524
@ Override
@@ -683,10 +716,10 @@ public void handleFilesDropped(List<File> fileList) {
683
716
return ;
684
717
}
685
718
log .debug ("handleFilesDropped: {}, #devices:{}" , fileList , selectedDeviceList .size ());
686
- installOrCopyFiles (selectedDeviceList , fileList , null );
719
+ installOrCopyFiles (selectedDeviceList , fileList );
687
720
}
688
721
689
- public void installOrCopyFiles (List <Device > selectedDeviceList , List <File > fileList , DeviceManager . TaskListener listener ) {
722
+ public void installOrCopyFiles (List <Device > selectedDeviceList , List <File > fileList ) {
690
723
FileUtils .FileStats stats = FileUtils .getFileStats (fileList );
691
724
// if all files are .apk, do install instead of copy
692
725
boolean isInstall = stats .numApk == stats .numTotal ;
@@ -701,14 +734,16 @@ public void installOrCopyFiles(List<Device> selectedDeviceList, List<File> fileL
701
734
dialog .setAlwaysOnTop (true );
702
735
if (!DialogHelper .showConfirmDialog (this , title , msg )) return ;
703
736
if (isInstall ) {
704
- installFiles (selectedDeviceList , fileList , listener );
737
+ installFiles (selectedDeviceList , fileList );
705
738
} else {
706
- copyFiles (selectedDeviceList , fileList , listener );
739
+ copyFiles (selectedDeviceList , fileList );
707
740
}
708
741
}
709
742
710
- private void copyFiles (List <Device > selectedDeviceList , List <File > fileList , DeviceManager .TaskListener listener ) {
711
- ResultWatcher resultWatcher = new ResultWatcher (getRootPane (), selectedDeviceList .size (), listener );
743
+ private void copyFiles (List <Device > selectedDeviceList , List <File > fileList ) {
744
+ ResultWatcher resultWatcher = new ResultWatcher (getRootPane (), selectedDeviceList .size (), (isSuccess , error ) -> {
745
+
746
+ });
712
747
String desc = String .format ("Copying %d file(s) to %d device(s)" , fileList .size (), selectedDeviceList .size ());
713
748
resultWatcher .setDesc (desc );
714
749
// TODO: where to put files on device?
@@ -724,8 +759,15 @@ private void copyFiles(List<Device> selectedDeviceList, List<File> fileList, Dev
724
759
}
725
760
}
726
761
727
- private void installFiles (List <Device > selectedDeviceList , List <File > apkList , DeviceManager .TaskListener listener ) {
728
- ResultWatcher resultWatcher = new ResultWatcher (getRootPane (), selectedDeviceList .size () * apkList .size (), listener );
762
+ private void installFiles (List <Device > selectedDeviceList , List <File > apkList ) {
763
+ ResultWatcher resultWatcher = new ResultWatcher (getRootPane (), selectedDeviceList .size () * apkList .size (), (isSuccess , error ) -> {
764
+ if (isSuccess ) {
765
+ // TODO: prompt to open app
766
+ // - requires figuring out the package name from .apk (aapt2?)
767
+ } else {
768
+ DialogHelper .showDialog (this , "Install Failed" , error );
769
+ }
770
+ });
729
771
for (Device device : selectedDeviceList ) {
730
772
for (File file : apkList ) {
731
773
String filename = file .getName ();
@@ -886,22 +928,68 @@ private void handleDeviceDetails(Device device) {
886
928
private void showInstalledApps (Device device ) {
887
929
if (device == null ) return ;
888
930
DeviceManager .getInstance ().getInstalledApps (device , appSet -> {
889
- final Map <String , String > appMep = new TreeMap <>();
931
+ final Map <String , String > appMap = new TreeMap <>(String . CASE_INSENSITIVE_ORDER );
890
932
// convert set to map
891
- for (String app : appSet ) appMep .put (app , null );
892
- DialogHelper .showListDialog (this , "Installed Apps" , appMep , (key , value ) -> {
893
- log .trace ("showInstalledApps: click: {}" , key );
894
- DeviceManager .getInstance ().fetchAppVersion (device , key , version -> {
895
- String text = String .format ("%s = %s" , key , version );
896
- DialogHelper .showTextDialog (this , key , text );
897
- });
933
+ for (String app : appSet ) appMap .put (app , null );
934
+ DialogHelper .showListDialog (this , "Installed Apps" , appMap , new DialogHelper .ListListener () {
935
+ @ Override
936
+ public void handleDoubleClick (String key , String value ) {
937
+ log .trace ("showInstalledApps: click: {}" , key );
938
+ DeviceManager .getInstance ().fetchAppVersion (device , key , version -> {
939
+ String text = String .format ("%s = %s" , key , version );
940
+ DialogHelper .showTextDialog (DeviceScreen .this , key , text );
941
+ });
942
+ }
943
+
944
+ @ Override
945
+ public void handleRightClick (String key , String value , JPopupMenu popupMenu ) {
946
+ UiUtils .addPopupMenuItem (popupMenu , "Download App" , actionEvent -> {
947
+ extractApk (device , key );
948
+ });
949
+ }
898
950
});
899
951
});
900
952
}
901
953
954
+ private void extractApk (Device device , String key ) {
955
+ String command = "pm path " + key ;
956
+ DeviceManager deviceManager = DeviceManager .getInstance ();
957
+ deviceManager .runCustomCommand (device , command , (result ) -> {
958
+ if (!result .isSuccess ) {
959
+ String msg = "Unable to download " + key + "\n \n " + result ;
960
+ DialogHelper .showDialog (this , "Error" , msg );
961
+ return ;
962
+ }
963
+ // download to new folder
964
+ String downloadFolder = Utils .getDownloadFolder ();
965
+ File appFolder = new File (downloadFolder , key );
966
+ appFolder .mkdirs ();
967
+
968
+ for (String path : result .resultList ) {
969
+ if (!TextUtils .startsWith (path , PACKAGE_PREFIX )) {
970
+ log .trace ("extractApk: BAD LINE: {}" , path );
971
+ continue ;
972
+ }
973
+ path = path .substring (PACKAGE_PREFIX .length ());
974
+ int pos = path .lastIndexOf ('/' );
975
+ if (pos < 1 ) continue ;
976
+ DeviceFile file = new DeviceFile ();
977
+ file .name = path .substring (pos + 1 );
978
+ path = path .substring (0 , pos );
979
+
980
+ File saveFile = new File (appFolder , file .name );
981
+ deviceManager .downloadFile (device , path , file , saveFile , (isSuccess , error ) -> {
982
+ log .trace ("extractApk: {}: {}" , isSuccess , error );
983
+ });
984
+ }
985
+ });
986
+ }
987
+
902
988
private void showDeviceProperties (Device device ) {
903
989
if (device == null || device .propMap == null ) return ;
904
- DialogHelper .showListDialog (this , "Device Properties" , device .propMap , null );
990
+ TreeMap <String , String > sortedPropMap = new TreeMap <>(String .CASE_INSENSITIVE_ORDER );
991
+ sortedPropMap .putAll (device .propMap );
992
+ DialogHelper .showListDialog (this , "Device Properties" , sortedPropMap , null );
905
993
}
906
994
907
995
private void addDeviceDetail (JPanel panel , String label , String value ) {
@@ -1174,19 +1262,23 @@ public void mousePressed(MouseEvent e) {
1174
1262
1175
1263
private void handleCustomScriptClicked (File script , String name ) {
1176
1264
List <Device > selectedDeviceList = getSelectedDevices (true );
1177
- if (selectedDeviceList .isEmpty ()) return ;
1265
+ // if (selectedDeviceList.isEmpty()) return;
1178
1266
1179
1267
log .trace ("handleCustomScriptClicked: {}, {}" , name , script .getAbsolutePath ());
1180
1268
1181
- ResultWatcher resultWatcher = new ResultWatcher (getRootPane (), selectedDeviceList .size ());
1182
- for (Device device : selectedDeviceList ) {
1269
+ String [] serialArr = new String [selectedDeviceList .size ()];
1270
+ for (int i = 0 ; i < selectedDeviceList .size (); i ++) {
1271
+ Device device = selectedDeviceList .get (i );
1183
1272
setDeviceBusy (device , true );
1184
- DeviceManager .getInstance ().runCustomScript ((isSuccess , error ) -> {
1185
- log .trace ("mousePressed: DONE:{}, {}" , isSuccess , error );
1186
- setDeviceBusy (device , false );
1187
- resultWatcher .handleResult (device .serial , isSuccess , error );
1188
- }, script .getAbsolutePath (), device .serial );
1273
+ serialArr [i ] = device .serial ;
1189
1274
}
1275
+
1276
+ DeviceManager .getInstance ().runCustomScript ((isSuccess , error ) -> {
1277
+ log .trace ("handleCustomScriptClicked: DONE:{}, {}" , isSuccess , error );
1278
+ for (Device device : selectedDeviceList ) {
1279
+ setDeviceBusy (device , false );
1280
+ }
1281
+ }, script .getAbsolutePath (), serialArr );
1190
1282
}
1191
1283
1192
1284
private void handleSettingsClicked () {
0 commit comments