3
3
import android .content .ClipData ;
4
4
import android .content .ClipboardManager ;
5
5
import 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 ;
7
10
11
+ import com .termux .shared .logger .Logger ;
12
+ import com .termux .shared .settings .properties .TermuxPropertyConstants ;
8
13
import 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 ;
9
17
import 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 ;
10
24
11
25
public class TermuxFloatSessionClient extends TermuxTerminalSessionClientBase {
12
26
13
27
private final TermuxFloatService mService ;
28
+ private final TermuxFloatView mView ;
29
+
30
+ private SoundPool mBellSoundPool ;
31
+
32
+ private int mBellSoundId ;
14
33
15
34
private static final String LOG_TAG = "TermuxFloatSessionClient" ;
16
35
17
- public TermuxFloatSessionClient (TermuxFloatService service ) {
18
- this .mService = service ;
36
+ public TermuxFloatSessionClient (TermuxFloatService service , TermuxFloatView view ) {
37
+ mService = service ;
38
+ mView = view ;
19
39
}
20
40
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
+
21
71
@ Override
22
72
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 ();
26
76
}
27
77
28
78
@ Override
@@ -37,8 +87,101 @@ public void onCopyTextToClipboard(TerminalSession pastingSession, String text) {
37
87
}
38
88
39
89
@ 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
+ }
42
185
}
43
186
44
187
}
0 commit comments