17
17
package jackpal .androidterm ;
18
18
19
19
import java .io .*;
20
+ import java .lang .reflect .Field ;
20
21
import java .util .ArrayList ;
21
22
23
+ import android .os .Build ;
22
24
import android .os .Handler ;
23
25
import android .os .Message ;
24
26
import android .os .ParcelFileDescriptor ;
35
37
* A terminal session, consisting of a TerminalEmulator, a TranscriptScreen,
36
38
* and the I/O streams used to talk to the process.
37
39
*/
38
- public class GenericTermSession extends TermSession {
40
+ class GenericTermSession extends TermSession {
39
41
//** Set to true to force into 80 x 24 for testing with vttest. */
40
42
private static final boolean VTTEST_MODE = false ;
41
43
44
+ private static Field descriptorField ;
45
+
46
+ private final long createdAt ;
47
+
42
48
// A cookie which uniquely identifies this session.
43
49
private String mHandle ;
44
50
@@ -53,7 +59,7 @@ public class GenericTermSession extends TermSession {
53
59
54
60
private UpdateCallback mUTF8ModeNotify = new UpdateCallback () {
55
61
public void onUpdate () {
56
- Exec . setPtyUTF8Mode (mTermFd , getUTF8Mode ());
62
+ setPtyUTF8Mode (getUTF8Mode ());
57
63
}
58
64
};
59
65
@@ -62,6 +68,8 @@ public void onUpdate() {
62
68
63
69
this .mTermFd = mTermFd ;
64
70
71
+ this .createdAt = System .currentTimeMillis ();
72
+
65
73
updatePrefs (settings );
66
74
}
67
75
@@ -79,7 +87,7 @@ public void initializeEmulator(int columns, int rows) {
79
87
}
80
88
super .initializeEmulator (columns , rows );
81
89
82
- Exec . setPtyUTF8Mode (mTermFd , getUTF8Mode ());
90
+ setPtyUTF8Mode (getUTF8Mode ());
83
91
setUTF8ModeUpdateCallback (mUTF8ModeNotify );
84
92
}
85
93
@@ -90,7 +98,7 @@ public void updateSize(int columns, int rows) {
90
98
rows = 24 ;
91
99
}
92
100
// Inform the attached pty of our new size:
93
- Exec . setPtyWindowSize (mTermFd , rows , columns , 0 , 0 );
101
+ setPtyWindowSize (rows , columns , 0 , 0 );
94
102
super .updateSize (columns , rows );
95
103
}
96
104
@@ -117,7 +125,12 @@ protected void onProcessExit() {
117
125
118
126
@ Override
119
127
public void finish () {
120
- Exec .close (mTermFd );
128
+ try {
129
+ mTermFd .close ();
130
+ } catch (IOException e ) {
131
+ // ok
132
+ }
133
+
121
134
super .finish ();
122
135
}
123
136
@@ -130,7 +143,7 @@ public void finish() {
130
143
* unset or an empty string.
131
144
*/
132
145
public String getTitle (String defaultTitle ) {
133
- String title = super . getTitle ();
146
+ String title = getTitle ();
134
147
if (title != null && title .length () > 0 ) {
135
148
return title ;
136
149
} else {
@@ -148,4 +161,76 @@ public void setHandle(String handle) {
148
161
public String getHandle () {
149
162
return mHandle ;
150
163
}
164
+
165
+ @ Override
166
+ public String toString () {
167
+ return getClass ().getSimpleName () + '(' + createdAt + ',' + mHandle + ')' ;
168
+ }
169
+
170
+ /**
171
+ * Set the widow size for a given pty. Allows programs
172
+ * connected to the pty learn how large their screen is.
173
+ */
174
+ void setPtyWindowSize (int row , int col , int xpixel , int ypixel ) {
175
+ // If the tty goes away too quickly, this may get called after it's descriptor is closed
176
+ if (!mTermFd .getFileDescriptor ().valid ())
177
+ return ;
178
+
179
+ try {
180
+ Exec .setPtyWindowSizeInternal (getIntFd (mTermFd ), row , col , xpixel , ypixel );
181
+ } catch (IOException e ) {
182
+ Log .e ("exec" , "Failed to set window size: " + e .getMessage ());
183
+
184
+ if (isFailFast ())
185
+ throw new IllegalStateException (e );
186
+ }
187
+ }
188
+
189
+ /**
190
+ * Set or clear UTF-8 mode for a given pty. Used by the terminal driver
191
+ * to implement correct erase behavior in cooked mode (Linux >= 2.6.4).
192
+ */
193
+ void setPtyUTF8Mode (boolean utf8Mode ) {
194
+ // If the tty goes away too quickly, this may get called after it's descriptor is closed
195
+ if (!mTermFd .getFileDescriptor ().valid ())
196
+ return ;
197
+
198
+ try {
199
+ Exec .setPtyUTF8ModeInternal (getIntFd (mTermFd ), utf8Mode );
200
+ } catch (IOException e ) {
201
+ Log .e ("exec" , "Failed to set UTF mode: " + e .getMessage ());
202
+
203
+ if (isFailFast ())
204
+ throw new IllegalStateException (e );
205
+ }
206
+ }
207
+
208
+ /**
209
+ * @return true, if failing to operate on file descriptor deserves an exception (never the case for ATE own shell)
210
+ */
211
+ boolean isFailFast () {
212
+ return false ;
213
+ }
214
+
215
+ private static void cacheDescField () throws NoSuchFieldException {
216
+ if (descriptorField != null )
217
+ return ;
218
+
219
+ descriptorField = FileDescriptor .class .getDeclaredField ("descriptor" );
220
+ descriptorField .setAccessible (true );
221
+ }
222
+
223
+ private static int getIntFd (ParcelFileDescriptor parcelFd ) throws IOException {
224
+ if (Build .VERSION .SDK_INT >= 12 )
225
+ return FdHelperHoneycomb .getFd (parcelFd );
226
+ else {
227
+ try {
228
+ cacheDescField ();
229
+
230
+ return descriptorField .getInt (parcelFd .getFileDescriptor ());
231
+ } catch (Exception e ) {
232
+ throw new IOException ("Unable to obtain file descriptor on this OS version: " + e .getMessage ());
233
+ }
234
+ }
235
+ }
151
236
}
0 commit comments