@@ -8,7 +8,9 @@ import { DeviceAndroidDebugBridge } from "./device-android-debug-bridge";
88
99interface IDeviceLoggingData {
1010 loggingProcess : ChildProcess ;
11+ appStartTrackingProcess : ChildProcess ;
1112 lineStream : any ;
13+ rawLineStream : any ;
1214 keepSingleProcess : boolean ;
1315}
1416
@@ -32,16 +34,18 @@ export class LogcatHelper implements Mobile.ILogcatHelper {
3234 loggingProcess : null ,
3335 lineStream : null ,
3436 keepSingleProcess : options . keepSingleProcess ,
37+ appStartTrackingProcess : null ,
38+ rawLineStream : null ,
3539 } ;
3640
3741 const logcatStream = await this . getLogcatStream (
3842 deviceIdentifier ,
3943 options . pid
4044 ) ;
45+
4146 const lineStream = byline ( logcatStream . stdout ) ;
42- this . mapDevicesLoggingData [
43- deviceIdentifier
44- ] . loggingProcess = logcatStream ;
47+ this . mapDevicesLoggingData [ deviceIdentifier ] . loggingProcess =
48+ logcatStream ;
4549 this . mapDevicesLoggingData [ deviceIdentifier ] . lineStream = lineStream ;
4650 logcatStream . stderr . on ( "data" , ( data : Buffer ) => {
4751 this . $logger . trace ( "ADB logcat stderr: " + data . toString ( ) ) ;
@@ -71,6 +75,41 @@ export class LogcatHelper implements Mobile.ILogcatHelper {
7175 ) ;
7276 }
7377 } ) ;
78+
79+ const appStartTrackingStream = await this . getAppStartTrackingLogcatStream (
80+ deviceIdentifier ,
81+ options . appId
82+ ) ;
83+
84+ this . mapDevicesLoggingData [ deviceIdentifier ] . appStartTrackingProcess =
85+ appStartTrackingStream ;
86+
87+ const rawLineStream = byline ( appStartTrackingStream . stdout ) ;
88+ this . mapDevicesLoggingData [ deviceIdentifier ] . rawLineStream =
89+ rawLineStream ;
90+
91+ rawLineStream . on ( "data" , ( lineBuffer : Buffer ) => {
92+ if ( ! this . mapDevicesLoggingData [ deviceIdentifier ] ?. loggingProcess )
93+ return ;
94+ const lines = ( lineBuffer . toString ( ) || "" ) . split ( "\n" ) ;
95+ for ( let line of lines ) {
96+ // 09-11 17:50:26.311 598 1979 I ActivityTaskManager: START u0 {flg=0x10000000 cmp=org.nativescript.myApp/com.tns.NativeScriptActivity} from uid 2000
97+ // ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^ ^^^^
98+ // action appId pid
99+
100+ if (
101+ // action
102+ line . includes ( "START" ) &&
103+ // appId
104+ line . includes ( options . appId ) &&
105+ // pid - only if it's not the current pid...
106+ ! line . includes ( options . pid )
107+ ) {
108+ this . forceStop ( deviceIdentifier ) ;
109+ options . onAppRestarted ?.( ) ;
110+ }
111+ }
112+ } ) ;
74113 }
75114 }
76115
@@ -108,39 +147,92 @@ export class LogcatHelper implements Mobile.ILogcatHelper {
108147 }
109148
110149 private forceStop ( deviceIdentifier : string ) : void {
111- this . mapDevicesLoggingData [
112- deviceIdentifier
113- ] . loggingProcess . removeAllListeners ( ) ;
114- this . mapDevicesLoggingData [ deviceIdentifier ] . loggingProcess . kill ( "SIGINT" ) ;
115- this . mapDevicesLoggingData [
116- deviceIdentifier
117- ] . lineStream . removeAllListeners ( ) ;
150+ const loggingData = this . mapDevicesLoggingData [ deviceIdentifier ] ;
151+ loggingData . loggingProcess ?. removeAllListeners ( ) ;
152+ loggingData . loggingProcess ?. kill ( "SIGINT" ) ;
153+ loggingData . lineStream ?. removeAllListeners ( ) ;
154+
155+ loggingData . appStartTrackingProcess ?. kill ( "SIGINT" ) ;
156+ loggingData . lineStream ?. removeAllListeners ( ) ;
157+
118158 delete this . mapDevicesLoggingData [ deviceIdentifier ] ;
119159 }
120160
121- private async getLogcatStream ( deviceIdentifier : string , pid ?: string ) {
161+ /**
162+ * @deprecated - we likely don't need this anymore, and can simplify the code...
163+ */
164+ private async isLogcatPidSupported ( deviceIdentifier : string ) {
122165 const device = await this . $devicesService . getDevice ( deviceIdentifier ) ;
123166 const minAndroidWithLogcatPidSupport = "7.0.0" ;
124- const isLogcatPidSupported =
167+ return (
125168 ! ! device . deviceInfo . version &&
126169 semver . gte (
127170 semver . coerce ( device . deviceInfo . version ) ,
128171 minAndroidWithLogcatPidSupport
129- ) ;
172+ )
173+ ) ;
174+ }
175+
176+ private async getLogcatStream ( deviceIdentifier : string , pid ?: string ) {
177+ const isLogcatPidSupported = await this . isLogcatPidSupported (
178+ deviceIdentifier
179+ ) ;
130180 const adb : Mobile . IDeviceAndroidDebugBridge = this . $injector . resolve (
131181 DeviceAndroidDebugBridge ,
132182 { identifier : deviceIdentifier }
133183 ) ;
134- const logcatCommand = [ "logcat" ] ;
184+
185+ // -T 1 - shows only new logs after starting adb logcat
186+ const logcatCommand = [ "logcat" , "-T" , "1" ] ;
187+
188+ const acceptedTags = [
189+ "chromium" ,
190+ '"Web Console"' ,
191+ "JS" ,
192+ "System.err" ,
193+ "TNS.Native" ,
194+ "TNS.Java" ,
195+ ] ;
135196
136197 if ( pid && isLogcatPidSupported ) {
137198 logcatCommand . push ( `--pid=${ pid } ` ) ;
199+
200+ acceptedTags . forEach ( ( tag ) => {
201+ // -s <tag> - shows only logs with the specified tag
202+ logcatCommand . push ( "-s" , tag ) ;
203+ } ) ;
138204 }
205+
139206 const logcatStream = await adb . executeCommand ( logcatCommand , {
140207 returnChildProcess : true ,
141208 } ) ;
209+
142210 return logcatStream ;
143211 }
212+
213+ private async getAppStartTrackingLogcatStream (
214+ deviceIdentifier : string ,
215+ appId ?: string
216+ ) {
217+ const adb : Mobile . IDeviceAndroidDebugBridge = this . $injector . resolve (
218+ DeviceAndroidDebugBridge ,
219+ { identifier : deviceIdentifier }
220+ ) ;
221+
222+ // -b system - shows the system buffer/logs only
223+ // -T 1 - shows only new logs after starting adb logcat
224+ const logcatCommand = [ `logcat` , `-b` , `system` , `-T` , `1` ] ;
225+
226+ if ( appId ) {
227+ logcatCommand . push ( `--regex=START.*${ appId } ` ) ;
228+ }
229+
230+ const appStartTrackingStream = await adb . executeCommand ( logcatCommand , {
231+ returnChildProcess : true ,
232+ } ) ;
233+
234+ return appStartTrackingStream ;
235+ }
144236}
145237
146238injector . register ( "logcatHelper" , LogcatHelper ) ;
0 commit comments