33import android .content .ClipData ;
44import android .content .ClipboardManager ;
55import android .content .Context ;
6- import android .os .Vibrator ;
6+ import android .graphics .Typeface ;
7+ import android .media .AudioAttributes ;
8+ import android .media .SoundPool ;
9+ import android .text .TextUtils ;
710
11+ import com .termux .shared .logger .Logger ;
12+ import com .termux .shared .settings .properties .TermuxPropertyConstants ;
813import com .termux .shared .terminal .TermuxTerminalSessionClientBase ;
14+ import com .termux .shared .terminal .io .BellHandler ;
15+ import com .termux .shared .termux .TermuxConstants ;
16+ import com .termux .terminal .TerminalColors ;
917import com .termux .terminal .TerminalSession ;
18+ import com .termux .terminal .TextStyle ;
19+
20+ import java .io .File ;
21+ import java .io .FileInputStream ;
22+ import java .io .InputStream ;
23+ import java .util .Properties ;
1024
1125public class TermuxFloatSessionClient extends TermuxTerminalSessionClientBase {
1226
1327 private final TermuxFloatService mService ;
28+ private final TermuxFloatView mView ;
29+
30+ private SoundPool mBellSoundPool ;
31+
32+ private int mBellSoundId ;
1433
1534 private static final String LOG_TAG = "TermuxFloatSessionClient" ;
1635
17- public TermuxFloatSessionClient (TermuxFloatService service ) {
18- this .mService = service ;
36+ public TermuxFloatSessionClient (TermuxFloatService service , TermuxFloatView view ) {
37+ mService = service ;
38+ mView = view ;
1939 }
2040
41+ /**
42+ * Should be called when TermuxFloatView.onAttachedToWindow() is called
43+ */
44+ public void onAttachedToWindow () {
45+ // Just initialize the mBellSoundPool and load the sound, otherwise bell might not run
46+ // the first time bell key is pressed and play() is called, since sound may not be loaded
47+ // quickly enough before the call to play(). https://stackoverflow.com/questions/35435625
48+ getBellSoundPool ();
49+ }
50+
51+ /**
52+ * Should be called when TermuxFloatView.onDetachedFromWindow() is called
53+ */
54+ public void onDetachedFromWindow () {
55+ // Release mBellSoundPool resources, specially to prevent exceptions like the following to be thrown
56+ // java.util.concurrent.TimeoutException: android.media.SoundPool.finalize() timed out after 10 seconds
57+ // Bell is not played in background anyways
58+ // Related: https://stackoverflow.com/a/28708351/14686958
59+ releaseBellSoundPool ();
60+ }
61+
62+ /**
63+ * Should be called when TermuxFloatView.onReload() is called
64+ */
65+ public void onReload () {
66+ checkForFontAndColors ();
67+ }
68+
69+
70+
2171 @ Override
2272 public void onTextChanged (TerminalSession changedSession ) {
23- TermuxFloatView floatingWindow = mService . getFloatingWindow () ;
24- if ( floatingWindow != null )
25- floatingWindow . mTerminalView .onScreenUpdated ();
73+ if (! mView . isVisible ()) return ;
74+
75+ mView . getTerminalView () .onScreenUpdated ();
2676 }
2777
2878 @ Override
@@ -37,8 +87,101 @@ public void onCopyTextToClipboard(TerminalSession pastingSession, String text) {
3787 }
3888
3989 @ Override
40- public void onBell (TerminalSession riningSession ) {
41- ((Vibrator ) mService .getSystemService (Context .VIBRATOR_SERVICE )).vibrate (50 );
90+ public void onPasteTextFromClipboard (TerminalSession session ) {
91+ if (!mView .isVisible ()) return ;
92+
93+ ClipboardManager clipboard = (ClipboardManager ) mService .getSystemService (Context .CLIPBOARD_SERVICE );
94+ ClipData clipData = clipboard .getPrimaryClip ();
95+ if (clipData != null ) {
96+ CharSequence paste = clipData .getItemAt (0 ).coerceToText (mService );
97+ if (!TextUtils .isEmpty (paste )) mView .getTerminalView ().mEmulator .paste (paste .toString ());
98+ }
99+ }
100+
101+ @ Override
102+ public void onBell (TerminalSession session ) {
103+ if (!mView .isVisible ()) return ;
104+
105+ switch (mView .getProperties ().getBellBehaviour ()) {
106+ case TermuxPropertyConstants .IVALUE_BELL_BEHAVIOUR_VIBRATE :
107+ BellHandler .getInstance (mService ).doBell ();
108+ break ;
109+ case TermuxPropertyConstants .IVALUE_BELL_BEHAVIOUR_BEEP :
110+ getBellSoundPool ().play (mBellSoundId , 1.f , 1.f , 1 , 0 , 1.f );
111+ break ;
112+ case TermuxPropertyConstants .IVALUE_BELL_BEHAVIOUR_IGNORE :
113+ // Ignore the bell character.
114+ break ;
115+ }
116+ }
117+
118+ @ Override
119+ public void onColorsChanged (TerminalSession changedSession ) {
120+ updateBackgroundColor ();
121+ }
122+
123+
124+ @ Override
125+ public Integer getTerminalCursorStyle () {
126+ return mView .getProperties ().getTerminalCursorStyle ();
127+ }
128+
129+
130+ /** Initialize and get mBellSoundPool */
131+ private synchronized SoundPool getBellSoundPool () {
132+ if (mBellSoundPool == null ) {
133+ mBellSoundPool = new SoundPool .Builder ().setMaxStreams (1 ).setAudioAttributes (
134+ new AudioAttributes .Builder ().setContentType (AudioAttributes .CONTENT_TYPE_SONIFICATION )
135+ .setUsage (AudioAttributes .USAGE_ASSISTANCE_SONIFICATION ).build ()).build ();
136+
137+ mBellSoundId = mBellSoundPool .load (mService , R .raw .bell , 1 );
138+ }
139+
140+ return mBellSoundPool ;
141+ }
142+
143+ /** Release mBellSoundPool resources */
144+ private synchronized void releaseBellSoundPool () {
145+ if (mBellSoundPool != null ) {
146+ mBellSoundPool .release ();
147+ mBellSoundPool = null ;
148+ }
149+ }
150+
151+
152+
153+ public void checkForFontAndColors () {
154+ try {
155+ File colorsFile = TermuxConstants .TERMUX_COLOR_PROPERTIES_FILE ;
156+ File fontFile = TermuxConstants .TERMUX_FONT_FILE ;
157+
158+ final Properties props = new Properties ();
159+ if (colorsFile .isFile ()) {
160+ try (InputStream in = new FileInputStream (colorsFile )) {
161+ props .load (in );
162+ }
163+ }
164+
165+ TerminalColors .COLOR_SCHEME .updateWith (props );
166+ TerminalSession session = mService .getSession ().getTerminalSession ();
167+ if (session != null && session .getEmulator () != null ) {
168+ session .getEmulator ().mColors .reset ();
169+ }
170+ updateBackgroundColor ();
171+
172+ final Typeface newTypeface = (fontFile .exists () && fontFile .length () > 0 ) ? Typeface .createFromFile (fontFile ) : Typeface .MONOSPACE ;
173+ mView .getTerminalView ().setTypeface (newTypeface );
174+ } catch (Exception e ) {
175+ Logger .logStackTraceWithMessage (LOG_TAG , "Error in checkForFontAndColors()" , e );
176+ }
177+ }
178+
179+ public void updateBackgroundColor () {
180+ //if (!mView.isVisible()) return;
181+ TerminalSession session = mService .getSession ().getTerminalSession ();
182+ if (session != null && session .getEmulator () != null ) {
183+ mView .getTerminalView ().setBackgroundColor (session .getEmulator ().mColors .mCurrentColors [TextStyle .COLOR_INDEX_BACKGROUND ]);
184+ }
42185 }
43186
44187}
0 commit comments