@@ -3,6 +3,11 @@ package bluepie.ad_silence
33import  android.app.Notification 
44import  android.content.Context 
55import  android.util.Log 
6+ import  android.view.View 
7+ import  android.view.ViewGroup 
8+ import  android.widget.FrameLayout 
9+ import  android.widget.RemoteViews 
10+ import  android.widget.TextView 
611import  bluepie.ad_silence.triggers.spotifyTrigger 
712import  java.util.* 
813
@@ -79,63 +84,100 @@ class NotificationParser(override var appNotification: AppNotification) :
7984        return  notificationInfo
8085    }
8186
82-     private  fun  parseAccuradioNotification (): Boolean  {
83-         Log .v(
84-             TAG ,
85-             " detected ${appNotification.context.getString(R .string.accuradio)}  -> ${ 
86-                 appNotification.context.getString(R .string.accuradio_pkg_name) 
87-             } " 
88-         )
89-         val  notification =  appNotification.notification
90-         try  {
91-             var  fields:  ArrayList <* >?  =  null 
9287
93-             var  contentView =  notification.contentView;
88+     private  fun  extractTextFromRemoteViews (remoteViews :  RemoteViews ): String  {
89+         return  try  {
90+             //  Inflate the RemoteViews into a temporary container.
91+             val  parent =  FrameLayout (appNotification.context)
92+             val  view =  remoteViews.apply (appNotification.context, parent)
93+             //  Traverse the inflated view tree to extract all text.
94+             extractTextFromView(view)
95+         } catch  (e:  Exception ) {
96+             Log .e(TAG , " RemoteViews inflation failed" 
97+             " " 
98+         }
99+     }
94100
95-             if  (contentView ==  null ) {
96-                 contentView =  notification.bigContentView;
101+     private  fun  extractTextFromView (view :  View ): String  {
102+         val  sb =  StringBuilder ()
103+         if  (view is  TextView ) {
104+             sb.append(view.text)
105+         }
106+         if  (view is  ViewGroup ) {
107+             for  (i in  0  until view.childCount) {
108+                 sb.append("  " 
97109            }
98-             if  (contentView ==  null ) {
99-                 contentView =  notification.headsUpContentView;
110+         }
111+         return  sb.toString().trim()
112+     }
113+ 
114+     private  fun  extractTextViaReflection (remoteViews :  RemoteViews ): String  {
115+         var  fields:  ArrayList <* >?  =  null 
116+         remoteViews.javaClass.declaredFields.forEach { field -> 
117+             if  (field.name ==  " mActions" 
118+                 field.isAccessible =  true 
119+                 fields =  field.get(remoteViews) as ?  ArrayList <* >
100120            }
121+         }
122+         val  info =  LinkedList <String >()
123+         fields?.forEach { action -> 
124+             action?.javaClass?.declaredFields
125+                 ?.firstOrNull { it.name ==  " value" 
126+                 ?.apply  { isAccessible =  true  }
127+                 ?.let  { field -> 
128+                     when  (val  v =  field.get(action)) {
129+                         is  String  ->  info.push(v)
130+                     }
131+                 }
132+         }
133+         return  info.joinToString("  " 
134+     }
101135
102136
103-             for  (field in  contentView.javaClass.declaredFields) {
104-                 if  (field.name ==  " mActions" 
105-                     field.isAccessible =  true 
106-                     fields =  field.get(contentView) as  ArrayList <* >
137+     private  fun  parseAccuradioNotification (): Boolean  {
138+         Log .v(
139+             TAG ,
140+             " detected ${appNotification.context.getString(R .string.accuradio)}  -> " + 
141+                     appNotification.context.getString(R .string.accuradio_pkg_name)
142+         )
143+         val  notification =  appNotification.notification
144+         try  {
145+             var  notificationText =  " " 
146+             //  remote views
147+             val  remoteViews =  notification.contentView
148+                 ? :  notification.bigContentView
149+                 ? :  notification.headsUpContentView
150+ 
151+             //  Trying to inflate the RemoteViews
152+             if  (remoteViews !=  null ) {
153+                 try  {
154+                     notificationText =  extractTextFromRemoteViews(remoteViews)
155+                 } catch  (e:  Exception ) {
156+                     Log .e(TAG , " RemoteViews inflation failed" 
157+                     notificationText =  " " 
107158                }
108- 
109159            }
110-             val  info =  LinkedList <String >()
111-             fields?.toArray()?.forEach { it -> 
112-                 if  (it !=  null ) {
113-                     val  fieldFilter =  it.javaClass.declaredFields.filter { it.name ==  " value" 
114-                     if  (fieldFilter.size ==  1 ) {
115-                         val  field =  fieldFilter.get(0 )
116-                         field.isAccessible =  true 
117- 
118-                         //  necessary fields
119-                         when  (val  v =  field.get(it)) {
120-                             is  String  ->  info.push(v)
121-                         }
122-                     }
123-                 }
160+ 
161+             //  fallback to reflection.
162+             if  (notificationText.isBlank() &&  remoteViews !=  null ) {
163+                 notificationText =  extractTextViaReflection(remoteViews)
124164            }
125165
126-             notificationInfo =  info
166+             notificationInfo =  LinkedList <String >().apply  { push(notificationText) }
167+ 
168+             //  Check for ad strings.
127169            var  isAd =  false 
128170            for  (adString in  appNotification.adString()) {
129-                 if  (info.any { it. contains(adString) } ) {
171+                 if  (notificationText. contains(adString)) {
130172                    Log .v(TAG , " detection in Accuradio: $adString " 
131173                    isAd =  true 
132174                    break 
133175                }
134176            }
135177            return  isAd
136-         } catch  (nullPointerException :   NullPointerException ) {
137-             Log .v(TAG , " Ad-silence exception in parsing accuradio" 
138-             return  false ; 
178+         } catch  (e :   Exception ) {
179+             Log .v(TAG , " Ad-silence exception in parsing accuradio" , e )
180+             return  false 
139181        }
140182    }
141183
0 commit comments