comparison src/com/five_ten_sg/connectbot/service/PromptHelper.java @ 0:0ce5cc452d02

initial version
author Carl Byington <carl@five-ten-sg.com>
date Thu, 22 May 2014 10:41:19 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:0ce5cc452d02
1 /*
2 * ConnectBot: simple, powerful, open-source SSH client for Android
3 * Copyright 2007 Kenny Root, Jeffrey Sharkey
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package com.five_ten_sg.connectbot.service;
19
20 import java.util.concurrent.Semaphore;
21
22 import android.os.Handler;
23 import android.os.Message;
24
25 /**
26 * Helps provide a relay for prompts and responses between a possible user
27 * interface and some underlying service.
28 *
29 * @author jsharkey
30 */
31 public class PromptHelper {
32 private final Object tag;
33
34 private Handler handler = null;
35
36 private Semaphore promptToken;
37 private Semaphore promptResponse;
38
39 public String promptInstructions = null;
40 public String promptHint = null;
41 public Object promptRequested = null;
42 public boolean passwordRequested = true;
43
44 private Object response = null;
45
46 public PromptHelper(Object tag) {
47 this.tag = tag;
48 // Threads must acquire this before they can send a prompt.
49 promptToken = new Semaphore(1);
50 // Responses will release this semaphore.
51 promptResponse = new Semaphore(0);
52 }
53
54
55 /**
56 * Register a user interface handler, if available.
57 */
58 public void setHandler(Handler handler) {
59 this.handler = handler;
60 }
61
62 /**
63 * Set an incoming value from an above user interface. Will automatically
64 * notify any waiting requests.
65 */
66 public void setResponse(Object value) {
67 response = value;
68 promptRequested = null;
69 promptInstructions = null;
70 promptHint = null;
71 promptResponse.release();
72 }
73
74 /**
75 * Return the internal response value just before erasing and returning it.
76 */
77 protected Object popResponse() {
78 Object value = response;
79 response = null;
80 return value;
81 }
82
83
84 /**
85 * Request a prompt response from parent. This is a blocking call until user
86 * interface returns a value.
87 * Only one thread can call this at a time. cancelPrompt() will force this to
88 * immediately return.
89 */
90 private Object requestPrompt(String instructions, String hint, Object type) throws InterruptedException {
91 Object response = null;
92 promptToken.acquire();
93
94 try {
95 promptInstructions = instructions;
96 promptHint = hint;
97 promptRequested = type;
98
99 // notify any parent watching for live events
100 if (handler != null)
101 Message.obtain(handler, -1, tag).sendToTarget();
102
103 // acquire lock until user passes back value
104 promptResponse.acquire();
105 response = popResponse();
106 }
107 finally {
108 promptToken.release();
109 }
110
111 return response;
112 }
113
114 /**
115 * Request a string response from parent. This is a blocking call until user
116 * interface returns a value.
117 * @param hint prompt hint for user to answer
118 * @return string user has entered
119 */
120 public String requestStringPrompt(String instructions, String hint) {
121 String value = null;
122 passwordRequested = false;
123
124 try {
125 value = (String)this.requestPrompt(instructions, hint, String.class);
126 }
127 catch (Exception e) {
128 }
129
130 return value;
131 }
132
133 /**
134 * Request a password response from parent. This is a blocking call until user
135 * interface returns a value.
136 * @param hint prompt hint for user to answer
137 * @return string user has entered
138 */
139 public String requestPasswordPrompt(String instructions, String hint) {
140 String value = null;
141 passwordRequested = true;
142
143 try {
144 value = (String)this.requestPrompt(instructions, hint, String.class);
145 }
146 catch (Exception e) {
147 }
148
149 return value;
150 }
151
152 /**
153 * Request a boolean response from parent. This is a blocking call until user
154 * interface returns a value.
155 * @param hint prompt hint for user to answer
156 * @return choice user has made (yes/no)
157 */
158 public Boolean requestBooleanPrompt(String instructions, String hint) {
159 Boolean value = null;
160
161 try {
162 value = (Boolean)this.requestPrompt(instructions, hint, Boolean.class);
163 }
164 catch (Exception e) {
165 }
166
167 return value;
168 }
169
170 /**
171 * Cancel an in-progress prompt.
172 */
173 public void cancelPrompt() {
174 if (!promptToken.tryAcquire()) {
175 // A thread has the token, so try to interrupt it
176 response = null;
177 promptResponse.release();
178 }
179 else {
180 // No threads have acquired the token
181 promptToken.release();
182 }
183 }
184 }