currentactivity 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,14 +21,107 @@ brew install android-platform-tools
21
21
  ```
22
22
 
23
23
  ## Usage
24
- Exec `currentactivity` in your terminal.
24
+ ### Show current activity's name
25
25
  ```
26
- currentactivity
26
+ currentactivity -a
27
+ ```
28
+ output example
29
+ ```
30
+ com.tencent.mm/com.tencent.mm.ui.LauncherUI
31
+ ```
32
+ ### Show current activity's name in real time
33
+ ```
34
+ currentactivity -a -w
35
+ ```
36
+ ### Show current activity's stack
37
+ ```
38
+ currentactivity -s
39
+ ```
40
+ output example
41
+ ```
42
+ ╔═══════════════════════════════════════════════════════════════╗
43
+ ║ com.tencent.mm/.plugin.webview.ui.tools.WebViewUI ║
44
+ ╟───────────────────────────────────────────────────────────────╢
45
+ ║ com.tencent.mm/.plugin.brandservice.ui.timeline.BizTimeLineUI ║
46
+ ╟───────────────────────────────────────────────────────────────╢
47
+ ║ com.tencent.mm/.ui.LauncherUI ║
48
+ ╚═══════════════════════════════════════════════════════════════╝
49
+ ```
50
+ ### Show current activity's fragments
51
+ ```
52
+ currentactivity -f
53
+ ```
54
+ output example
55
+ ```
56
+ ╔═════════════════════╤════════════════════════════════════════════════════════════════════════════════════════╗
57
+ ║ activity │ com.tencent.mm/.ui.LauncherUI ║
58
+ ╟─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────╢
59
+ ║ framework fragments │ └─ #0: ad{d7a01e4 #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag} ║
60
+ ║ │ ║
61
+ ╟─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────╢
62
+ ║ androidx fragments │ ├─ MainUI{403dae2} (f74366df-8aa6-4cc2-b702-9b609620a895 id=0x7f092d4a) ║
63
+ ║ │ ├─ MvvmAddressUIFragment{ef218ab} (fbc006c7-be02-47fa-be40-952dcc42293b id=0x7f092d4a) ║
64
+ ║ │ ├─ MoreTabUI{dcc2cc6} (106e8aa9-d6da-48f2-b870-d0a95882d33f id=0x7f092d4a) ║
65
+ ║ │ ├─ ChattingUIFragment{cad8b94} (3fccfb2c-fc14-4b3c-8b91-ba9d3e102759 id=0x7f0909d7) ║
66
+ ║ │ └─ FindMoreFriendsUI{fdacb08} (b1b80b1b-ea6f-470b-b16c-cd76c853e8ad id=0x7f092d4a) ║
67
+ ║ │ ║
68
+ ╚═════════════════════╧════════════════════════════════════════════════════════════════════════════════════════╝
69
+ ```
70
+ ### Show all the info about the current activity
71
+ ```
72
+ currentactivity -A
73
+ ```
74
+ output example
75
+ ```
76
+ ╔═════════════════════════════════════════════╗
77
+ ║ current window ║
78
+ ╟─────────────────────────────────────────────╢
79
+ ║ com.tencent.mm/com.tencent.mm.ui.LauncherUI ║
80
+ ╚═════════════════════════════════════════════╝
81
+
82
+
83
+
84
+ ╔═══════════════════════════════╗
85
+ ║ activity stack ║
86
+ ╟───────────────────────────────╢
87
+ ║ com.tencent.mm/.ui.LauncherUI ║
88
+ ╚═══════════════════════════════╝
89
+
90
+
91
+
92
+ ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
93
+ ║ fragments ║
94
+ ╟─────────────────────┬────────────────────────────────────────────────────────────────────────────────────────╢
95
+ ║ framework fragments │ └─ #0: ad{d7a01e4 #0 androidx.lifecycle.LifecycleDispatcher.report_fragment_tag} ║
96
+ ║ │ ║
97
+ ╟─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────╢
98
+ ║ androidx fragments │ ├─ MainUI{403dae2} (f74366df-8aa6-4cc2-b702-9b609620a895 id=0x7f092d4a) ║
99
+ ║ │ ├─ MvvmAddressUIFragment{ef218ab} (fbc006c7-be02-47fa-be40-952dcc42293b id=0x7f092d4a) ║
100
+ ║ │ ├─ MoreTabUI{dcc2cc6} (106e8aa9-d6da-48f2-b870-d0a95882d33f id=0x7f092d4a) ║
101
+ ║ │ ├─ ChattingUIFragment{cad8b94} (3fccfb2c-fc14-4b3c-8b91-ba9d3e102759 id=0x7f0909d7) ║
102
+ ║ │ └─ FindMoreFriendsUI{fdacb08} (b1b80b1b-ea6f-470b-b16c-cd76c853e8ad id=0x7f092d4a) ║
103
+ ║ │ ║
104
+ ╚═════════════════════╧════════════════════════════════════════════════════════════════════════════════════════╝
105
+ ```
106
+ ### More Options
107
+ ```
108
+ -h, --help Show help
109
+ -a, --activity Show the current activity's name
110
+ -s, --stack Show the current activity's stack
111
+ -f, --fragment Show all fragments in the current activity
112
+ -w, --watch Monitor activity or fragments changes in real time
113
+ -A, --all Show all information, including the current activity name, activity stack and fragments
27
114
  ```
28
115
  That's it.
29
116
 
30
117
  ## Changelog
31
118
 
119
+ * 1.0.2
120
+ * Compatible with some Samsung phones
121
+
122
+ * 1.0.1
123
+ * Added more options for more flexible output
124
+
32
125
  * 1.0.0
33
126
  * Initial version
34
127
 
package/build/index.js CHANGED
@@ -9,12 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  step((generator = generator.apply(thisArg, _arguments || [])).next());
10
10
  });
11
11
  };
12
+ var __importDefault = (this && this.__importDefault) || function (mod) {
13
+ return (mod && mod.__esModule) ? mod : { "default": mod };
14
+ };
12
15
  Object.defineProperty(exports, "__esModule", { value: true });
13
16
  const child_process_1 = require("child_process");
14
17
  const table_1 = require("table");
15
18
  const treeify_1 = require("treeify");
19
+ const yargs_1 = __importDefault(require("yargs"));
16
20
  require("./extension");
17
- function printDumpInfo() {
21
+ function printAll() {
18
22
  var _a, _b, _c, _d, _e, _f;
19
23
  return __awaiter(this, void 0, void 0, function* () {
20
24
  // exec adb shell dumpsys window displays
@@ -34,7 +38,7 @@ function printDumpInfo() {
34
38
  const activityOutput = (0, child_process_1.execSync)("adb shell dumpsys activity " + currentApp, { encoding: "utf-8" });
35
39
  const activityLines = activityOutput.split("\n");
36
40
  // 1. find top activity
37
- const activitesLines = findLines(activityLines, "ACTIVITY");
41
+ const activitesLines = findLines(activityLines, "ACTIVITY ");
38
42
  let sliceStart = 0;
39
43
  let sliceEnd = activityLines.length - 1;
40
44
  activitesLines.forEach((v, index) => {
@@ -64,38 +68,56 @@ function printDumpInfo() {
64
68
  frameworkRangeLines.sort((a, b) => a.start.index - b.start.index);
65
69
  frameworkRangeLines.forEach((v) => {
66
70
  const firstFragmentLine = frameworkLines === null || frameworkLines === void 0 ? void 0 : frameworkLines.at(v.start.index + 1);
67
- if (firstFragmentLine) {
71
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
68
72
  frameworkFragmentLines.push({
69
- content: firstFragmentLine,
73
+ content: handleFragmentLine(firstFragmentLine),
70
74
  index: v.start.index + 1,
71
75
  });
72
76
  }
73
77
  frameworkLines === null || frameworkLines === void 0 ? void 0 : frameworkLines.forEach((item, index) => {
74
78
  if (firstFragmentLine &&
79
+ !isNullLine(item) &&
75
80
  spaceCount(item) == spaceCount(firstFragmentLine) &&
76
81
  index > v.start.index + 1 &&
77
82
  index < v.end.index) {
78
- frameworkFragmentLines.push({ content: item, index: index });
83
+ frameworkFragmentLines.push({
84
+ content: handleFragmentLine(item),
85
+ index: index,
86
+ });
79
87
  }
80
88
  });
81
89
  });
82
90
  if (androidxLines) {
91
+ const activeFragmentsLine = findFirstLines(androidxLines, "Active Fragments:");
92
+ if (activeFragmentsLine != undefined &&
93
+ !activeFragmentsLine.endsWith("Active Fragments:")) {
94
+ const androidxLinesText = androidxLines.join("\n");
95
+ const activeFragmentsSliceIndex = androidxLinesText.indexOf("Active Fragments:") +
96
+ "Active Fragments:".length;
97
+ androidxLines = (androidxLinesText.slice(0, activeFragmentsSliceIndex) +
98
+ "\n" +
99
+ androidxLinesText.slice(activeFragmentsSliceIndex)).split("\n");
100
+ }
83
101
  const androidxRangeLines = findRangeLines(androidxLines, "Active Fragments", "Added Fragments");
84
102
  androidxRangeLines.sort((a, b) => a.start.index - b.start.index);
85
103
  androidxRangeLines.forEach((v) => {
86
104
  const firstFragmentLine = androidxLines === null || androidxLines === void 0 ? void 0 : androidxLines.at(v.start.index + 1);
87
- if (firstFragmentLine) {
105
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
88
106
  androidxFragmentLines.push({
89
- content: firstFragmentLine,
107
+ content: handleFragmentLine(firstFragmentLine),
90
108
  index: v.start.index + 1,
91
109
  });
92
110
  }
93
111
  androidxLines === null || androidxLines === void 0 ? void 0 : androidxLines.forEach((item, index) => {
94
112
  if (firstFragmentLine &&
113
+ !isNullLine(item) &&
95
114
  spaceCount(item) == spaceCount(firstFragmentLine) &&
96
115
  index > v.start.index + 1 &&
97
116
  index < v.end.index) {
98
- androidxFragmentLines.push({ content: item, index: index });
117
+ androidxFragmentLines.push({
118
+ content: handleFragmentLine(item),
119
+ index: index,
120
+ });
99
121
  }
100
122
  });
101
123
  });
@@ -114,9 +136,10 @@ function printDumpInfo() {
114
136
  if (stackId != undefined) {
115
137
  const stackLines = windowLines.filter((v) => {
116
138
  const s = v.trim();
117
- return s.startsWith("*") && s.indexOf(stackId) > 0;
139
+ return ((s.startsWith("*") || s.startsWith("Activity #")) &&
140
+ s.indexOf(stackId) > 0);
118
141
  });
119
- const stacks = stackLines.map((v) => v.trim().split(" ")[3]);
142
+ const stacks = stackLines.map((v) => v.trim().split(" ").last(1));
120
143
  if (stacks[0] != currentActivity) {
121
144
  stacks.shift();
122
145
  }
@@ -151,14 +174,32 @@ function printDumpInfo() {
151
174
  }
152
175
  });
153
176
  }
177
+ function handleFragmentLine(content) {
178
+ var _a;
179
+ if (content.length > 160) {
180
+ if (content.trimStart().startsWith("SupportRequestManagerFragment")) {
181
+ const parentIndex = content.indexOf("{parent=");
182
+ const parentText = content.substring(parentIndex);
183
+ return (content.substring(0, parentIndex) + ((_a = parentText.split(" ")) === null || _a === void 0 ? void 0 : _a.at(0)) + "}");
184
+ }
185
+ else {
186
+ return content.substring(0, 160);
187
+ }
188
+ }
189
+ return content;
190
+ }
191
+ function isNullLine(content) {
192
+ if (content.trim() == "null")
193
+ return true;
194
+ return false;
195
+ }
154
196
  function toTreeArray(arr) {
155
197
  const result = Array();
156
198
  arr.forEach((v, index) => {
157
199
  result.push({
158
200
  id: index.toString(),
159
201
  content: v.content.trim(),
160
- parentId: findParentIndex(arr.map((item) => item.content), v.content)
161
- .toString(),
202
+ parentId: findParentIndex(arr.map((item) => item.content), v.content).toString(),
162
203
  children: null,
163
204
  });
164
205
  });
@@ -248,7 +289,7 @@ function spaceCount(value) {
248
289
  function findLines(lines, target) {
249
290
  const result = Array();
250
291
  lines.forEach((v, i) => {
251
- if (v.indexOf(target) > 0) {
292
+ if (v.indexOf(target) >= 0) {
252
293
  result.push({
253
294
  content: v,
254
295
  index: i,
@@ -261,6 +302,15 @@ function findFirstLines(lines, target) {
261
302
  var _a;
262
303
  return (_a = findLines(lines, target).at(0)) === null || _a === void 0 ? void 0 : _a.content;
263
304
  }
305
+ function findFirstLineIndex(lines, target) {
306
+ const firstLine = findLines(lines, target).at(0);
307
+ if (firstLine == undefined) {
308
+ return -1;
309
+ }
310
+ else {
311
+ return firstLine.index;
312
+ }
313
+ }
264
314
  function findLastLines(lines, target) {
265
315
  var _a;
266
316
  return (_a = findLines(lines, target).last(0)) === null || _a === void 0 ? void 0 : _a.content;
@@ -289,15 +339,296 @@ function findRangeLines(lines, start, end) {
289
339
  return children;
290
340
  }
291
341
  let oldActivity = "";
292
- function main(onCurrentWindowChanged) {
342
+ function onCurrentWindowChanged(f) {
293
343
  return __awaiter(this, void 0, void 0, function* () {
294
344
  while (true) {
295
345
  const currentActivity = (0, child_process_1.execSync)("adb shell dumpsys window displays | grep -E 'mCurrentFocus'", { encoding: "utf-8" });
296
346
  if (oldActivity != currentActivity) {
297
- onCurrentWindowChanged();
347
+ f();
298
348
  oldActivity = currentActivity;
299
349
  }
300
350
  }
301
351
  });
302
352
  }
303
- main(() => printDumpInfo());
353
+ let oldFragments = "";
354
+ function onFragmentsChanged(f) {
355
+ return __awaiter(this, void 0, void 0, function* () {
356
+ while (true) {
357
+ const activityOutput = (0, child_process_1.execSync)("adb shell dumpsys activity top", {
358
+ encoding: "utf-8",
359
+ });
360
+ const activityLines = activityOutput.split("\n");
361
+ const topActivityLine = findLastLines(activityLines, "TASK");
362
+ let sliceStart = activityLines.indexOf(topActivityLine);
363
+ let sliceEnd = activityLines.length - 1;
364
+ const topActivityLines = activityLines.slice(sliceStart, sliceEnd);
365
+ const frameworkFragmentSliceStart = findFirstLineIndex(topActivityLines, "Local Activity");
366
+ const frameworkFragmentSliceEnd = findFirstLineIndex(topActivityLines, "ViewRoot:");
367
+ const androidXFragmentSliceStart = findFirstLineIndex(topActivityLines, "Local FragmentActivity");
368
+ const androidXFragmentSliceEnd = topActivityLines.length - 1;
369
+ let frameworkFragmentLines = "";
370
+ if (frameworkFragmentSliceStart >= 0 &&
371
+ frameworkFragmentSliceEnd >= 0 &&
372
+ frameworkFragmentSliceStart < frameworkFragmentSliceEnd) {
373
+ frameworkFragmentLines = topActivityLines
374
+ .slice(frameworkFragmentSliceStart, frameworkFragmentSliceEnd)
375
+ .join("\n");
376
+ }
377
+ let androidXFragmentLines = "";
378
+ if (androidXFragmentSliceStart >= 0 &&
379
+ androidXFragmentSliceEnd >= 0 &&
380
+ androidXFragmentSliceStart < androidXFragmentSliceEnd) {
381
+ androidXFragmentLines = topActivityLines
382
+ .slice(androidXFragmentSliceStart, androidXFragmentSliceEnd)
383
+ .join("\n");
384
+ }
385
+ const fragmentLines = frameworkFragmentLines + "\n" + androidXFragmentLines;
386
+ if (oldFragments != fragmentLines) {
387
+ f();
388
+ oldFragments = fragmentLines;
389
+ }
390
+ }
391
+ });
392
+ }
393
+ function printCurrentActivityName() {
394
+ var _a, _b;
395
+ return __awaiter(this, void 0, void 0, function* () {
396
+ const windowOutput = (0, child_process_1.execSync)("adb shell dumpsys window displays", {
397
+ encoding: "utf-8",
398
+ });
399
+ const windowLines = windowOutput.split("\n");
400
+ const currentFocusLine = findFirstLines(windowLines, "mCurrentFocus");
401
+ const currentWindow = (_b = (_a = currentFocusLine === null || currentFocusLine === void 0 ? void 0 : currentFocusLine.split(" ")) === null || _a === void 0 ? void 0 : _a.last(0)) === null || _b === void 0 ? void 0 : _b.removeLast(1);
402
+ if (currentWindow) {
403
+ console.clear();
404
+ console.log(currentWindow);
405
+ }
406
+ });
407
+ }
408
+ function printCurrentActivityStack() {
409
+ var _a, _b, _c;
410
+ return __awaiter(this, void 0, void 0, function* () {
411
+ const windowOutput = (0, child_process_1.execSync)("adb shell dumpsys window displays", {
412
+ encoding: "utf-8",
413
+ });
414
+ const windowLines = windowOutput.split("\n");
415
+ const currentFocusAppLine = findFirstLines(windowLines, "mFocusedApp");
416
+ const currentActivity = (_a = currentFocusAppLine === null || currentFocusAppLine === void 0 ? void 0 : currentFocusAppLine.split(" ")) === null || _a === void 0 ? void 0 : _a.last(1);
417
+ const stackId = (_c = (_b = currentFocusAppLine === null || currentFocusAppLine === void 0 ? void 0 : currentFocusAppLine.split(" ")) === null || _b === void 0 ? void 0 : _b.last(0)) === null || _c === void 0 ? void 0 : _c.removeLast(1);
418
+ if (stackId != undefined) {
419
+ const stackLines = windowLines.filter((v) => {
420
+ const s = v.trim();
421
+ return ((s.startsWith("*") || s.startsWith("Activity #")) &&
422
+ s.indexOf(stackId) > 0);
423
+ });
424
+ const stacks = stackLines.map((v) => v.trim().split(" ").last(1));
425
+ if (stacks[0] != currentActivity) {
426
+ stacks.shift();
427
+ }
428
+ const statckTable = Array();
429
+ stacks.forEach((v) => statckTable.push([v]));
430
+ console.clear();
431
+ console.log((0, table_1.table)(statckTable));
432
+ }
433
+ });
434
+ }
435
+ function printCurrentActivityFragments() {
436
+ var _a, _b;
437
+ return __awaiter(this, void 0, void 0, function* () {
438
+ const windowOutput = (0, child_process_1.execSync)("adb shell dumpsys window displays", {
439
+ encoding: "utf-8",
440
+ });
441
+ const windowLines = windowOutput.split("\n");
442
+ const currentFocusAppLine = findFirstLines(windowLines, "mFocusedApp");
443
+ const currentActivity = (_a = currentFocusAppLine === null || currentFocusAppLine === void 0 ? void 0 : currentFocusAppLine.split(" ")) === null || _a === void 0 ? void 0 : _a.last(1);
444
+ const currentApp = (_b = currentActivity === null || currentActivity === void 0 ? void 0 : currentActivity.split("/")) === null || _b === void 0 ? void 0 : _b.at(0);
445
+ const frameworkFragmentLines = Array();
446
+ const androidxFragmentLines = Array();
447
+ if (currentApp != undefined) {
448
+ const activityOutput = (0, child_process_1.execSync)("adb shell dumpsys activity " + currentApp, { encoding: "utf-8" });
449
+ const activityLines = activityOutput.split("\n");
450
+ // 1. find top activity
451
+ const activitesLines = findLines(activityLines, "ACTIVITY ");
452
+ let sliceStart = 0;
453
+ let sliceEnd = activityLines.length - 1;
454
+ activitesLines.forEach((v, index) => {
455
+ if (currentActivity && v.content.indexOf(currentActivity) > 0) {
456
+ sliceStart = v.index;
457
+ if (index + 1 <= activitesLines.length - 1) {
458
+ sliceEnd = activitesLines[index + 1].index;
459
+ }
460
+ }
461
+ });
462
+ // 2. cut out the top activity lines
463
+ const topActivityLines = activityLines.slice(sliceStart, sliceEnd);
464
+ // 3. split into framework fragments and androidx fragments
465
+ const splitLine = findLastLines(topActivityLines, "Local FragmentActivity");
466
+ let frameworkLines;
467
+ let androidxLines;
468
+ if (splitLine != undefined) {
469
+ const splitLineIndex = topActivityLines.indexOf(splitLine);
470
+ frameworkLines = topActivityLines.slice(0, splitLineIndex);
471
+ androidxLines = topActivityLines.slice(splitLineIndex);
472
+ }
473
+ else {
474
+ frameworkLines = topActivityLines;
475
+ }
476
+ // 4. find all children of between "Active Fragments" and "Added Fragments" node
477
+ const frameworkRangeLines = findRangeLines(frameworkLines, "Active Fragments", "Added Fragments");
478
+ frameworkRangeLines.sort((a, b) => a.start.index - b.start.index);
479
+ frameworkRangeLines.forEach((v) => {
480
+ const firstFragmentLine = frameworkLines === null || frameworkLines === void 0 ? void 0 : frameworkLines.at(v.start.index + 1);
481
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
482
+ frameworkFragmentLines.push({
483
+ content: handleFragmentLine(firstFragmentLine),
484
+ index: v.start.index + 1,
485
+ });
486
+ }
487
+ frameworkLines === null || frameworkLines === void 0 ? void 0 : frameworkLines.forEach((item, index) => {
488
+ if (firstFragmentLine &&
489
+ !isNullLine(item) &&
490
+ spaceCount(item) == spaceCount(firstFragmentLine) &&
491
+ index > v.start.index + 1 &&
492
+ index < v.end.index) {
493
+ frameworkFragmentLines.push({
494
+ content: handleFragmentLine(item),
495
+ index: index,
496
+ });
497
+ }
498
+ });
499
+ });
500
+ if (androidxLines) {
501
+ const activeFragmentsLine = findFirstLines(androidxLines, "Active Fragments:");
502
+ if (activeFragmentsLine != undefined &&
503
+ !activeFragmentsLine.endsWith("Active Fragments:")) {
504
+ const androidxLinesText = androidxLines.join("\n");
505
+ const activeFragmentsSliceIndex = androidxLinesText.indexOf("Active Fragments:") +
506
+ "Active Fragments:".length;
507
+ androidxLines = (androidxLinesText.slice(0, activeFragmentsSliceIndex) +
508
+ "\n" +
509
+ androidxLinesText.slice(activeFragmentsSliceIndex)).split("\n");
510
+ }
511
+ const androidxRangeLines = findRangeLines(androidxLines, "Active Fragments", "Added Fragments");
512
+ androidxRangeLines.sort((a, b) => a.start.index - b.start.index);
513
+ androidxRangeLines.forEach((v) => {
514
+ const firstFragmentLine = androidxLines === null || androidxLines === void 0 ? void 0 : androidxLines.at(v.start.index + 1);
515
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
516
+ androidxFragmentLines.push({
517
+ content: handleFragmentLine(firstFragmentLine),
518
+ index: v.start.index + 1,
519
+ });
520
+ }
521
+ androidxLines === null || androidxLines === void 0 ? void 0 : androidxLines.forEach((item, index) => {
522
+ if (firstFragmentLine &&
523
+ !isNullLine(item) &&
524
+ spaceCount(item) == spaceCount(firstFragmentLine) &&
525
+ index > v.start.index + 1 &&
526
+ index < v.end.index) {
527
+ androidxFragmentLines.push({
528
+ content: handleFragmentLine(item),
529
+ index: index,
530
+ });
531
+ }
532
+ });
533
+ });
534
+ }
535
+ }
536
+ if (frameworkFragmentLines.length > 0 || androidxFragmentLines.length > 0) {
537
+ const fragmentTable = Array();
538
+ fragmentTable.push(["activity", currentActivity]);
539
+ if (frameworkFragmentLines.length > 0) {
540
+ frameworkFragmentLines.sort((a, b) => a.index - b.index);
541
+ fragmentTable.push([
542
+ "framework fragments",
543
+ (0, treeify_1.asTree)(toTreeObject(listToTree(toTreeArray(frameworkFragmentLines))), true),
544
+ ]);
545
+ }
546
+ if (androidxFragmentLines.length > 0) {
547
+ androidxFragmentLines.sort((a, b) => a.index - b.index);
548
+ fragmentTable.push([
549
+ "androidx fragments",
550
+ (0, treeify_1.asTree)(toTreeObject(listToTree(toTreeArray(androidxFragmentLines))), true),
551
+ ]);
552
+ }
553
+ console.clear();
554
+ console.log((0, table_1.table)(fragmentTable));
555
+ }
556
+ else {
557
+ console.clear();
558
+ const fragmentTable = Array();
559
+ fragmentTable.push(["activity", currentActivity]);
560
+ console.log((0, table_1.table)(fragmentTable));
561
+ }
562
+ });
563
+ }
564
+ const argv = (0, yargs_1.default)(process.argv.slice(2))
565
+ .help("help")
566
+ .alias("help", "h")
567
+ .options({
568
+ activity: {
569
+ type: "boolean",
570
+ default: true,
571
+ alias: "a",
572
+ description: "Show the current activity's name",
573
+ },
574
+ stack: {
575
+ type: "boolean",
576
+ default: false,
577
+ alias: "s",
578
+ description: "Show the current activity's stack",
579
+ },
580
+ fragment: {
581
+ type: "boolean",
582
+ default: false,
583
+ alias: "f",
584
+ description: "Show all fragments in the current activity",
585
+ },
586
+ watch: {
587
+ type: "boolean",
588
+ default: false,
589
+ alias: "w",
590
+ description: "Monitor activity or fragments changes in real time",
591
+ },
592
+ all: {
593
+ type: "boolean",
594
+ default: false,
595
+ alias: "A",
596
+ description: "Show all information, including the current activity name, activity stack and fragments",
597
+ },
598
+ })
599
+ .locale("en")
600
+ .parseSync();
601
+ if (argv.all) {
602
+ if (argv.watch) {
603
+ onCurrentWindowChanged(() => printAll());
604
+ }
605
+ else {
606
+ printAll();
607
+ }
608
+ }
609
+ else if (argv.fragment) {
610
+ if (argv.watch) {
611
+ onFragmentsChanged(() => printCurrentActivityFragments());
612
+ }
613
+ else {
614
+ printCurrentActivityFragments();
615
+ }
616
+ }
617
+ else if (argv.activity) {
618
+ if (argv.stack) {
619
+ if (argv.watch) {
620
+ onCurrentWindowChanged(() => printCurrentActivityStack());
621
+ }
622
+ else {
623
+ printCurrentActivityStack();
624
+ }
625
+ }
626
+ else {
627
+ if (argv.watch) {
628
+ onCurrentWindowChanged(() => printCurrentActivityName());
629
+ }
630
+ else {
631
+ printCurrentActivityName();
632
+ }
633
+ }
634
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "currentactivity",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A command line tool to display the current activity for android.",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/Alluretears/currentactivity.git"
11
+ "url": "git+https://github.com/dfshizhiqiang/currentactivity.git"
12
12
  },
13
13
  "keywords": [
14
14
  "current activity",
@@ -19,19 +19,21 @@
19
19
  "author": "Zech",
20
20
  "license": "MIT",
21
21
  "bugs": {
22
- "url": "https://github.com/Alluretears/currentactivity/issues"
22
+ "url": "https://github.com/dfshizhiqiang/currentactivity/issues"
23
23
  },
24
- "homepage": "https://github.com/Alluretears/currentactivity#readme",
24
+ "homepage": "https://github.com/dfshizhiqiang/currentactivity#readme",
25
25
  "bin": {
26
26
  "currentactivity": "./build/index.js"
27
27
  },
28
28
  "devDependencies": {
29
+ "@types/yargs": "^17.0.10",
29
30
  "ts-node": "^10.4.0",
30
31
  "typescript": "^4.5.5"
31
32
  },
32
33
  "dependencies": {
33
34
  "table": "^6.8.0",
34
- "treeify": "^1.1.0"
35
+ "treeify": "^1.1.0",
36
+ "yargs": "^17.5.1"
35
37
  },
36
38
  "publishConfig": {
37
39
  "access": "public"
package/src/index.ts CHANGED
@@ -2,9 +2,10 @@
2
2
  import { execSync } from "child_process";
3
3
  import { table } from "table";
4
4
  import { asTree } from "treeify";
5
+ import yargs from "yargs";
5
6
  import "./extension";
6
7
 
7
- async function printDumpInfo() {
8
+ async function printAll() {
8
9
  // exec adb shell dumpsys window displays
9
10
  const windowOutput = execSync("adb shell dumpsys window displays", {
10
11
  encoding: "utf-8",
@@ -24,12 +25,12 @@ async function printDumpInfo() {
24
25
  if (currentApp != undefined) {
25
26
  const activityOutput = execSync(
26
27
  "adb shell dumpsys activity " + currentApp,
27
- { encoding: "utf-8" },
28
+ { encoding: "utf-8" }
28
29
  );
29
30
  const activityLines = activityOutput.split("\n");
30
31
 
31
32
  // 1. find top activity
32
- const activitesLines = findLines(activityLines, "ACTIVITY");
33
+ const activitesLines = findLines(activityLines, "ACTIVITY ");
33
34
  let sliceStart = 0;
34
35
  let sliceEnd = activityLines.length - 1;
35
36
  activitesLines.forEach((v, index) => {
@@ -44,10 +45,7 @@ async function printDumpInfo() {
44
45
  // 2. cut out the top activity lines
45
46
  const topActivityLines = activityLines.slice(sliceStart, sliceEnd);
46
47
  // 3. split into framework fragments and androidx fragments
47
- const splitLine = findLastLines(
48
- topActivityLines,
49
- "Local FragmentActivity",
50
- );
48
+ const splitLine = findLastLines(topActivityLines, "Local FragmentActivity");
51
49
  let frameworkLines: Array<string>;
52
50
  let androidxLines: Array<string> | undefined;
53
51
  if (splitLine != undefined) {
@@ -61,53 +59,79 @@ async function printDumpInfo() {
61
59
  const frameworkRangeLines = findRangeLines(
62
60
  frameworkLines,
63
61
  "Active Fragments",
64
- "Added Fragments",
62
+ "Added Fragments"
65
63
  );
66
64
  frameworkRangeLines.sort((a, b) => a.start.index - b.start.index);
67
65
  frameworkRangeLines.forEach((v) => {
68
66
  const firstFragmentLine = frameworkLines?.at(v.start.index + 1);
69
- if (firstFragmentLine) {
67
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
70
68
  frameworkFragmentLines.push({
71
- content: firstFragmentLine,
69
+ content: handleFragmentLine(firstFragmentLine),
72
70
  index: v.start.index + 1,
73
71
  });
74
72
  }
75
73
  frameworkLines?.forEach((item, index) => {
76
74
  if (
77
75
  firstFragmentLine &&
76
+ !isNullLine(item) &&
78
77
  spaceCount(item) == spaceCount(firstFragmentLine) &&
79
78
  index > v.start.index + 1 &&
80
79
  index < v.end.index
81
80
  ) {
82
- frameworkFragmentLines.push({ content: item, index: index });
81
+ frameworkFragmentLines.push({
82
+ content: handleFragmentLine(item),
83
+ index: index,
84
+ });
83
85
  }
84
86
  });
85
87
  });
86
88
 
87
89
  if (androidxLines) {
90
+ const activeFragmentsLine = findFirstLines(
91
+ androidxLines,
92
+ "Active Fragments:"
93
+ );
94
+ if (
95
+ activeFragmentsLine != undefined &&
96
+ !activeFragmentsLine.endsWith("Active Fragments:")
97
+ ) {
98
+ const androidxLinesText = androidxLines.join("\n");
99
+ const activeFragmentsSliceIndex =
100
+ androidxLinesText.indexOf("Active Fragments:") +
101
+ "Active Fragments:".length;
102
+ androidxLines = (
103
+ androidxLinesText.slice(0, activeFragmentsSliceIndex) +
104
+ "\n" +
105
+ androidxLinesText.slice(activeFragmentsSliceIndex)
106
+ ).split("\n");
107
+ }
88
108
  const androidxRangeLines = findRangeLines(
89
109
  androidxLines,
90
110
  "Active Fragments",
91
- "Added Fragments",
111
+ "Added Fragments"
92
112
  );
93
113
  androidxRangeLines.sort((a, b) => a.start.index - b.start.index);
94
114
 
95
115
  androidxRangeLines.forEach((v) => {
96
116
  const firstFragmentLine = androidxLines?.at(v.start.index + 1);
97
- if (firstFragmentLine) {
117
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
98
118
  androidxFragmentLines.push({
99
- content: firstFragmentLine,
119
+ content: handleFragmentLine(firstFragmentLine),
100
120
  index: v.start.index + 1,
101
121
  });
102
122
  }
103
123
  androidxLines?.forEach((item, index) => {
104
124
  if (
105
125
  firstFragmentLine &&
126
+ !isNullLine(item) &&
106
127
  spaceCount(item) == spaceCount(firstFragmentLine) &&
107
128
  index > v.start.index + 1 &&
108
129
  index < v.end.index
109
130
  ) {
110
- androidxFragmentLines.push({ content: item, index: index });
131
+ androidxFragmentLines.push({
132
+ content: handleFragmentLine(item),
133
+ index: index,
134
+ });
111
135
  }
112
136
  });
113
137
  });
@@ -123,7 +147,7 @@ async function printDumpInfo() {
123
147
  console.log(
124
148
  table(windowTable, {
125
149
  header: { content: "current window", alignment: "center" },
126
- }),
150
+ })
127
151
  );
128
152
  }
129
153
 
@@ -131,9 +155,12 @@ async function printDumpInfo() {
131
155
  if (stackId != undefined) {
132
156
  const stackLines = windowLines.filter((v) => {
133
157
  const s = v.trim();
134
- return s.startsWith("*") && s.indexOf(stackId) > 0;
158
+ return (
159
+ (s.startsWith("*") || s.startsWith("Activity #")) &&
160
+ s.indexOf(stackId) > 0
161
+ );
135
162
  });
136
- const stacks = stackLines.map((v) => v.trim().split(" ")[3]);
163
+ const stacks = stackLines.map((v) => v.trim().split(" ").last(1));
137
164
  if (stacks[0] != currentActivity) {
138
165
  stacks.shift();
139
166
  }
@@ -143,7 +170,7 @@ async function printDumpInfo() {
143
170
  console.log(
144
171
  table(statckTable, {
145
172
  header: { content: "activity stack", alignment: "center" },
146
- }),
173
+ })
147
174
  );
148
175
  }
149
176
 
@@ -156,7 +183,7 @@ async function printDumpInfo() {
156
183
  "framework fragments",
157
184
  asTree(
158
185
  toTreeObject(listToTree(toTreeArray(frameworkFragmentLines))),
159
- true,
186
+ true
160
187
  ),
161
188
  ]);
162
189
  }
@@ -166,7 +193,7 @@ async function printDumpInfo() {
166
193
  "androidx fragments",
167
194
  asTree(
168
195
  toTreeObject(listToTree(toTreeArray(androidxFragmentLines))),
169
- true,
196
+ true
170
197
  ),
171
198
  ]);
172
199
  }
@@ -174,11 +201,31 @@ async function printDumpInfo() {
174
201
  console.log(
175
202
  table(fragmentTable, {
176
203
  header: { content: "fragments", alignment: "center" },
177
- }),
204
+ })
178
205
  );
179
206
  }
180
207
  }
181
208
 
209
+ function handleFragmentLine(content: string): string {
210
+ if (content.length > 160) {
211
+ if (content.trimStart().startsWith("SupportRequestManagerFragment")) {
212
+ const parentIndex = content.indexOf("{parent=");
213
+ const parentText = content.substring(parentIndex);
214
+ return (
215
+ content.substring(0, parentIndex) + parentText.split(" ")?.at(0) + "}"
216
+ );
217
+ } else {
218
+ return content.substring(0, 160);
219
+ }
220
+ }
221
+ return content;
222
+ }
223
+
224
+ function isNullLine(content: string): boolean {
225
+ if (content.trim() == "null") return true;
226
+ return false;
227
+ }
228
+
182
229
  type Tree = {
183
230
  id: string;
184
231
  content: string;
@@ -192,18 +239,17 @@ function toTreeArray(arr: Array<Line>): Array<Tree> {
192
239
  result.push({
193
240
  id: index.toString(),
194
241
  content: v.content.trim(),
195
- parentId: findParentIndex(arr.map((item) => item.content), v.content)
196
- .toString(),
242
+ parentId: findParentIndex(
243
+ arr.map((item) => item.content),
244
+ v.content
245
+ ).toString(),
197
246
  children: null,
198
247
  });
199
248
  });
200
249
  return result;
201
250
  }
202
251
 
203
- function findParentIndex(
204
- arr: Array<string>,
205
- target: string,
206
- ): number {
252
+ function findParentIndex(arr: Array<string>, target: string): number {
207
253
  const targetIndex = arr.indexOf(target);
208
254
  if (targetIndex < 0) return -1;
209
255
  let parentIndex = -1;
@@ -267,15 +313,15 @@ function findChildren(arr: Array<string>, target: string): Array<string> {
267
313
  const result = Array<string>();
268
314
  const targetIndex = arr.indexOf(target);
269
315
  if (targetIndex < 0 || targetIndex == arr.length - 1) return result;
270
- const nextBrotherIndex = arr.findIndex((v, i) =>
271
- spaceCount(v) == spaceCount(target) && i > targetIndex
316
+ const nextBrotherIndex = arr.findIndex(
317
+ (v, i) => spaceCount(v) == spaceCount(target) && i > targetIndex
272
318
  );
273
319
  if (nextBrotherIndex == targetIndex + 1) return result;
274
320
  const firstChild = arr.at(targetIndex + 1);
275
321
  if (firstChild) {
276
322
  const range = arr.slice(targetIndex, nextBrotherIndex);
277
- const children = range.filter((v) =>
278
- spaceCount(v) == spaceCount(firstChild)
323
+ const children = range.filter(
324
+ (v) => spaceCount(v) == spaceCount(firstChild)
279
325
  );
280
326
  result.concat(children);
281
327
  }
@@ -292,13 +338,10 @@ type Line = {
292
338
  index: number;
293
339
  };
294
340
 
295
- function findLines(
296
- lines: Array<string>,
297
- target: string,
298
- ): Array<Line> {
341
+ function findLines(lines: Array<string>, target: string): Array<Line> {
299
342
  const result = Array<Line>();
300
343
  lines.forEach((v, i) => {
301
- if (v.indexOf(target) > 0) {
344
+ if (v.indexOf(target) >= 0) {
302
345
  result.push({
303
346
  content: v,
304
347
  index: i,
@@ -310,14 +353,23 @@ function findLines(
310
353
 
311
354
  function findFirstLines(
312
355
  lines: Array<string>,
313
- target: string,
356
+ target: string
314
357
  ): string | undefined {
315
358
  return findLines(lines, target).at(0)?.content;
316
359
  }
317
360
 
361
+ function findFirstLineIndex(lines: Array<string>, target: string): number {
362
+ const firstLine = findLines(lines, target).at(0);
363
+ if (firstLine == undefined) {
364
+ return -1;
365
+ } else {
366
+ return firstLine.index;
367
+ }
368
+ }
369
+
318
370
  function findLastLines(
319
371
  lines: Array<string>,
320
- target: string,
372
+ target: string
321
373
  ): string | undefined {
322
374
  return findLines(lines, target).last(0)?.content;
323
375
  }
@@ -330,7 +382,7 @@ type RangeLine = {
330
382
  function findRangeLines(
331
383
  lines: Array<string>,
332
384
  start: string,
333
- end: string,
385
+ end: string
334
386
  ): Array<RangeLine> {
335
387
  const startLines = findLines(lines, start);
336
388
  const endLines = findLines(lines, end);
@@ -355,17 +407,338 @@ function findRangeLines(
355
407
  }
356
408
 
357
409
  let oldActivity = "";
358
- async function main(onCurrentWindowChanged: () => void) {
410
+ async function onCurrentWindowChanged(f: () => void) {
359
411
  while (true) {
360
412
  const currentActivity = execSync(
361
413
  "adb shell dumpsys window displays | grep -E 'mCurrentFocus'",
362
- { encoding: "utf-8" },
414
+ { encoding: "utf-8" }
363
415
  );
364
416
  if (oldActivity != currentActivity) {
365
- onCurrentWindowChanged();
417
+ f();
366
418
  oldActivity = currentActivity;
367
419
  }
368
420
  }
369
421
  }
370
422
 
371
- main(() => printDumpInfo());
423
+ let oldFragments = "";
424
+ async function onFragmentsChanged(f: () => void) {
425
+ while (true) {
426
+ const activityOutput = execSync("adb shell dumpsys activity top", {
427
+ encoding: "utf-8",
428
+ });
429
+ const activityLines = activityOutput.split("\n");
430
+ const topActivityLine = findLastLines(activityLines, "TASK");
431
+ let sliceStart = activityLines.indexOf(topActivityLine);
432
+ let sliceEnd = activityLines.length - 1;
433
+ const topActivityLines = activityLines.slice(sliceStart, sliceEnd);
434
+ const frameworkFragmentSliceStart = findFirstLineIndex(
435
+ topActivityLines,
436
+ "Local Activity"
437
+ );
438
+ const frameworkFragmentSliceEnd = findFirstLineIndex(
439
+ topActivityLines,
440
+ "ViewRoot:"
441
+ );
442
+ const androidXFragmentSliceStart = findFirstLineIndex(
443
+ topActivityLines,
444
+ "Local FragmentActivity"
445
+ );
446
+ const androidXFragmentSliceEnd = topActivityLines.length - 1;
447
+ let frameworkFragmentLines = "";
448
+ if (
449
+ frameworkFragmentSliceStart >= 0 &&
450
+ frameworkFragmentSliceEnd >= 0 &&
451
+ frameworkFragmentSliceStart < frameworkFragmentSliceEnd
452
+ ) {
453
+ frameworkFragmentLines = topActivityLines
454
+ .slice(frameworkFragmentSliceStart, frameworkFragmentSliceEnd)
455
+ .join("\n");
456
+ }
457
+ let androidXFragmentLines = "";
458
+ if (
459
+ androidXFragmentSliceStart >= 0 &&
460
+ androidXFragmentSliceEnd >= 0 &&
461
+ androidXFragmentSliceStart < androidXFragmentSliceEnd
462
+ ) {
463
+ androidXFragmentLines = topActivityLines
464
+ .slice(androidXFragmentSliceStart, androidXFragmentSliceEnd)
465
+ .join("\n");
466
+ }
467
+ const fragmentLines = frameworkFragmentLines + "\n" + androidXFragmentLines;
468
+ if (oldFragments != fragmentLines) {
469
+ f();
470
+ oldFragments = fragmentLines;
471
+ }
472
+ }
473
+ }
474
+
475
+ async function printCurrentActivityName() {
476
+ const windowOutput = execSync("adb shell dumpsys window displays", {
477
+ encoding: "utf-8",
478
+ });
479
+ const windowLines = windowOutput.split("\n");
480
+ const currentFocusLine = findFirstLines(windowLines, "mCurrentFocus");
481
+ const currentWindow = currentFocusLine?.split(" ")?.last(0)?.removeLast(1);
482
+ if (currentWindow) {
483
+ console.clear();
484
+ console.log(currentWindow);
485
+ }
486
+ }
487
+
488
+ async function printCurrentActivityStack() {
489
+ const windowOutput = execSync("adb shell dumpsys window displays", {
490
+ encoding: "utf-8",
491
+ });
492
+ const windowLines = windowOutput.split("\n");
493
+
494
+ const currentFocusAppLine = findFirstLines(windowLines, "mFocusedApp");
495
+ const currentActivity = currentFocusAppLine?.split(" ")?.last(1);
496
+ const stackId = currentFocusAppLine?.split(" ")?.last(0)?.removeLast(1);
497
+
498
+ if (stackId != undefined) {
499
+ const stackLines = windowLines.filter((v) => {
500
+ const s = v.trim();
501
+ return (
502
+ (s.startsWith("*") || s.startsWith("Activity #")) &&
503
+ s.indexOf(stackId) > 0
504
+ );
505
+ });
506
+ const stacks = stackLines.map((v) => v.trim().split(" ").last(1));
507
+ if (stacks[0] != currentActivity) {
508
+ stacks.shift();
509
+ }
510
+ const statckTable = Array<Array<string>>();
511
+ stacks.forEach((v) => statckTable.push([v]));
512
+ console.clear();
513
+ console.log(table(statckTable));
514
+ }
515
+ }
516
+
517
+ async function printCurrentActivityFragments() {
518
+ const windowOutput = execSync("adb shell dumpsys window displays", {
519
+ encoding: "utf-8",
520
+ });
521
+ const windowLines = windowOutput.split("\n");
522
+
523
+ const currentFocusAppLine = findFirstLines(windowLines, "mFocusedApp");
524
+ const currentActivity = currentFocusAppLine?.split(" ")?.last(1);
525
+
526
+ const currentApp = currentActivity?.split("/")?.at(0);
527
+
528
+ const frameworkFragmentLines = Array<Line>();
529
+ const androidxFragmentLines = Array<Line>();
530
+ if (currentApp != undefined) {
531
+ const activityOutput = execSync(
532
+ "adb shell dumpsys activity " + currentApp,
533
+ { encoding: "utf-8" }
534
+ );
535
+ const activityLines = activityOutput.split("\n");
536
+
537
+ // 1. find top activity
538
+ const activitesLines = findLines(activityLines, "ACTIVITY ");
539
+ let sliceStart = 0;
540
+ let sliceEnd = activityLines.length - 1;
541
+ activitesLines.forEach((v, index) => {
542
+ if (currentActivity && v.content.indexOf(currentActivity) > 0) {
543
+ sliceStart = v.index;
544
+ if (index + 1 <= activitesLines.length - 1) {
545
+ sliceEnd = activitesLines[index + 1].index;
546
+ }
547
+ }
548
+ });
549
+
550
+ // 2. cut out the top activity lines
551
+ const topActivityLines = activityLines.slice(sliceStart, sliceEnd);
552
+ // 3. split into framework fragments and androidx fragments
553
+ const splitLine = findLastLines(topActivityLines, "Local FragmentActivity");
554
+ let frameworkLines: Array<string>;
555
+ let androidxLines: Array<string> | undefined;
556
+ if (splitLine != undefined) {
557
+ const splitLineIndex = topActivityLines.indexOf(splitLine);
558
+ frameworkLines = topActivityLines.slice(0, splitLineIndex);
559
+ androidxLines = topActivityLines.slice(splitLineIndex);
560
+ } else {
561
+ frameworkLines = topActivityLines;
562
+ }
563
+ // 4. find all children of between "Active Fragments" and "Added Fragments" node
564
+ const frameworkRangeLines = findRangeLines(
565
+ frameworkLines,
566
+ "Active Fragments",
567
+ "Added Fragments"
568
+ );
569
+ frameworkRangeLines.sort((a, b) => a.start.index - b.start.index);
570
+ frameworkRangeLines.forEach((v) => {
571
+ const firstFragmentLine = frameworkLines?.at(v.start.index + 1);
572
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
573
+ frameworkFragmentLines.push({
574
+ content: handleFragmentLine(firstFragmentLine),
575
+ index: v.start.index + 1,
576
+ });
577
+ }
578
+ frameworkLines?.forEach((item, index) => {
579
+ if (
580
+ firstFragmentLine &&
581
+ !isNullLine(item) &&
582
+ spaceCount(item) == spaceCount(firstFragmentLine) &&
583
+ index > v.start.index + 1 &&
584
+ index < v.end.index
585
+ ) {
586
+ frameworkFragmentLines.push({
587
+ content: handleFragmentLine(item),
588
+ index: index,
589
+ });
590
+ }
591
+ });
592
+ });
593
+
594
+ if (androidxLines) {
595
+ const activeFragmentsLine = findFirstLines(
596
+ androidxLines,
597
+ "Active Fragments:"
598
+ );
599
+ if (
600
+ activeFragmentsLine != undefined &&
601
+ !activeFragmentsLine.endsWith("Active Fragments:")
602
+ ) {
603
+ const androidxLinesText = androidxLines.join("\n");
604
+ const activeFragmentsSliceIndex =
605
+ androidxLinesText.indexOf("Active Fragments:") +
606
+ "Active Fragments:".length;
607
+ androidxLines = (
608
+ androidxLinesText.slice(0, activeFragmentsSliceIndex) +
609
+ "\n" +
610
+ androidxLinesText.slice(activeFragmentsSliceIndex)
611
+ ).split("\n");
612
+ }
613
+ const androidxRangeLines = findRangeLines(
614
+ androidxLines,
615
+ "Active Fragments",
616
+ "Added Fragments"
617
+ );
618
+ androidxRangeLines.sort((a, b) => a.start.index - b.start.index);
619
+
620
+ androidxRangeLines.forEach((v) => {
621
+ const firstFragmentLine = androidxLines?.at(v.start.index + 1);
622
+ if (firstFragmentLine && !isNullLine(firstFragmentLine)) {
623
+ androidxFragmentLines.push({
624
+ content: handleFragmentLine(firstFragmentLine),
625
+ index: v.start.index + 1,
626
+ });
627
+ }
628
+ androidxLines?.forEach((item, index) => {
629
+ if (
630
+ firstFragmentLine &&
631
+ !isNullLine(item) &&
632
+ spaceCount(item) == spaceCount(firstFragmentLine) &&
633
+ index > v.start.index + 1 &&
634
+ index < v.end.index
635
+ ) {
636
+ androidxFragmentLines.push({
637
+ content: handleFragmentLine(item),
638
+ index: index,
639
+ });
640
+ }
641
+ });
642
+ });
643
+ }
644
+ }
645
+
646
+ if (frameworkFragmentLines.length > 0 || androidxFragmentLines.length > 0) {
647
+ const fragmentTable = Array<Array<string>>();
648
+ fragmentTable.push(["activity", currentActivity]);
649
+ if (frameworkFragmentLines.length > 0) {
650
+ frameworkFragmentLines.sort((a, b) => a.index - b.index);
651
+ fragmentTable.push([
652
+ "framework fragments",
653
+ asTree(
654
+ toTreeObject(listToTree(toTreeArray(frameworkFragmentLines))),
655
+ true
656
+ ),
657
+ ]);
658
+ }
659
+ if (androidxFragmentLines.length > 0) {
660
+ androidxFragmentLines.sort((a, b) => a.index - b.index);
661
+ fragmentTable.push([
662
+ "androidx fragments",
663
+ asTree(
664
+ toTreeObject(listToTree(toTreeArray(androidxFragmentLines))),
665
+ true
666
+ ),
667
+ ]);
668
+ }
669
+ console.clear();
670
+ console.log(table(fragmentTable));
671
+ } else {
672
+ console.clear();
673
+ const fragmentTable = Array<Array<string>>();
674
+ fragmentTable.push(["activity", currentActivity]);
675
+ console.log(table(fragmentTable));
676
+ }
677
+ }
678
+
679
+ const argv = yargs(process.argv.slice(2))
680
+ .help("help")
681
+ .alias("help", "h")
682
+ .options({
683
+ activity: {
684
+ type: "boolean",
685
+ default: true,
686
+ alias: "a",
687
+ description: "Show the current activity's name",
688
+ },
689
+ stack: {
690
+ type: "boolean",
691
+ default: false,
692
+ alias: "s",
693
+ description: "Show the current activity's stack",
694
+ },
695
+ fragment: {
696
+ type: "boolean",
697
+ default: false,
698
+ alias: "f",
699
+ description: "Show all fragments in the current activity",
700
+ },
701
+ watch: {
702
+ type: "boolean",
703
+ default: false,
704
+ alias: "w",
705
+ description: "Monitor activity or fragments changes in real time",
706
+ },
707
+ all: {
708
+ type: "boolean",
709
+ default: false,
710
+ alias: "A",
711
+ description:
712
+ "Show all information, including the current activity name, activity stack and fragments",
713
+ },
714
+ })
715
+ .locale("en")
716
+ .parseSync();
717
+
718
+ if (argv.all) {
719
+ if (argv.watch) {
720
+ onCurrentWindowChanged(() => printAll());
721
+ } else {
722
+ printAll();
723
+ }
724
+ } else if (argv.fragment) {
725
+ if (argv.watch) {
726
+ onFragmentsChanged(() => printCurrentActivityFragments());
727
+ } else {
728
+ printCurrentActivityFragments();
729
+ }
730
+ } else if (argv.activity) {
731
+ if (argv.stack) {
732
+ if (argv.watch) {
733
+ onCurrentWindowChanged(() => printCurrentActivityStack());
734
+ } else {
735
+ printCurrentActivityStack();
736
+ }
737
+ } else {
738
+ if (argv.watch) {
739
+ onCurrentWindowChanged(() => printCurrentActivityName());
740
+ } else {
741
+ printCurrentActivityName();
742
+ }
743
+ }
744
+ }