160 lines
4.0 KiB
Java
160 lines
4.0 KiB
Java
/*
|
|
* ConnectBot: simple, powerful, open-source SSH client for Android
|
|
* Copyright 2007 Kenny Root, Jeffrey Sharkey
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package org.connectbot.service;
|
|
|
|
import java.util.concurrent.Semaphore;
|
|
|
|
import android.os.Handler;
|
|
import android.os.Message;
|
|
|
|
/**
|
|
* Helps provide a relay for prompts and responses between a possible user
|
|
* interface and some underlying service.
|
|
*
|
|
* @author jsharkey
|
|
*/
|
|
public class PromptHelper {
|
|
private final Object tag;
|
|
|
|
private Handler handler = null;
|
|
|
|
private Semaphore promptToken;
|
|
private Semaphore promptResponse;
|
|
|
|
public String promptInstructions = null;
|
|
public String promptHint = null;
|
|
public Object promptRequested = null;
|
|
|
|
private Object response = null;
|
|
|
|
public PromptHelper(Object tag) {
|
|
this.tag = tag;
|
|
|
|
// Threads must acquire this before they can send a prompt.
|
|
promptToken = new Semaphore(1);
|
|
|
|
// Responses will release this semaphore.
|
|
promptResponse = new Semaphore(0);
|
|
}
|
|
|
|
|
|
/**
|
|
* Register a user interface handler, if available.
|
|
*/
|
|
public void setHandler(Handler handler) {
|
|
this.handler = handler;
|
|
}
|
|
|
|
/**
|
|
* Set an incoming value from an above user interface. Will automatically
|
|
* notify any waiting requests.
|
|
*/
|
|
public void setResponse(Object value) {
|
|
response = value;
|
|
promptResponse.release();
|
|
}
|
|
|
|
/**
|
|
* Return the internal response value just before erasing and returning it.
|
|
*/
|
|
protected Object popResponse() {
|
|
Object value = response;
|
|
response = null;
|
|
return value;
|
|
}
|
|
|
|
|
|
/**
|
|
* Request a prompt response from parent. This is a blocking call until user
|
|
* interface returns a value.
|
|
* Only one thread can call this at a time. cancelPrompt() will force this to
|
|
* immediately return.
|
|
*/
|
|
private Object requestPrompt(String instructions, String hint, Object type) throws InterruptedException {
|
|
Object response = null;
|
|
|
|
promptToken.acquire();
|
|
|
|
try {
|
|
promptInstructions = instructions;
|
|
promptHint = hint;
|
|
promptRequested = type;
|
|
|
|
// notify any parent watching for live events
|
|
if (handler != null)
|
|
Message.obtain(handler, -1, tag).sendToTarget();
|
|
|
|
// acquire lock until user passes back value
|
|
promptResponse.acquire();
|
|
promptInstructions = null;
|
|
promptHint = null;
|
|
promptRequested = null;
|
|
|
|
response = popResponse();
|
|
} finally {
|
|
promptToken.release();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/**
|
|
* Request a string response from parent. This is a blocking call until user
|
|
* interface returns a value.
|
|
* @param hint prompt hint for user to answer
|
|
* @return string user has entered
|
|
*/
|
|
public String requestStringPrompt(String instructions, String hint) {
|
|
String value = null;
|
|
try {
|
|
value = (String)this.requestPrompt(instructions, hint, String.class);
|
|
} catch(Exception e) {
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Request a boolean response from parent. This is a blocking call until user
|
|
* interface returns a value.
|
|
* @param hint prompt hint for user to answer
|
|
* @return choice user has made (yes/no)
|
|
*/
|
|
public Boolean requestBooleanPrompt(String instructions, String hint) {
|
|
Boolean value = null;
|
|
try {
|
|
value = (Boolean)this.requestPrompt(instructions, hint, Boolean.class);
|
|
} catch(Exception e) {
|
|
}
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* Cancel an in-progress prompt.
|
|
*/
|
|
public void cancelPrompt() {
|
|
if (!promptToken.tryAcquire()) {
|
|
// A thread has the token, so try to interrupt it
|
|
response = null;
|
|
promptResponse.release();
|
|
} else {
|
|
// No threads have acquired the token
|
|
promptToken.release();
|
|
}
|
|
}
|
|
}
|