diff options
author | Nathan Harold <nharold@google.com> | 2016-02-10 18:38:44 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2016-02-10 18:38:44 +0000 |
commit | 1e8f01cc80946b394d17ab4ef189f1ef7d9891ca (patch) | |
tree | ae70060a5dc3aa8b0da015046fef7b4d10a7c673 | |
parent | 6885fe4311ee263e6b1301973f4f57cf8b19c07c (diff) | |
parent | 8fc5e96e8a5187117df3a05cefff9141e29fb302 (diff) | |
download | platform_packages_apps_Test_connectivity-1e8f01cc80946b394d17ab4ef189f1ef7d9891ca.tar.gz platform_packages_apps_Test_connectivity-1e8f01cc80946b394d17ab4ef189f1ef7d9891ca.tar.bz2 platform_packages_apps_Test_connectivity-1e8f01cc80946b394d17ab4ef189f1ef7d9891ca.zip |
Merge "Remove sl4a from packages/apps/Test/connectivity" into nyc-dev
334 files changed, 0 insertions, 55053 deletions
diff --git a/sl4a/Android.mk b/sl4a/Android.mk deleted file mode 100644 index d6432d8..0000000 --- a/sl4a/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -## Copyright (C) 2016 Google, Inc. -# -## 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -include $(call all-makefiles-under,$(LOCAL_PATH)) - diff --git a/sl4a/Common/Android.mk b/sl4a/Common/Android.mk deleted file mode 100644 index fc92181..0000000 --- a/sl4a/Common/Android.mk +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - - -LOCAL_MODULE := sl4a.Common -LOCAL_MODULE_OWNER := google - -LOCAL_STATIC_JAVA_LIBRARIES := guava android-common sl4a.Utils -LOCAL_JAVA_LIBRARIES := telephony-common -LOCAL_JAVA_LIBRARIES += ims-common - -LOCAL_SRC_FILES := $(call all-java-files-under, src/com/googlecode/android_scripting) -LOCAL_SRC_FILES += $(call all-java-files-under, src/org/apache/commons/codec) - -include $(BUILD_STATIC_JAVA_LIBRARY) - -include $(CLEAR_VARS) -include $(BUILD_MULTI_PREBUILT) diff --git a/sl4a/Common/src/com/googlecode/android_scripting/BaseApplication.java b/sl4a/Common/src/com/googlecode/android_scripting/BaseApplication.java deleted file mode 100644 index f0b6905..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/BaseApplication.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.Application; - -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.trigger.TriggerRepository; - -public class BaseApplication extends Application { - - private final FutureActivityTaskExecutor mTaskExecutor = new FutureActivityTaskExecutor(this); - private TriggerRepository mTriggerRepository; - - protected InterpreterConfiguration mConfiguration; - - public FutureActivityTaskExecutor getTaskExecutor() { - return mTaskExecutor; - } - - @Override - public void onCreate() { - mConfiguration = new InterpreterConfiguration(this); - mConfiguration.startDiscovering(); - mTriggerRepository = new TriggerRepository(this); - } - - public InterpreterConfiguration getInterpreterConfiguration() { - return mConfiguration; - } - - public TriggerRepository getTriggerRepository() { - return mTriggerRepository; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/Constants.java b/sl4a/Common/src/com/googlecode/android_scripting/Constants.java deleted file mode 100644 index 4b18bba..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/Constants.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.ComponentName; - -public interface Constants { - - public static final String ACTION_LAUNCH_FOREGROUND_SCRIPT = - "com.googlecode.android_scripting.action.LAUNCH_FOREGROUND_SCRIPT"; - public static final String ACTION_LAUNCH_BACKGROUND_SCRIPT = - "com.googlecode.android_scripting.action.LAUNCH_BACKGROUND_SCRIPT"; - public static final String ACTION_LAUNCH_SCRIPT_FOR_RESULT = - "com.googlecode.android_scripting.action.ACTION_LAUNCH_SCRIPT_FOR_RESULT"; - public static final String ACTION_LAUNCH_INTERPRETER = - "com.googlecode.android_scripting.action.LAUNCH_INTERPRETER"; - public static final String ACTION_EDIT_SCRIPT = - "com.googlecode.android_scripting.action.EDIT_SCRIPT"; - public static final String ACTION_SAVE_SCRIPT = - "com.googlecode.android_scripting.action.SAVE_SCRIPT"; - public static final String ACTION_SAVE_AND_RUN_SCRIPT = - "com.googlecode.android_scripting.action.SAVE_AND_RUN_SCRIPT"; - public static final String ACTION_KILL_PROCESS = - "com.googlecode.android_scripting.action.KILL_PROCESS"; - public static final String ACTION_KILL_ALL = "com.googlecode.android_scripting.action.KILL_ALL"; - public static final String ACTION_SHOW_RUNNING_SCRIPTS = - "com.googlecode.android_scripting.action.SHOW_RUNNING_SCRIPTS"; - public static final String ACTION_CANCEL_NOTIFICATION = - "com.googlecode.android_scripting.action.CANCEL_NOTIFICAITON"; - public static final String ACTION_ACTIVITY_RESULT = - "com.googlecode.android_scripting.action.ACTIVITY_RESULT"; - public static final String ACTION_LAUNCH_SERVER = - "com.googlecode.android_scripting.action.LAUNCH_SERVER"; - - public static final String EXTRA_RESULT = "SCRIPT_RESULT"; - public static final String EXTRA_SCRIPT_PATH = - "com.googlecode.android_scripting.extra.SCRIPT_PATH"; - public static final String EXTRA_SCRIPT_CONTENT = - "com.googlecode.android_scripting.extra.SCRIPT_CONTENT"; - public static final String EXTRA_INTERPRETER_NAME = - "com.googlecode.android_scripting.extra.INTERPRETER_NAME"; - - public static final String EXTRA_USE_EXTERNAL_IP = - "com.googlecode.android_scripting.extra.USE_PUBLIC_IP"; - public static final String EXTRA_USE_SERVICE_PORT = - "com.googlecode.android_scripting.extra.USE_SERVICE_PORT"; - public static final String EXTRA_SCRIPT_TEXT = - "com.googlecode.android_scripting.extra.SCRIPT_TEXT"; - public static final String EXTRA_RPC_HELP_TEXT = - "com.googlecode.android_scripting.extra.RPC_HELP_TEXT"; - public static final String EXTRA_API_PROMPT_RPC_NAME = - "com.googlecode.android_scripting.extra.API_PROMPT_RPC_NAME"; - public static final String EXTRA_API_PROMPT_VALUES = - "com.googlecode.android_scripting.extra.API_PROMPT_VALUES"; - public static final String EXTRA_PROXY_PORT = "com.googlecode.android_scripting.extra.PROXY_PORT"; - public static final String EXTRA_PROCESS_ID = - "com.googlecode.android_scripting.extra.SCRIPT_PROCESS_ID"; - public static final String EXTRA_IS_NEW_SCRIPT = - "com.googlecode.android_scripting.extra.IS_NEW_SCRIPT"; - public static final String EXTRA_TRIGGER_ID = - "com.googlecode.android_scripting.extra.EXTRA_TRIGGER_ID"; - public static final String EXTRA_LAUNCH_IN_BACKGROUND = - "com.googlecode.android_scripting.extra.EXTRA_LAUNCH_IN_BACKGROUND"; - public static final String EXTRA_TASK_ID = "com.googlecode.android_scripting.extra.EXTRA_TASK_ID"; - - // BluetoothDeviceManager - public static final String EXTRA_DEVICE_ADDRESS = - "com.googlecode.android_scripting.extra.device_address"; - - public static final ComponentName SL4A_SERVICE_COMPONENT_NAME = new ComponentName( - "com.googlecode.android_scripting", - "com.googlecode.android_scripting.activity.ScriptingLayerService"); - public static final ComponentName SL4A_SERVICE_LAUNCHER_COMPONENT_NAME = new ComponentName( - "com.googlecode.android_scripting", - "com.googlecode.android_scripting.activity.ScriptingLayerServiceLauncher"); - public static final ComponentName BLUETOOTH_DEVICE_LIST_COMPONENT_NAME = new ComponentName( - "com.googlecode.android_scripting", - "com.googlecode.android_scripting.activity.BluetoothDeviceList"); - public static final ComponentName TRIGGER_SERVICE_COMPONENT_NAME = new ComponentName( - "com.googlecode.android_scripting", - "com.googlecode.android_scripting.activity.TriggerService"); - - // Preference Keys - - public static final String FORCE_BROWSER = "helpForceBrowser"; - public final static String HIDE_NOTIFY = "hideServiceNotifications"; -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/Exec.java b/sl4a/Common/src/com/googlecode/android_scripting/Exec.java deleted file mode 100644 index 778b5a3..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/Exec.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import java.io.FileDescriptor; - -/** - * Tools for executing commands. - */ -public class Exec { - /** - * @param cmd - * The command to execute - * @param arg0 - * The first argument to the command, may be null - * @param arg1 - * the second argument to the command, may be null - * @return the file descriptor of the started process. - * - */ - public static FileDescriptor createSubprocess(String command, String[] arguments, - String[] environmentVariables, String workingDirectory) { - return createSubprocess(command, arguments, environmentVariables, workingDirectory, null); - } - - /** - * @param cmd - * The command to execute - * @param arguments - * Array of arguments, may be null - * @param environmentVariables - * Array of environment variables, may be null - * @param processId - * A one-element array to which the process ID of the started process will be written. - * @return the file descriptor of the opened process's psuedo-terminal. - * - */ - public static native FileDescriptor createSubprocess(String command, String[] arguments, - String[] environmentVariables, String workingDirectory, int[] processId); - - public static native void setPtyWindowSize(FileDescriptor fd, int row, int col, int xpixel, - int ypixel); - - /** - * Causes the calling thread to wait for the process associated with the receiver to finish - * executing. - * - * @return The exit value of the Process being waited on - * - */ - public static native int waitFor(int processId); - - static { - System.loadLibrary("com_googlecode_android_scripting_Exec"); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/FeaturedInterpreters.java b/sl4a/Common/src/com/googlecode/android_scripting/FeaturedInterpreters.java deleted file mode 100644 index 005560b..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/FeaturedInterpreters.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class FeaturedInterpreters { - private static final Map<String, FeaturedInterpreter> mNameMap = - new HashMap<String, FeaturedInterpreter>(); - private static final Map<String, FeaturedInterpreter> mExtensionMap = - new HashMap<String, FeaturedInterpreter>(); - - static { - try { - FeaturedInterpreter interpreters[] = - { - new FeaturedInterpreter("BeanShell 2.0b4", ".bsh", - "http://android-scripting.googlecode.com/files/beanshell_for_android_r2.apk"), - new FeaturedInterpreter("JRuby", ".rb", - "https://github.com/downloads/ruboto/sl4a_jruby_interpreter/JRubyForAndroid_r2dev.apk"), - new FeaturedInterpreter("Lua 5.1.4", ".lua", - "http://android-scripting.googlecode.com/files/lua_for_android_r1.apk"), - new FeaturedInterpreter("Perl 5.10.1", ".pl", - "http://android-scripting.googlecode.com/files/perl_for_android_r1.apk"), - new FeaturedInterpreter("Python 2.6.2", ".py", - "http://python-for-android.googlecode.com/files/PythonForAndroid_r5.apk"), - new FeaturedInterpreter("Rhino 1.7R2", ".js", - "http://android-scripting.googlecode.com/files/rhino_for_android_r2.apk"), - new FeaturedInterpreter("PHP 5.3.3", ".php", - "http://php-for-android.googlecode.com/files/phpforandroid_r1.apk") }; - for (FeaturedInterpreter interpreter : interpreters) { - mNameMap.put(interpreter.mmName, interpreter); - mExtensionMap.put(interpreter.mmExtension, interpreter); - } - } catch (MalformedURLException e) { - Log.e(e); - } - } - - public static List<String> getList() { - ArrayList<String> list = new ArrayList<String>(mNameMap.keySet()); - Collections.sort(list); - return list; - } - - public static URL getUrlForName(String name) { - if (!mNameMap.containsKey(name)) { - return null; - } - return mNameMap.get(name).mmUrl; - } - - public static String getInterpreterNameForScript(String fileName) { - String extension = getExtension(fileName); - if (extension == null || !mExtensionMap.containsKey(extension)) { - return null; - } - return mExtensionMap.get(extension).mmName; - } - - public static boolean isSupported(String fileName) { - String extension = getExtension(fileName); - return (extension != null) && (mExtensionMap.containsKey(extension)); - } - - public static int getInterpreterIcon(Context context, String key) { - String packageName = context.getPackageName(); - String name = "_icon"; - if (key.contains(".")) { - name = key.substring(key.lastIndexOf('.') + 1) + name; - } else { - name = key + name; - } - return context.getResources().getIdentifier(name, "drawable", packageName); - } - - private static String getExtension(String fileName) { - int dotIndex = fileName.lastIndexOf('.'); - if (dotIndex == -1) { - return null; - } - return fileName.substring(dotIndex); - } - - private static class FeaturedInterpreter { - private final String mmName; - private final String mmExtension; - private final URL mmUrl; - - private FeaturedInterpreter(String name, String extension, String url) - throws MalformedURLException { - mmName = name; - mmExtension = extension; - mmUrl = new URL(url); - } - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/FutureActivityTaskExecutor.java b/sl4a/Common/src/com/googlecode/android_scripting/FutureActivityTaskExecutor.java deleted file mode 100644 index 374d122..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/FutureActivityTaskExecutor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.content.Intent; - -import com.googlecode.android_scripting.activity.FutureActivity; -import com.googlecode.android_scripting.future.FutureActivityTask; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -public class FutureActivityTaskExecutor { - - private final Context mContext; - private final Map<Integer, FutureActivityTask<?>> mTaskMap = - new ConcurrentHashMap<Integer, FutureActivityTask<?>>(); - private final AtomicInteger mIdGenerator = new AtomicInteger(0); - - public FutureActivityTaskExecutor(Context context) { - mContext = context; - } - - public void execute(FutureActivityTask<?> task) { - int id = mIdGenerator.incrementAndGet(); - mTaskMap.put(id, task); - launchHelper(id); - } - - public FutureActivityTask<?> getTask(int id) { - return mTaskMap.remove(id); - } - - private void launchHelper(int id) { - Intent helper = new Intent(mContext, FutureActivity.class); - helper.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - helper.putExtra(Constants.EXTRA_TASK_ID, id); - mContext.startActivity(helper); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/IntentBuilders.java b/sl4a/Common/src/com/googlecode/android_scripting/IntentBuilders.java deleted file mode 100644 index 9941c4e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/IntentBuilders.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.PendingIntent; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.os.Parcelable; - -import com.googlecode.android_scripting.interpreter.Interpreter; - -import java.io.File; - -public class IntentBuilders { - /** An arbitrary value that is used to identify pending intents for executing scripts. */ - private static final int EXECUTE_SCRIPT_REQUEST_CODE = 0x12f412a; - - private IntentBuilders() { - // Utility class. - } - - public static Intent buildTriggerServiceIntent() { - Intent intent = new Intent(); - intent.setComponent(Constants.TRIGGER_SERVICE_COMPONENT_NAME); - return intent; - } - - /** - * Builds an intent that will launch a script in the background. - * - * @param script - * the script to launch - * @return the intent that will launch the script - */ - public static Intent buildStartInBackgroundIntent(File script) { - final ComponentName componentName = Constants.SL4A_SERVICE_LAUNCHER_COMPONENT_NAME; - Intent intent = new Intent(); - intent.setComponent(componentName); - intent.setAction(Constants.ACTION_LAUNCH_BACKGROUND_SCRIPT); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, script.getAbsolutePath()); - return intent; - } - - /** - * Builds an intent that launches a script in a terminal. - * - * @param script - * the script to launch - * @return the intent that will launch the script - */ - public static Intent buildStartInTerminalIntent(File script) { - final ComponentName componentName = Constants.SL4A_SERVICE_LAUNCHER_COMPONENT_NAME; - Intent intent = new Intent(); - intent.setComponent(componentName); - intent.setAction(Constants.ACTION_LAUNCH_FOREGROUND_SCRIPT); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, script.getAbsolutePath()); - return intent; - } - - /** - * Builds an intent that launches an interpreter. - * - * @param interpreterName - * the interpreter to launch - * @return the intent that will launch the interpreter - */ - public static Intent buildStartInterpreterIntent(String interpreterName) { - final ComponentName componentName = Constants.SL4A_SERVICE_LAUNCHER_COMPONENT_NAME; - Intent intent = new Intent(); - intent.setComponent(componentName); - intent.setAction(Constants.ACTION_LAUNCH_INTERPRETER); - intent.putExtra(Constants.EXTRA_INTERPRETER_NAME, interpreterName); - return intent; - } - - /** - * Builds an intent that creates a shortcut to launch the provided interpreter. - * - * @param interpreter - * the interpreter to link to - * @param iconResource - * the icon resource to associate with the shortcut - * @return the intent that will create the shortcut - */ - public static Intent buildInterpreterShortcutIntent(Interpreter interpreter, - Parcelable iconResource) { - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, - buildStartInterpreterIntent(interpreter.getName())); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, interpreter.getNiceName()); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - return intent; - } - - /** - * Builds an intent that creates a shortcut to launch the provided script in the background. - * - * @param script - * the script to link to - * @param iconResource - * the icon resource to associate with the shortcut - * @return the intent that will create the shortcut - */ - public static Intent buildBackgroundShortcutIntent(File script, Parcelable iconResource) { - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, buildStartInBackgroundIntent(script)); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, script.getName()); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - return intent; - } - - /** - * Builds an intent that creates a shortcut to launch the provided script in a terminal. - * - * @param script - * the script to link to - * @param iconResource - * the icon resource to associate with the shortcut - * @return the intent that will create the shortcut - */ - public static Intent buildTerminalShortcutIntent(File script, Parcelable iconResource) { - Intent intent = new Intent(); - intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, buildStartInTerminalIntent(script)); - intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, script.getName()); - intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); - return intent; - } - - /** - * Creates a pending intent that can be used to start the trigger service. - * - * @param context - * the context under whose authority to launch the intent - * - * @return {@link PendingIntent} object for running the trigger service - */ - public static PendingIntent buildTriggerServicePendingIntent(Context context) { - final Intent intent = buildTriggerServiceIntent(); - return PendingIntent.getService(context, EXECUTE_SCRIPT_REQUEST_CODE, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/Process.java b/sl4a/Common/src/com/googlecode/android_scripting/Process.java deleted file mode 100644 index 25a80be..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/Process.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import com.googlecode.android_scripting.interpreter.InterpreterConstants; -import com.trilead.ssh2.StreamGobbler; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicInteger; - -public class Process { - - private static final int DEFAULT_BUFFER_SIZE = 8192; - - private final List<String> mArguments; - private final Map<String, String> mEnvironment; - - private static final int PID_INIT_VALUE = -1; - - private File mBinary; - private String mName; - private long mStartTime; - private long mEndTime; - - protected final AtomicInteger mPid; - protected FileDescriptor mFd; - protected OutputStream mOut; - protected InputStream mIn; - protected File mLog; - - public Process() { - mArguments = new ArrayList<String>(); - mEnvironment = new HashMap<String, String>(); - mPid = new AtomicInteger(PID_INIT_VALUE); - } - - public void addArgument(String argument) { - mArguments.add(argument); - } - - public void addAllArguments(List<String> arguments) { - mArguments.addAll(arguments); - } - - public void putAllEnvironmentVariables(Map<String, String> environment) { - mEnvironment.putAll(environment); - } - - public void putEnvironmentVariable(String key, String value) { - mEnvironment.put(key, value); - } - - public void setBinary(File binary) { - if (!binary.exists()) { - throw new RuntimeException("Binary " + binary + " does not exist!"); - } - mBinary = binary; - } - - public Integer getPid() { - return mPid.get(); - } - - public FileDescriptor getFd() { - return mFd; - } - - public OutputStream getOut() { - return mOut; - } - - public OutputStream getErr() { - return getOut(); - } - - public File getLogFile() { - return mLog; - } - - public InputStream getIn() { - return mIn; - } - - public void start(final Runnable shutdownHook) { - if (isAlive()) { - throw new RuntimeException("Attempted to start process that is already running."); - } - - String binaryPath = mBinary.getAbsolutePath(); - Log.v("Executing " + binaryPath + " with arguments " + mArguments + " and with environment " - + mEnvironment.toString()); - - int[] pid = new int[1]; - String[] argumentsArray = mArguments.toArray(new String[mArguments.size()]); - mLog = new File(String.format("%s/%s.log", InterpreterConstants.SDCARD_SL4A_ROOT, getName())); - - mFd = - Exec.createSubprocess(binaryPath, argumentsArray, getEnvironmentArray(), - getWorkingDirectory(), pid); - mPid.set(pid[0]); - mOut = new FileOutputStream(mFd); - mIn = new StreamGobbler(new FileInputStream(mFd), mLog, DEFAULT_BUFFER_SIZE); - mStartTime = System.currentTimeMillis(); - - new Thread(new Runnable() { - public void run() { - int result = Exec.waitFor(mPid.get()); - mEndTime = System.currentTimeMillis(); - int pid = mPid.getAndSet(PID_INIT_VALUE); - Log.v("Process " + pid + " exited with result code " + result + "."); - try { - mIn.close(); - } catch (IOException e) { - Log.e(e); - } - try { - mOut.close(); - } catch (IOException e) { - Log.e(e); - } - if (shutdownHook != null) { - shutdownHook.run(); - } - } - }).start(); - } - - private String[] getEnvironmentArray() { - List<String> environmentVariables = new ArrayList<String>(); - for (Entry<String, String> entry : mEnvironment.entrySet()) { - environmentVariables.add(entry.getKey() + "=" + entry.getValue()); - } - String[] environment = environmentVariables.toArray(new String[environmentVariables.size()]); - return environment; - } - - public void kill() { - if (isAlive()) { - android.os.Process.killProcess(mPid.get()); - Log.v("Killed process " + mPid); - } - } - - public boolean isAlive() { - return (mFd != null && mFd.valid()) && mPid.get() != PID_INIT_VALUE; - } - - public String getUptime() { - long ms; - if (!isAlive()) { - ms = mEndTime - mStartTime; - } else { - ms = System.currentTimeMillis() - mStartTime; - } - StringBuilder buffer = new StringBuilder(); - int days = (int) (ms / (1000 * 60 * 60 * 24)); - int hours = (int) (ms % (1000 * 60 * 60 * 24)) / 3600000; - int minutes = (int) (ms % 3600000) / 60000; - int seconds = (int) (ms % 60000) / 1000; - if (days != 0) { - buffer.append(String.format("%02d:%02d:", days, hours)); - } else if (hours != 0) { - buffer.append(String.format("%02d:", hours)); - } - buffer.append(String.format("%02d:%02d", minutes, seconds)); - return buffer.toString(); - } - - public String getName() { - return mName; - } - - public void setName(String name) { - mName = name; - } - - public String getWorkingDirectory() { - return null; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/Version.java b/sl4a/Common/src/com/googlecode/android_scripting/Version.java deleted file mode 100644 index 4ef9fff..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/Version.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; - -public class Version { - - private Version() { - // Utility class. - } - - public static String getVersion(Context context) { - try { - PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); - return info.versionName; - } catch (PackageManager.NameNotFoundException e) { - Log.e("Package name not found", e); - } - return "?"; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/activity/FutureActivity.java b/sl4a/Common/src/com/googlecode/android_scripting/activity/FutureActivity.java deleted file mode 100644 index 20e1bf9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/activity/FutureActivity.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.app.Service; -import android.content.Intent; -import android.content.pm.ResolveInfo; -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.View; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; - -/** - * This {@link Activity} is launched by {@link RpcReceiver}s in order to perform operations that a - * {@link Service} is unable to do. For example: start another activity for result, show dialogs, - * etc. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class FutureActivity extends Activity { - private FutureActivityTask<?> mTask; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Log.v("FutureActivity created."); - int id = getIntent().getIntExtra(Constants.EXTRA_TASK_ID, 0); - if (id == 0) { - throw new RuntimeException("FutureActivityTask ID is not specified."); - } - FutureActivityTaskExecutor taskQueue = ((BaseApplication) getApplication()).getTaskExecutor(); - mTask = taskQueue.getTask(id); - if (mTask == null) { // TODO: (Robbie) This is now less of a kludge. Would still like to know - // what is happening. - Log.w("FutureActivity has no task!"); - try { - Intent intent = new Intent(Intent.ACTION_MAIN); // Should default to main of current app. - intent.addCategory(Intent.CATEGORY_LAUNCHER); - String packageName = getPackageName(); - for (ResolveInfo resolve : getPackageManager().queryIntentActivities(intent, 0)) { - if (resolve.activityInfo.packageName.equals(packageName)) { - intent.setClassName(packageName, resolve.activityInfo.name); - break; - } - } - startActivity(intent); - } catch (Exception e) { - Log.e("Can't find main activity."); - } - } else { - mTask.setActivity(this); - mTask.onCreate(); - } - } - - @Override - protected void onStart() { - super.onStart(); - if (mTask != null) { - mTask.onStart(); - } - } - - @Override - protected void onResume() { - super.onResume(); - if (mTask != null) { - mTask.onResume(); - } - } - - @Override - protected void onPause() { - super.onPause(); - if (mTask != null) { - mTask.onPause(); - } - } - - @Override - protected void onStop() { - super.onStop(); - if (mTask != null) { - mTask.onStop(); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - if (mTask != null) { - mTask.onDestroy(); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - if (mTask != null) { - mTask.onCreateContextMenu(menu, v, menuInfo); - } - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - if (mTask == null) { - return false; - } else { - return mTask.onPrepareOptionsMenu(menu); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (mTask != null) { - mTask.onActivityResult(requestCode, resultCode, data); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mTask != null) { - return mTask.onKeyDown(keyCode, event); - } - return false; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/event/Event.java b/sl4a/Common/src/com/googlecode/android_scripting/event/Event.java deleted file mode 100644 index 3c0baf4..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/event/Event.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.event; - -import com.google.common.base.Preconditions; - -public class Event { - - private String mName; - private Object mData; - private double mCreationTime; - - public Event(String name, Object data) { - Preconditions.checkNotNull(name); - setName(name); - setData(data); - mCreationTime = System.currentTimeMillis(); - } - - public void setName(String name) { - mName = name; - } - - public String getName() { - return mName; - } - - public void setData(Object data) { - mData = data; - } - - public Object getData() { - return mData; - } - - public double getCreationTime() { - return mCreationTime; - } - - public boolean nameEquals(String name) { - return mName.equals(name); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/event/EventObserver.java b/sl4a/Common/src/com/googlecode/android_scripting/event/EventObserver.java deleted file mode 100644 index 6f4066e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/event/EventObserver.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.event; - - -public interface EventObserver { - public void onEventReceived(Event event); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/event/EventServer.java b/sl4a/Common/src/com/googlecode/android_scripting/event/EventServer.java deleted file mode 100644 index 325c740..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/event/EventServer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.event; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SimpleServer; -import com.googlecode.android_scripting.jsonrpc.JsonBuilder; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.Vector; -import java.util.concurrent.CountDownLatch; - -import org.json.JSONException; - -/** - * An Event Forwarding server that forwards events from the rpc queue in realtime to listener - * clients. - * - */ -public class EventServer extends SimpleServer implements EventObserver { - private static final Vector<Listener> mListeners = new Vector<Listener>(); - private InetSocketAddress address = null; - - public EventServer() { - this(0); - } - - public EventServer(int port) { - address = startAllInterfaces(port); - } - - public InetSocketAddress getAddress() { - return address; - } - - @Override - public void shutdown() { - onEventReceived(new Event("sl4a", "{\"shutdown\": \"event-server\"}")); - for (Listener listener : mListeners) { - mListeners.remove(listener); - listener.lock.countDown(); - } - super.shutdown(); - } - - @Override - protected void handleConnection(Socket socket) throws IOException { - Log.d("handle event connection."); - Listener l = new Listener(socket); - Log.v("Adding EventServer listener " + socket.getPort()); - mListeners.add(l); - // we are running in the socket accept thread - // wait until the event dispatcher gets us the events - // or we die, what ever happens first - try { - l.lock.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - try { - l.sock.close(); - } catch (IOException e) { - e.printStackTrace(); - } - Log.v("Ending EventServer listener " + socket.getPort()); - } - - @Override - public void onEventReceived(Event event) { - Object result = null; - try { - result = JsonBuilder.build(event); - } catch (JSONException e) { - return; - } - - Log.v("EventServer dispatching " + result); - - for (Listener listener : mListeners) { - if (!listener.out.checkError()) { - listener.out.write(result + "\n"); - listener.out.flush(); - } else { - // let the socket accept thread we're done - mListeners.remove(listener); - listener.lock.countDown(); - } - } - } - - private class Listener { - private Socket sock; - private PrintWriter out; - private CountDownLatch lock = new CountDownLatch(1); - - public Listener(Socket l) throws IOException { - sock = l; - out = new PrintWriter(l.getOutputStream(), true); - } - } - - @Override - protected void handleRPCConnection(Socket sock, Integer UID, BufferedReader reader, PrintWriter writer) - throws Exception { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ActivityResultFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ActivityResultFacade.java deleted file mode 100644 index a90fba4..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ActivityResultFacade.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Activity; -import android.content.Intent; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.Serializable; - -/** - * Allows you to return results to a startActivityForResult call. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class ActivityResultFacade extends RpcReceiver { - - private static final String sRpcDescription = - "Sets the result of a script execution. Whenever the script APK is called via " - + "startActivityForResult(), the resulting intent will contain " + Constants.EXTRA_RESULT - + " extra with the given value."; - private static final String sCodeDescription = - "The result code to propagate back to the originating activity, often RESULT_CANCELED (0) " - + "or RESULT_OK (-1)"; - - private Activity mActivity = null; - private Intent mResult = null; - private int mResultCode; - - public ActivityResultFacade(FacadeManager manager) { - super(manager); - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultBoolean( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Boolean resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.booleanValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultByte( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Byte resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.byteValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultShort( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Short resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.shortValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultChar( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Character resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.charValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultInteger( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Integer resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.intValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultLong( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Long resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.longValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultFloat( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Float resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.floatValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultDouble( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Double resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue.doubleValue()); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultString( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") String resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultBooleanArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Boolean[] resultValue) { - mResult = new Intent(); - boolean[] array = new boolean[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultByteArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Byte[] resultValue) { - mResult = new Intent(); - byte[] array = new byte[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultShortArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Short[] resultValue) { - mResult = new Intent(); - short[] array = new short[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultCharArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Character[] resultValue) { - mResult = new Intent(); - char[] array = new char[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultIntegerArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Integer[] resultValue) { - mResult = new Intent(); - int[] array = new int[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultLongArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Long[] resultValue) { - mResult = new Intent(); - long[] array = new long[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultFloatArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Float[] resultValue) { - mResult = new Intent(); - float[] array = new float[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultDoubleArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Double[] resultValue) { - mResult = new Intent(); - double[] array = new double[resultValue.length]; - for (int i = 0; i < resultValue.length; i++) { - array[i] = resultValue[i]; - } - mResult.putExtra(Constants.EXTRA_RESULT, array); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultStringArray( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") String[] resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - @Rpc(description = sRpcDescription) - public synchronized void setResultSerializable( - @RpcParameter(name = "resultCode", description = sCodeDescription) Integer resultCode, - @RpcParameter(name = "resultValue") Serializable resultValue) { - mResult = new Intent(); - mResult.putExtra(Constants.EXTRA_RESULT, resultValue); - mResultCode = resultCode; - if (mActivity != null) { - setResult(); - } - } - - public synchronized void setActivity(Activity activity) { - mActivity = activity; - if (mResult != null) { - setResult(); - } - } - - private void setResult() { - mActivity.setResult(mResultCode, mResult); - mActivity.finish(); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java deleted file mode 100644 index 1de3055..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/AndroidFacade.java +++ /dev/null @@ -1,1037 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.ClipData; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.StatFs; -import android.os.Vibrator; -import android.content.ClipboardManager; -import android.text.InputType; -import android.text.method.PasswordTransformationMethod; -import android.widget.EditText; -import android.widget.Toast; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.NotificationIdFactory; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.TimeUnit; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Some general purpose Android routines.<br> - * <h2>Intents</h2> Intents are returned as a map, in the following form:<br> - * <ul> - * <li><b>action</b> - action. - * <li><b>data</b> - url - * <li><b>type</b> - mime type - * <li><b>packagename</b> - name of package. If used, requires classname to be useful (optional) - * <li><b>classname</b> - name of class. If used, requires packagename to be useful (optional) - * <li><b>categories</b> - list of categories - * <li><b>extras</b> - map of extras - * <li><b>flags</b> - integer flags. - * </ul> - * <br> - * An intent can be built using the {@see #makeIntent} call, but can also be constructed exterally. - * - */ -public class AndroidFacade extends RpcReceiver { - /** - * An instance of this interface is passed to the facade. From this object, the resource IDs can - * be obtained. - */ - - public interface Resources { - int getLogo48(); - } - - private final Service mService; - private final Handler mHandler; - private final Intent mIntent; - private final FutureActivityTaskExecutor mTaskQueue; - - private final Vibrator mVibrator; - private final NotificationManager mNotificationManager; - - private final Resources mResources; - private ClipboardManager mClipboard = null; - - @Override - public void shutdown() { - } - - public AndroidFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mIntent = manager.getIntent(); - BaseApplication application = ((BaseApplication) mService.getApplication()); - mTaskQueue = application.getTaskExecutor(); - mHandler = new Handler(mService.getMainLooper()); - mVibrator = (Vibrator) mService.getSystemService(Context.VIBRATOR_SERVICE); - mNotificationManager = - (NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE); - mResources = manager.getAndroidFacadeResources(); - } - - ClipboardManager getClipboardManager() { - Object clipboard = null; - if (mClipboard == null) { - try { - clipboard = mService.getSystemService(Context.CLIPBOARD_SERVICE); - } catch (Exception e) { - Looper.prepare(); // Clipboard manager won't work without this on higher SDK levels... - clipboard = mService.getSystemService(Context.CLIPBOARD_SERVICE); - } - mClipboard = (ClipboardManager) clipboard; - if (mClipboard == null) { - Log.w("Clipboard managed not accessible."); - } - } - return mClipboard; - } - - public Intent startActivityForResult(final Intent intent) { - FutureActivityTask<Intent> task = new FutureActivityTask<Intent>() { - @Override - public void onCreate() { - super.onCreate(); - try { - startActivityForResult(intent, 0); - } catch (Exception e) { - intent.putExtra("EXCEPTION", e.getMessage()); - setResult(intent); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - setResult(data); - } - }; - mTaskQueue.execute(task); - - try { - return task.getResult(); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - task.finish(); - } - } - - public int startActivityForResultCodeWithTimeout(final Intent intent, - final int request, final int timeout) { - FutureActivityTask<Integer> task = new FutureActivityTask<Integer>() { - @Override - public void onCreate() { - super.onCreate(); - try { - startActivityForResult(intent, request); - } catch (Exception e) { - intent.putExtra("EXCEPTION", e.getMessage()); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (request == requestCode){ - setResult(resultCode); - } - } - }; - mTaskQueue.execute(task); - - try { - return task.getResult(timeout, TimeUnit.SECONDS); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - task.finish(); - } - } - - // TODO(damonkohler): Pull this out into proper argument deserialization and support - // complex/nested types being passed in. - public static void putExtrasFromJsonObject(JSONObject extras, - Intent intent) throws JSONException { - JSONArray names = extras.names(); - for (int i = 0; i < names.length(); i++) { - String name = names.getString(i); - Object data = extras.get(name); - if (data == null) { - continue; - } - if (data instanceof Integer) { - intent.putExtra(name, (Integer) data); - } - if (data instanceof Float) { - intent.putExtra(name, (Float) data); - } - if (data instanceof Double) { - intent.putExtra(name, (Double) data); - } - if (data instanceof Long) { - intent.putExtra(name, (Long) data); - } - if (data instanceof String) { - intent.putExtra(name, (String) data); - } - if (data instanceof Boolean) { - intent.putExtra(name, (Boolean) data); - } - // Nested JSONObject - if (data instanceof JSONObject) { - Bundle nestedBundle = new Bundle(); - intent.putExtra(name, nestedBundle); - putNestedJSONObject((JSONObject) data, nestedBundle); - } - // Nested JSONArray. Doesn't support mixed types in single array - if (data instanceof JSONArray) { - // Empty array. No way to tell what type of data to pass on, so skipping - if (((JSONArray) data).length() == 0) { - Log.e("Empty array not supported in JSONObject, skipping"); - continue; - } - // Integer - if (((JSONArray) data).get(0) instanceof Integer) { - Integer[] integerArrayData = new Integer[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - integerArrayData[j] = ((JSONArray) data).getInt(j); - } - intent.putExtra(name, integerArrayData); - } - // Double - if (((JSONArray) data).get(0) instanceof Double) { - Double[] doubleArrayData = new Double[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - doubleArrayData[j] = ((JSONArray) data).getDouble(j); - } - intent.putExtra(name, doubleArrayData); - } - // Long - if (((JSONArray) data).get(0) instanceof Long) { - Long[] longArrayData = new Long[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - longArrayData[j] = ((JSONArray) data).getLong(j); - } - intent.putExtra(name, longArrayData); - } - // String - if (((JSONArray) data).get(0) instanceof String) { - String[] stringArrayData = new String[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - stringArrayData[j] = ((JSONArray) data).getString(j); - } - intent.putExtra(name, stringArrayData); - } - // Boolean - if (((JSONArray) data).get(0) instanceof Boolean) { - Boolean[] booleanArrayData = new Boolean[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - booleanArrayData[j] = ((JSONArray) data).getBoolean(j); - } - intent.putExtra(name, booleanArrayData); - } - } - } - } - - // Contributed by Emmanuel T - // Nested Array handling contributed by Sergey Zelenev - private static void putNestedJSONObject(JSONObject jsonObject, Bundle bundle) - throws JSONException { - JSONArray names = jsonObject.names(); - for (int i = 0; i < names.length(); i++) { - String name = names.getString(i); - Object data = jsonObject.get(name); - if (data == null) { - continue; - } - if (data instanceof Integer) { - bundle.putInt(name, ((Integer) data).intValue()); - } - if (data instanceof Float) { - bundle.putFloat(name, ((Float) data).floatValue()); - } - if (data instanceof Double) { - bundle.putDouble(name, ((Double) data).doubleValue()); - } - if (data instanceof Long) { - bundle.putLong(name, ((Long) data).longValue()); - } - if (data instanceof String) { - bundle.putString(name, (String) data); - } - if (data instanceof Boolean) { - bundle.putBoolean(name, ((Boolean) data).booleanValue()); - } - // Nested JSONObject - if (data instanceof JSONObject) { - Bundle nestedBundle = new Bundle(); - bundle.putBundle(name, nestedBundle); - putNestedJSONObject((JSONObject) data, nestedBundle); - } - // Nested JSONArray. Doesn't support mixed types in single array - if (data instanceof JSONArray) { - // Empty array. No way to tell what type of data to pass on, so skipping - if (((JSONArray) data).length() == 0) { - Log.e("Empty array not supported in nested JSONObject, skipping"); - continue; - } - // Integer - if (((JSONArray) data).get(0) instanceof Integer) { - int[] integerArrayData = new int[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - integerArrayData[j] = ((JSONArray) data).getInt(j); - } - bundle.putIntArray(name, integerArrayData); - } - // Double - if (((JSONArray) data).get(0) instanceof Double) { - double[] doubleArrayData = new double[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - doubleArrayData[j] = ((JSONArray) data).getDouble(j); - } - bundle.putDoubleArray(name, doubleArrayData); - } - // Long - if (((JSONArray) data).get(0) instanceof Long) { - long[] longArrayData = new long[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - longArrayData[j] = ((JSONArray) data).getLong(j); - } - bundle.putLongArray(name, longArrayData); - } - // String - if (((JSONArray) data).get(0) instanceof String) { - String[] stringArrayData = new String[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - stringArrayData[j] = ((JSONArray) data).getString(j); - } - bundle.putStringArray(name, stringArrayData); - } - // Boolean - if (((JSONArray) data).get(0) instanceof Boolean) { - boolean[] booleanArrayData = new boolean[((JSONArray) data).length()]; - for (int j = 0; j < ((JSONArray) data).length(); ++j) { - booleanArrayData[j] = ((JSONArray) data).getBoolean(j); - } - bundle.putBooleanArray(name, booleanArrayData); - } - } - } - } - - void startActivity(final Intent intent) { - try { - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mService.startActivity(intent); - } catch (Exception e) { - Log.e("Failed to launch intent.", e); - } - } - - private Intent buildIntent(String action, String uri, String type, JSONObject extras, - String packagename, String classname, JSONArray categories) throws JSONException { - Intent intent = new Intent(); - if (action != null) { - intent.setAction(action); - } - intent.setDataAndType(uri != null ? Uri.parse(uri) : null, type); - if (packagename != null && classname != null) { - intent.setComponent(new ComponentName(packagename, classname)); - } - if (extras != null) { - putExtrasFromJsonObject(extras, intent); - } - if (categories != null) { - for (int i = 0; i < categories.length(); i++) { - intent.addCategory(categories.getString(i)); - } - } - return intent; - } - - // TODO(damonkohler): It's unnecessary to add the complication of choosing between startActivity - // and startActivityForResult. It's probably better to just always use the ForResult version. - // However, this makes the call always blocking. We'd need to add an extra boolean parameter to - // indicate if we should wait for a result. - @Rpc(description = "Starts an activity and returns the result.", - returns = "A Map representation of the result Intent.") - public Intent startActivityForResult( - @RpcParameter(name = "action") - String action, - @RpcParameter(name = "uri") - @RpcOptional String uri, - @RpcParameter(name = "type", description = "MIME type/subtype of the URI") - @RpcOptional String type, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") - @RpcOptional JSONObject extras, - @RpcParameter(name = "packagename", - description = "name of package. If used, requires classname to be useful") - @RpcOptional String packagename, - @RpcParameter(name = "classname", - description = "name of class. If used, requires packagename to be useful") - @RpcOptional String classname - ) throws JSONException { - final Intent intent = buildIntent(action, uri, type, extras, packagename, classname, null); - return startActivityForResult(intent); - } - - @Rpc(description = "Starts an activity and returns the result.", - returns = "A Map representation of the result Intent.") - public Intent startActivityForResultIntent( - @RpcParameter(name = "intent", - description = "Intent in the format as returned from makeIntent") - Intent intent) { - return startActivityForResult(intent); - } - - private void doStartActivity(final Intent intent, Boolean wait) throws Exception { - if (wait == null || wait == false) { - startActivity(intent); - } else { - FutureActivityTask<Intent> task = new FutureActivityTask<Intent>() { - private boolean mSecondResume = false; - - @Override - public void onCreate() { - super.onCreate(); - startActivity(intent); - } - - @Override - public void onResume() { - if (mSecondResume) { - finish(); - } - mSecondResume = true; - } - - @Override - public void onDestroy() { - setResult(null); - } - - }; - mTaskQueue.execute(task); - - try { - task.getResult(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - /** - * Creates a new AndroidFacade that simplifies the interface to various Android APIs. - * - * @param service - * is the {@link Context} the APIs will run under - */ - - @Rpc(description = "Put a text string in the clipboard.") - public void setTextClip(@RpcParameter(name = "text") - String text, - @RpcParameter(name = "label") - @RpcOptional @RpcDefault(value = "copiedText") - String label) { - getClipboardManager().setPrimaryClip(ClipData.newPlainText(label, text)); - } - - @Rpc(description = "Get the device serial number.") - public String getBuildSerial() { - return Build.SERIAL; - } - - @Rpc(description = "Get the name of system bootloader version number.") - public String getBuildBootloader() { - return android.os.Build.BOOTLOADER; - } - - @Rpc(description = "Get the name of the industrial design.") - public String getBuildIndustrialDesignName() { - return Build.DEVICE; - } - - @Rpc(description = "Get the build ID string meant for displaying to the user") - public String getBuildDisplay() { - return Build.DISPLAY; - } - - @Rpc(description = "Get the string that uniquely identifies this build.") - public String getBuildFingerprint() { - return Build.FINGERPRINT; - } - - @Rpc(description = "Get the name of the hardware (from the kernel command " - + "line or /proc)..") - public String getBuildHardware() { - return Build.HARDWARE; - } - - @Rpc(description = "Get the device host.") - public String getBuildHost() { - return Build.HOST; - } - - @Rpc(description = "Get Either a changelist number, or a label like." - + " \"M4-rc20\".") - public String getBuildID() { - return android.os.Build.ID; - } - - @Rpc(description = "Returns true if we are running a debug build such" - + " as \"user-debug\" or \"eng\".") - public boolean getBuildIsDebuggable() { - return Build.IS_DEBUGGABLE; - } - - @Rpc(description = "Get the name of the overall product.") - public String getBuildProduct() { - return android.os.Build.PRODUCT; - } - - @Rpc(description = "Get an ordered list of 32 bit ABIs supported by this " - + "device. The most preferred ABI is the first element in the list") - public String[] getBuildSupported32BitAbis() { - return Build.SUPPORTED_32_BIT_ABIS; - } - - @Rpc(description = "Get an ordered list of 64 bit ABIs supported by this " - + "device. The most preferred ABI is the first element in the list") - public String[] getBuildSupported64BitAbis() { - return Build.SUPPORTED_64_BIT_ABIS; - } - - @Rpc(description = "Get an ordered list of ABIs supported by this " - + "device. The most preferred ABI is the first element in the list") - public String[] getBuildSupportedBitAbis() { - return Build.SUPPORTED_ABIS; - } - - @Rpc(description = "Get comma-separated tags describing the build," - + " like \"unsigned,debug\".") - public String getBuildTags() { - return Build.TAGS; - } - - @Rpc(description = "Get The type of build, like \"user\" or \"eng\".") - public String getBuildType() { - return Build.TYPE; - } - @Rpc(description = "Returns the board name.") - public String getBuildBoard() { - return Build.BOARD; - } - - @Rpc(description = "Returns the brand name.") - public String getBuildBrand() { - return Build.BRAND; - } - - @Rpc(description = "Returns the manufacturer name.") - public String getBuildManufacturer() { - return Build.MANUFACTURER; - } - - @Rpc(description = "Returns the model name.") - public String getBuildModel() { - return Build.MODEL; - } - - @Rpc(description = "Returns the build number.") - public String getBuildNumber() { - return Build.FINGERPRINT; - } - - @Rpc(description = "Returns the SDK version.") - public Integer getBuildSdkVersion() { - return Build.VERSION.SDK_INT; - } - - @Rpc(description = "Returns the current device time.") - public Long getBuildTime() { - return Build.TIME; - } - - @Rpc(description = "Read all text strings copied by setTextClip from the clipboard.") - public List<String> getTextClip() { - ClipboardManager cm = getClipboardManager(); - ArrayList<String> texts = new ArrayList<String>(); - if(!cm.hasPrimaryClip()) { - return texts; - } - ClipData cd = cm.getPrimaryClip(); - for(int i=0; i<cd.getItemCount(); i++) { - texts.add(cd.getItemAt(i).coerceToText(mService).toString()); - } - return texts; - } - - /** - * packagename and classname, if provided, are used in a 'setComponent' call. - */ - @Rpc(description = "Starts an activity.") - public void startActivity( - @RpcParameter(name = "action") - String action, - @RpcParameter(name = "uri") - @RpcOptional String uri, - @RpcParameter(name = "type", description = "MIME type/subtype of the URI") - @RpcOptional String type, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") - @RpcOptional JSONObject extras, - @RpcParameter(name = "wait", description = "block until the user exits the started activity") - @RpcOptional Boolean wait, - @RpcParameter(name = "packagename", - description = "name of package. If used, requires classname to be useful") - @RpcOptional String packagename, - @RpcParameter(name = "classname", - description = "name of class. If used, requires packagename to be useful") - @RpcOptional String classname - ) throws Exception { - final Intent intent = buildIntent(action, uri, type, extras, packagename, classname, null); - doStartActivity(intent, wait); - } - - @Rpc(description = "Send a broadcast.") - public void sendBroadcast( - @RpcParameter(name = "action") - String action, - @RpcParameter(name = "uri") - @RpcOptional String uri, - @RpcParameter(name = "type", description = "MIME type/subtype of the URI") - @RpcOptional String type, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") - @RpcOptional JSONObject extras, - @RpcParameter(name = "packagename", - description = "name of package. If used, requires classname to be useful") - @RpcOptional String packagename, - @RpcParameter(name = "classname", - description = "name of class. If used, requires packagename to be useful") - @RpcOptional String classname - ) throws JSONException { - final Intent intent = buildIntent(action, uri, type, extras, packagename, classname, null); - try { - mService.sendBroadcast(intent); - } catch (Exception e) { - Log.e("Failed to broadcast intent.", e); - } - } - - @Rpc(description = "Starts a service.") - public void startService( - @RpcParameter(name = "uri") - @RpcOptional String uri, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") - @RpcOptional JSONObject extras, - @RpcParameter(name = "packagename", - description = "name of package. If used, requires classname to be useful") - @RpcOptional String packagename, - @RpcParameter(name = "classname", - description = "name of class. If used, requires packagename to be useful") - @RpcOptional String classname - ) throws Exception { - final Intent intent = buildIntent(null /* action */, uri, null /* type */, extras, packagename, - classname, null /* categories */); - mService.startService(intent); - } - - @Rpc(description = "Create an Intent.", returns = "An object representing an Intent") - public Intent makeIntent( - @RpcParameter(name = "action") - String action, - @RpcParameter(name = "uri") - @RpcOptional String uri, - @RpcParameter(name = "type", description = "MIME type/subtype of the URI") - @RpcOptional String type, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") - @RpcOptional JSONObject extras, - @RpcParameter(name = "categories", description = "a List of categories to add to the Intent") - @RpcOptional JSONArray categories, - @RpcParameter(name = "packagename", - description = "name of package. If used, requires classname to be useful") - @RpcOptional String packagename, - @RpcParameter(name = "classname", - description = "name of class. If used, requires packagename to be useful") - @RpcOptional String classname, - @RpcParameter(name = "flags", description = "Intent flags") - @RpcOptional Integer flags - ) throws JSONException { - Intent intent = buildIntent(action, uri, type, extras, packagename, classname, categories); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (flags != null) { - intent.setFlags(flags); - } - return intent; - } - - @Rpc(description = "Start Activity using Intent") - public void startActivityIntent( - @RpcParameter(name = "intent", - description = "Intent in the format as returned from makeIntent") - Intent intent, - @RpcParameter(name = "wait", - description = "block until the user exits the started activity") - @RpcOptional Boolean wait - ) throws Exception { - doStartActivity(intent, wait); - } - - @Rpc(description = "Send Broadcast Intent") - public void sendBroadcastIntent( - @RpcParameter(name = "intent", - description = "Intent in the format as returned from makeIntent") - Intent intent - ) throws Exception { - mService.sendBroadcast(intent); - } - - @Rpc(description = "Start Service using Intent") - public void startServiceIntent( - @RpcParameter(name = "intent", - description = "Intent in the format as returned from makeIntent") - Intent intent - ) throws Exception { - mService.startService(intent); - } - - @Rpc(description = "Vibrates the phone or a specified duration in milliseconds.") - public void vibrate( - @RpcParameter(name = "duration", description = "duration in milliseconds") - @RpcDefault("300") - Integer duration) { - mVibrator.vibrate(duration); - } - - @Rpc(description = "Displays a short-duration Toast notification.") - public void makeToast(@RpcParameter(name = "message") final String message) { - mHandler.post(new Runnable() { - public void run() { - Toast.makeText(mService, message, Toast.LENGTH_SHORT).show(); - } - }); - } - - private String getInputFromAlertDialog(final String title, final String message, - final boolean password) { - final FutureActivityTask<String> task = new FutureActivityTask<String>() { - @Override - public void onCreate() { - super.onCreate(); - final EditText input = new EditText(getActivity()); - if (password) { - input.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); - input.setTransformationMethod(new PasswordTransformationMethod()); - } - AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); - alert.setTitle(title); - alert.setMessage(message); - alert.setView(input); - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - dialog.dismiss(); - setResult(input.getText().toString()); - finish(); - } - }); - alert.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - dialog.dismiss(); - setResult(null); - finish(); - } - }); - alert.show(); - } - }; - mTaskQueue.execute(task); - - try { - return task.getResult(); - } catch (Exception e) { - Log.e("Failed to display dialog.", e); - throw new RuntimeException(e); - } - } - - @Rpc(description = "Queries the user for a text input.") - @RpcDeprecated(value = "dialogGetInput", release = "r3") - public String getInput( - @RpcParameter(name = "title", description = "title of the input box") - @RpcDefault("SL4A Input") - final String title, - @RpcParameter(name = "message", description = "message to display above the input box") - @RpcDefault("Please enter value:") - final String message) { - return getInputFromAlertDialog(title, message, false); - } - - @Rpc(description = "Queries the user for a password.") - @RpcDeprecated(value = "dialogGetPassword", release = "r3") - public String getPassword( - @RpcParameter(name = "title", description = "title of the input box") - @RpcDefault("SL4A Password Input") - final String title, - @RpcParameter(name = "message", description = "message to display above the input box") - @RpcDefault("Please enter password:") - final String message) { - return getInputFromAlertDialog(title, message, true); - } - - @Rpc(description = "Displays a notification that will be canceled when the user clicks on it.") - public void notify(@RpcParameter(name = "title", description = "title") String title, - @RpcParameter(name = "message") String message) { - // This contentIntent is a noop. - PendingIntent contentIntent = PendingIntent.getService(mService, 0, new Intent(), 0); - Notification.Builder builder = new Notification.Builder(mService); - builder.setSmallIcon(mResources.getLogo48()) - .setTicker(message) - .setWhen(System.currentTimeMillis()) - .setContentTitle(title) - .setContentText(message) - .setContentIntent(contentIntent); - Notification notification = builder.build(); - notification.flags = Notification.FLAG_AUTO_CANCEL; - // Get a unique notification id from the application. - final int notificationId = NotificationIdFactory.create(); - mNotificationManager.notify(notificationId, notification); - } - - @Rpc(description = "Returns the intent that launched the script.") - public Object getIntent() { - return mIntent; - } - - @Rpc(description = "Launches an activity that sends an e-mail message to a given recipient.") - public void sendEmail( - @RpcParameter(name = "to", description = "A comma separated list of recipients.") - final String to, - @RpcParameter(name = "subject") final String subject, - @RpcParameter(name = "body") final String body, - @RpcParameter(name = "attachmentUri") - @RpcOptional final String attachmentUri) { - final Intent intent = new Intent(android.content.Intent.ACTION_SEND); - intent.setType("plain/text"); - intent.putExtra(android.content.Intent.EXTRA_EMAIL, to.split(",")); - intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject); - intent.putExtra(android.content.Intent.EXTRA_TEXT, body); - if (attachmentUri != null) { - intent.putExtra(android.content.Intent.EXTRA_STREAM, Uri.parse(attachmentUri)); - } - startActivity(intent); - } - - @Rpc(description = "Returns package version code.") - public int getPackageVersionCode(@RpcParameter(name = "packageName") final String packageName) { - int result = -1; - PackageInfo pInfo = null; - try { - pInfo = - mService.getPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA); - } catch (NameNotFoundException e) { - pInfo = null; - } - if (pInfo != null) { - result = pInfo.versionCode; - } - return result; - } - - @Rpc(description = "Returns package version name.") - public String getPackageVersion(@RpcParameter(name = "packageName") final String packageName) { - PackageInfo packageInfo = null; - try { - packageInfo = - mService.getPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA); - } catch (NameNotFoundException e) { - return null; - } - if (packageInfo != null) { - return packageInfo.versionName; - } - return null; - } - - @Rpc(description = "Checks if SL4A's version is >= the specified version.") - public boolean requiredVersion( - @RpcParameter(name = "requiredVersion") final Integer version) { - boolean result = false; - int packageVersion = getPackageVersionCode( - "com.googlecode.android_scripting"); - if (version > -1) { - result = (packageVersion >= version); - } - return result; - } - - @Rpc(description = "Writes message to logcat at verbose level") - public void logV( - @RpcParameter(name = "message") - String message) { - android.util.Log.v("SL4A: ", message); - } - - @Rpc(description = "Writes message to logcat at info level") - public void logI( - @RpcParameter(name = "message") - String message) { - android.util.Log.i("SL4A: ", message); - } - - @Rpc(description = "Writes message to logcat at debug level") - public void logD( - @RpcParameter(name = "message") - String message) { - android.util.Log.d("SL4A: ", message); - } - - @Rpc(description = "Writes message to logcat at warning level") - public void logW( - @RpcParameter(name = "message") - String message) { - android.util.Log.w("SL4A: ", message); - } - - @Rpc(description = "Writes message to logcat at error level") - public void logE( - @RpcParameter(name = "message") - String message) { - android.util.Log.e("SL4A: ", message); - } - - @Rpc(description = "Writes message to logcat at wtf level") - public void logWTF( - @RpcParameter(name = "message") - String message) { - android.util.Log.wtf("SL4A: ", message); - } - - /** - * - * Map returned: - * - * <pre> - * TZ = Timezone - * id = Timezone ID - * display = Timezone display name - * offset = Offset from UTC (in ms) - * SDK = SDK Version - * download = default download path - * appcache = Location of application cache - * sdcard = Space on sdcard - * availblocks = Available blocks - * blockcount = Total Blocks - * blocksize = size of block. - * </pre> - */ - @Rpc(description = "A map of various useful environment details") - public Map<String, Object> environment() { - Map<String, Object> result = new HashMap<String, Object>(); - Map<String, Object> zone = new HashMap<String, Object>(); - Map<String, Object> space = new HashMap<String, Object>(); - TimeZone tz = TimeZone.getDefault(); - zone.put("id", tz.getID()); - zone.put("display", tz.getDisplayName()); - zone.put("offset", tz.getOffset((new Date()).getTime())); - result.put("TZ", zone); - result.put("SDK", android.os.Build.VERSION.SDK_INT); - result.put("download", FileUtils.getExternalDownload().getAbsolutePath()); - result.put("appcache", mService.getCacheDir().getAbsolutePath()); - try { - StatFs fs = new StatFs("/sdcard"); - space.put("availblocks", fs.getAvailableBlocksLong()); - space.put("blocksize", fs.getBlockSizeLong()); - space.put("blockcount", fs.getBlockCountLong()); - } catch (Exception e) { - space.put("exception", e.toString()); - } - result.put("sdcard", space); - return result; - } - - @Rpc(description = "Get list of constants (static final fields) for a class") - public Bundle getConstants( - @RpcParameter(name = "classname", description = "Class to get constants from") - String classname) - throws Exception { - Bundle result = new Bundle(); - int flags = Modifier.FINAL | Modifier.PUBLIC | Modifier.STATIC; - Class<?> clazz = Class.forName(classname); - for (Field field : clazz.getFields()) { - if ((field.getModifiers() & flags) == flags) { - Class<?> type = field.getType(); - String name = field.getName(); - if (type == int.class) { - result.putInt(name, field.getInt(null)); - } else if (type == long.class) { - result.putLong(name, field.getLong(null)); - } else if (type == double.class) { - result.putDouble(name, field.getDouble(null)); - } else if (type == char.class) { - result.putChar(name, field.getChar(null)); - } else if (type instanceof Object) { - result.putString(name, field.get(null).toString()); - } - } - } - return result; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ApplicationManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ApplicationManagerFacade.java deleted file mode 100644 index 69ed5ad..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ApplicationManagerFacade.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Facade for managing Applications. - * - */ -public class ApplicationManagerFacade extends RpcReceiver { - - private final Service mService; - private final AndroidFacade mAndroidFacade; - private final ActivityManager mActivityManager; - private final PackageManager mPackageManager; - - public ApplicationManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - mActivityManager = (ActivityManager) mService.getSystemService(Context.ACTIVITY_SERVICE); - mPackageManager = mService.getPackageManager(); - } - - @Rpc(description = "Returns a list of all launchable application class names.") - public Map<String, String> getLaunchableApplications() { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - List<ResolveInfo> resolveInfos = mPackageManager.queryIntentActivities(intent, 0); - Map<String, String> applications = new HashMap<String, String>(); - for (ResolveInfo info : resolveInfos) { - applications.put(info.loadLabel(mPackageManager).toString(), info.activityInfo.name); - } - return applications; - } - - @Rpc(description = "Start activity with the given class name.") - public void launch(@RpcParameter(name = "className") String className) { - Intent intent = new Intent(Intent.ACTION_MAIN); - String packageName = className.substring(0, className.lastIndexOf(".")); - intent.setClassName(packageName, className); - mAndroidFacade.startActivity(intent); - } - - @Rpc(description = "Launch the specified app.") - public void appLaunch(@RpcParameter(name = "name") String name) { - Intent LaunchIntent = mPackageManager.getLaunchIntentForPackage(name); - mService.startActivity(LaunchIntent); - } - - @Rpc(description = "Kill the specified app.") - public Boolean appKill(@RpcParameter(name = "name") String name) { - for (RunningAppProcessInfo info : mActivityManager.getRunningAppProcesses()) { - if (info.processName.contains(name)) { - Log.d("Killing " + info.processName); - android.os.Process.killProcess(info.pid); - android.os.Process.sendSignal(info.pid, android.os.Process.SIGNAL_KILL); - mActivityManager.killBackgroundProcesses(info.processName); - return true; - } - } - return false; - } - - @Rpc(description = "Returns a list of packages running activities or services.", returns = "List of packages running activities.") - public List<String> getRunningPackages() { - Set<String> runningPackages = new HashSet<String>(); - List<ActivityManager.RunningAppProcessInfo> appProcesses = - mActivityManager.getRunningAppProcesses(); - for (ActivityManager.RunningAppProcessInfo info : appProcesses) { - runningPackages.addAll(Arrays.asList(info.pkgList)); - } - List<ActivityManager.RunningServiceInfo> serviceProcesses = - mActivityManager.getRunningServices(Integer.MAX_VALUE); - for (ActivityManager.RunningServiceInfo info : serviceProcesses) { - runningPackages.add(info.service.getPackageName()); - } - return new ArrayList<String>(runningPackages); - } - - @Rpc(description = "Force stops a package.") - public void forceStopPackage( - @RpcParameter(name = "packageName", description = "name of package") String packageName) { - mActivityManager.restartPackage(packageName); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/BatteryManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/BatteryManagerFacade.java deleted file mode 100644 index 5d0b34e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/BatteryManagerFacade.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.BatteryManager; -import android.os.Bundle; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcStartEvent; -import com.googlecode.android_scripting.rpc.RpcStopEvent; - -import java.lang.reflect.Field; - -/** - * Exposes Batterymanager API. Note that in order to use any of the batteryGet* functions, you need - * to batteryStartMonitoring, and then wait for a "battery" event. Sleeping for a second will - * usually work just as well. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - * @author Robbie Matthews (rjmatthews62@gmail.com) - */ -public class BatteryManagerFacade extends RpcReceiver { - - private final Service mService; - private final EventFacade mEventFacade; - private final int mSdkVersion; - - private BatteryStateListener mReceiver; - - private volatile Bundle mBatteryData = null; - private volatile Integer mBatteryStatus = null; - private volatile Integer mBatteryHealth = null; - private volatile Integer mPlugType = null; - - private volatile Boolean mBatteryPresent = null; - private volatile Integer mBatteryLevel = null; - private volatile Integer mBatteryMaxLevel = null; - private volatile Integer mBatteryVoltage = null; - private volatile Integer mBatteryTemperature = null; - private volatile String mBatteryTechnology = null; - - public BatteryManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mSdkVersion = manager.getSdkLevel(); - mEventFacade = manager.getReceiver(EventFacade.class); - mReceiver = null; - mBatteryData = null; - } - - private class BatteryStateListener extends BroadcastReceiver { - - private final EventFacade mmEventFacade; - - private BatteryStateListener(EventFacade facade) { - mmEventFacade = facade; - } - - @Override - public void onReceive(Context context, Intent intent) { - mBatteryStatus = intent.getIntExtra("status", 1); - mBatteryHealth = intent.getIntExtra("health", 1); - mPlugType = intent.getIntExtra("plugged", -1); - if (mSdkVersion >= 5) { - mBatteryPresent = - intent.getBooleanExtra(getBatteryManagerFieldValue("EXTRA_PRESENT"), false); - mBatteryLevel = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_LEVEL"), -1); - mBatteryMaxLevel = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_SCALE"), 0); - mBatteryVoltage = intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_VOLTAGE"), -1); - mBatteryTemperature = - intent.getIntExtra(getBatteryManagerFieldValue("EXTRA_TEMPERATURE"), -1); - mBatteryTechnology = intent.getStringExtra(getBatteryManagerFieldValue("EXTRA_TECHNOLOGY")); - } - Bundle data = new Bundle(); - data.putInt("status", mBatteryStatus); - data.putInt("health", mBatteryHealth); - data.putInt("plugged", mPlugType); - if (mSdkVersion >= 5) { - data.putBoolean("battery_present", mBatteryPresent); - if (mBatteryMaxLevel == null || mBatteryMaxLevel == 100 || mBatteryMaxLevel == 0) { - data.putInt("level", mBatteryLevel); - } else { - data.putInt("level", (int) (mBatteryLevel * 100.0 / mBatteryMaxLevel)); - } - data.putInt("voltage", mBatteryVoltage); - data.putInt("temperature", mBatteryTemperature); - data.putString("technology", mBatteryTechnology); - } - mBatteryData = data; - mmEventFacade.postEvent("battery", mBatteryData.clone()); - } - } - - private String getBatteryManagerFieldValue(String name) { - try { - Field f = BatteryManager.class.getField(name); - return f.get(null).toString(); - } catch (Exception e) { - Log.e(e); - } - return null; - } - - @Rpc(description = "Returns the most recently recorded battery data.") - public Bundle readBatteryData() { - return mBatteryData; - } - - /** - * throws "battery" events - */ - @Rpc(description = "Starts tracking battery state.") - @RpcStartEvent("battery") - public void batteryStartMonitoring() { - if (mReceiver == null) { - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_BATTERY_CHANGED); - mReceiver = new BatteryStateListener(mEventFacade); - mService.registerReceiver(mReceiver, filter); - } - } - - @Rpc(description = "Stops tracking battery state.") - @RpcStopEvent("battery") - public void batteryStopMonitoring() { - if (mReceiver != null) { - mService.unregisterReceiver(mReceiver); - mReceiver = null; - } - mBatteryData = null; - } - - @Override - public void shutdown() { - batteryStopMonitoring(); - } - - @Rpc(description = "Returns the most recently received battery status data:" + "\n1 - unknown;" - + "\n2 - charging;" + "\n3 - discharging;" + "\n4 - not charging;" + "\n5 - full;") - public Integer batteryGetStatus() { - return mBatteryStatus; - } - - @Rpc(description = "Returns the most recently received battery health data:" + "\n1 - unknown;" - + "\n2 - good;" + "\n3 - overheat;" + "\n4 - dead;" + "\n5 - over voltage;" - + "\n6 - unspecified failure;") - public Integer batteryGetHealth() { - return mBatteryHealth; - } - - /** Power source is an AC charger. */ - public static final int BATTERY_PLUGGED_AC = 1; - /** Power source is a USB port. */ - public static final int BATTERY_PLUGGED_USB = 2; - - @Rpc(description = "Returns the most recently received plug type data:" + "\n-1 - unknown" - + "\n0 - unplugged;" + "\n1 - power source is an AC charger" - + "\n2 - power source is a USB port") - public Integer batteryGetPlugType() { - return mPlugType; - } - - @Rpc(description = "Returns the most recently received battery presence data.") - public Boolean batteryCheckPresent() { - return mBatteryPresent; - } - - @Rpc(description = "Returns the most recently received battery level (percentage).") - public Integer batteryGetLevel() { - if (mBatteryMaxLevel == null || mBatteryMaxLevel == 100 || mBatteryMaxLevel == 0) { - return mBatteryLevel; - } else { - return (int) (mBatteryLevel * 100.0 / mBatteryMaxLevel); - } - } - - @Rpc(description = "Returns the most recently received battery voltage.") - public Integer batteryGetVoltage() { - return mBatteryVoltage; - } - - @Rpc(description = "Returns the most recently received battery temperature.") - public Integer batteryGetTemperature() { - return mBatteryTemperature; - } - - @Rpc(description = "Returns the most recently received battery technology data.") - public String batteryGetTechnology() { - return mBatteryTechnology; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/CameraFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/CameraFacade.java deleted file mode 100644 index ff353f9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/CameraFacade.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.Intent; -import android.hardware.Camera; -import android.hardware.Camera.AutoFocusCallback; -import android.hardware.Camera.Parameters; -import android.hardware.Camera.PictureCallback; -import android.net.Uri; -import android.os.Bundle; -import android.provider.MediaStore; -import android.view.SurfaceHolder; -import android.view.SurfaceHolder.Callback; -import android.view.SurfaceView; -import android.view.WindowManager; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.concurrent.CountDownLatch; - -/** - * Access Camera functions. - * - */ -public class CameraFacade extends RpcReceiver { - - private final Service mService; - private final Parameters mParameters; - - private class BooleanResult { - boolean mmResult = false; - } - - public Camera openCamera(int cameraId) throws Exception { - int sSdkLevel = Integer.parseInt(android.os.Build.VERSION.SDK); - Camera result; - if (sSdkLevel < 9) { - result = Camera.open(); - } else { - Method openCamera = Camera.class.getMethod("open", int.class); - result = (Camera) openCamera.invoke(null, cameraId); - } - return result; - } - - public CameraFacade(FacadeManager manager) throws Exception { - super(manager); - mService = manager.getService(); - Camera camera = openCamera(0); - try { - mParameters = camera.getParameters(); - } finally { - camera.release(); - } - } - - @Rpc(description = "Take a picture and save it to the specified path.", returns = "A map of Booleans autoFocus and takePicture where True indicates success. cameraId also included.") - public Bundle cameraCapturePicture( - @RpcParameter(name = "targetPath") final String targetPath, - @RpcParameter(name = "useAutoFocus") @RpcDefault("true") Boolean useAutoFocus, - @RpcParameter(name = "cameraId", description = "Id of camera to use. SDK 9") @RpcDefault("0") Integer cameraId) - throws Exception { - final BooleanResult autoFocusResult = new BooleanResult(); - final BooleanResult takePictureResult = new BooleanResult(); - Camera camera = openCamera(cameraId); - camera.setParameters(mParameters); - - try { - Method method = camera.getClass().getMethod("setDisplayOrientation", int.class); - method.invoke(camera, 90); - } catch (Exception e) { - Log.e(e); - } - - try { - FutureActivityTask<SurfaceHolder> previewTask = setPreviewDisplay(camera); - camera.startPreview(); - if (useAutoFocus) { - autoFocus(autoFocusResult, camera); - } - takePicture(new File(targetPath), takePictureResult, camera); - previewTask.finish(); - } catch (Exception e) { - Log.e(e); - } finally { - camera.release(); - } - - Bundle result = new Bundle(); - result.putBoolean("autoFocus", autoFocusResult.mmResult); - result.putBoolean("takePicture", takePictureResult.mmResult); - result.putInt("cameraId", cameraId); - return result; - } - - private FutureActivityTask<SurfaceHolder> setPreviewDisplay(Camera camera) throws IOException, - InterruptedException { - FutureActivityTask<SurfaceHolder> task = new FutureActivityTask<SurfaceHolder>() { - @Override - public void onCreate() { - super.onCreate(); - final SurfaceView view = new SurfaceView(getActivity()); - getActivity().setContentView(view); - getActivity().getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED); - view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - view.getHolder().addCallback(new Callback() { - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - setResult(view.getHolder()); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - } - }); - } - }; - FutureActivityTaskExecutor taskQueue = - ((BaseApplication) mService.getApplication()).getTaskExecutor(); - taskQueue.execute(task); - camera.setPreviewDisplay(task.getResult()); - return task; - } - - private void takePicture(final File file, final BooleanResult takePictureResult, - final Camera camera) throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - camera.takePicture(null, null, new PictureCallback() { - @Override - public void onPictureTaken(byte[] data, Camera camera) { - if (!FileUtils.makeDirectories(file.getParentFile(), 0755)) { - takePictureResult.mmResult = false; - return; - } - try { - FileOutputStream output = new FileOutputStream(file); - output.write(data); - output.close(); - takePictureResult.mmResult = true; - } catch (FileNotFoundException e) { - Log.e("Failed to save picture.", e); - takePictureResult.mmResult = false; - return; - } catch (IOException e) { - Log.e("Failed to save picture.", e); - takePictureResult.mmResult = false; - return; - } finally { - latch.countDown(); - } - } - }); - latch.await(); - } - - private void autoFocus(final BooleanResult result, final Camera camera) - throws InterruptedException { - final CountDownLatch latch = new CountDownLatch(1); - { - camera.autoFocus(new AutoFocusCallback() { - @Override - public void onAutoFocus(boolean success, Camera camera) { - result.mmResult = success; - latch.countDown(); - } - }); - latch.await(); - } - } - - @Override - public void shutdown() { - // Nothing to clean up. - } - - @Rpc(description = "Starts the image capture application to take a picture and saves it to the specified path.") - public void cameraInteractiveCapturePicture( - @RpcParameter(name = "targetPath") final String targetPath) { - Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - File file = new File(targetPath); - intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); - AndroidFacade facade = mManager.getReceiver(AndroidFacade.class); - facade.startActivityForResult(intent); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/CommonIntentsFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/CommonIntentsFacade.java deleted file mode 100644 index ffa464c..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/CommonIntentsFacade.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.SearchManager; -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.net.Uri; -import android.provider.Contacts.People; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.File; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * A selection of commonly used intents. <br> - * <br> - * These can be used to trigger some common tasks. - * - */ -public class CommonIntentsFacade extends RpcReceiver { - - private final AndroidFacade mAndroidFacade; - - public CommonIntentsFacade(FacadeManager manager) { - super(manager); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - } - - @Override - public void shutdown() { - } - - @Rpc(description = "Display content to be picked by URI (e.g. contacts)", returns = "A map of result values.") - public Intent pick(@RpcParameter(name = "uri") String uri) throws JSONException { - return mAndroidFacade.startActivityForResult(Intent.ACTION_PICK, uri, null, null, null, null); - } - - @Rpc(description = "Starts the barcode scanner.", returns = "A Map representation of the result Intent.") - public Intent scanBarcode() throws JSONException { - try { - return mAndroidFacade.startActivityForResult("com.google.zxing.client.android.SCAN", null, - null, null, null, null); - } catch (ActivityNotFoundException e) { - Log.e("No Activity found to scan a barcode!", e); - return null; - } - } - - private void view(Uri uri, String type) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(uri, type); - mAndroidFacade.startActivity(intent); - } - - @Rpc(description = "Start activity with view action by URI (i.e. browser, contacts, etc.).") - public void view( - @RpcParameter(name = "uri") String uri, - @RpcParameter(name = "type", description = "MIME type/subtype of the URI") @RpcOptional String type, - @RpcParameter(name = "extras", description = "a Map of extras to add to the Intent") @RpcOptional JSONObject extras) - throws Exception { - mAndroidFacade.startActivity(Intent.ACTION_VIEW, uri, type, extras, true, null, null); - } - - @Rpc(description = "Opens a map search for query (e.g. pizza, 123 My Street).") - public void viewMap(@RpcParameter(name = "query, e.g. pizza, 123 My Street") String query) - throws Exception { - view("geo:0,0?q=" + query, null, null); - } - - @Rpc(description = "Opens the list of contacts.") - public void viewContacts() throws JSONException { - view(People.CONTENT_URI, null); - } - - @Rpc(description = "Opens the browser to display a local HTML file.") - public void viewHtml( - @RpcParameter(name = "path", description = "the path to the HTML file") String path) - throws JSONException { - File file = new File(path); - view(Uri.fromFile(file), "text/html"); - } - - @Rpc(description = "Starts a search for the given query.") - public void search(@RpcParameter(name = "query") String query) { - Intent intent = new Intent(Intent.ACTION_SEARCH); - intent.putExtra(SearchManager.QUERY, query); - mAndroidFacade.startActivity(intent); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java deleted file mode 100644 index 594c934..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ConnectivityManagerFacade.java +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.ConnectivityManager.PacketKeepaliveCallback; -import android.net.ConnectivityManager.PacketKeepalive; -import android.net.LinkProperties; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.NetworkInfo; -import android.provider.Settings.SettingNotFoundException; -import android.os.Bundle; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.telephony.TelephonyConstants; -import com.googlecode.android_scripting.facade.telephony.TelephonyEvents; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.HashMap; - -/** - * Access ConnectivityManager functions. - */ -public class ConnectivityManagerFacade extends RpcReceiver { - - public static int AIRPLANE_MODE_OFF = 0; - public static int AIRPLANE_MODE_ON = 1; - - class ConnectivityReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - Log.e("ConnectivityReceiver received non-connectivity action!"); - return; - } - - Bundle b = intent.getExtras(); - - if (b == null) { - Log.e("ConnectivityReceiver failed to receive extras!"); - return; - } - - int netType = - b.getInt(ConnectivityManager.EXTRA_NETWORK_TYPE, - ConnectivityManager.TYPE_NONE); - - if (netType == ConnectivityManager.TYPE_NONE) { - Log.i("ConnectivityReceiver received change to TYPE_NONE."); - return; - } - - /* - * Technically there is a race condition here, but retrieving the NetworkInfo from the - * bundle is deprecated. See ConnectivityManager.EXTRA_NETWORK_INFO - */ - for (NetworkInfo info : mManager.getAllNetworkInfo()) { - if (info.getType() == netType) { - mEventFacade.postEvent(TelephonyConstants.EventConnectivityChanged, info); - } - } - } - } - - class PacketKeepaliveReceiver extends PacketKeepaliveCallback { - public static final int EVENT_INVALID = -1; - public static final int EVENT_NONE = 0; - public static final int EVENT_STARTED = 1 << 0; - public static final int EVENT_STOPPED = 1 << 1; - public static final int EVENT_ERROR = 1 << 2; - public static final int EVENT_ALL = EVENT_STARTED | - EVENT_STOPPED | - EVENT_ERROR; - private int mEvents; - public String mId; - public PacketKeepalive mPacketKeepalive; - - public PacketKeepaliveReceiver(int events) { - super(); - mEvents = events; - mId = this.toString(); - } - - public void startListeningForEvents(int events) { - mEvents |= events & EVENT_ALL; - } - - public void stopListeningForEvents(int events) { - mEvents &= ~(events & EVENT_ALL); - } - - @Override - public void onStarted() { - Log.d("PacketKeepaliveCallback on start!"); - if ((mEvents & EVENT_STARTED) == EVENT_STARTED) { - mEventFacade.postEvent( - TelephonyConstants.EventPacketKeepaliveCallback, - new TelephonyEvents.PacketKeepaliveEvent( - mId, - getPacketKeepaliveReceiverEventString(EVENT_STARTED))); - } - } - - @Override - public void onStopped() { - Log.d("PacketKeepaliveCallback on stop!"); - if ((mEvents & EVENT_STOPPED) == EVENT_STOPPED) { - mEventFacade.postEvent( - TelephonyConstants.EventPacketKeepaliveCallback, - new TelephonyEvents.PacketKeepaliveEvent( - mId, - getPacketKeepaliveReceiverEventString(EVENT_STOPPED))); - } - } - - @Override - public void onError(int error) { - Log.d("PacketKeepaliveCallback on error! - code:" + error); - if ((mEvents & EVENT_ERROR) == EVENT_ERROR) { - mEventFacade.postEvent( - TelephonyConstants.EventPacketKeepaliveCallback, - new TelephonyEvents.PacketKeepaliveEvent( - mId, - getPacketKeepaliveReceiverEventString(EVENT_ERROR))); - } - } - } - - class NetworkCallback extends ConnectivityManager.NetworkCallback { - public static final int EVENT_INVALID = -1; - public static final int EVENT_NONE = 0; - public static final int EVENT_PRECHECK = 1 << 0; - public static final int EVENT_AVAILABLE = 1 << 1; - public static final int EVENT_LOSING = 1 << 2; - public static final int EVENT_LOST = 1 << 3; - public static final int EVENT_UNAVAILABLE = 1 << 4; - public static final int EVENT_CAPABILITIES_CHANGED = 1 << 5; - public static final int EVENT_SUSPENDED = 1 << 6; - public static final int EVENT_RESUMED = 1 << 7; - public static final int EVENT_LINK_PROPERTIES_CHANGED = 1 << 8; - public static final int EVENT_ALL = EVENT_PRECHECK | - EVENT_AVAILABLE | - EVENT_LOSING | - EVENT_LOST | - EVENT_UNAVAILABLE | - EVENT_CAPABILITIES_CHANGED | - EVENT_SUSPENDED | - EVENT_RESUMED | - EVENT_LINK_PROPERTIES_CHANGED; - - private int mEvents; - public String mId; - - public NetworkCallback(int events) { - super(); - mEvents = events; - mId = this.toString(); - } - - public void startListeningForEvents(int events) { - mEvents |= events & EVENT_ALL; - } - - public void stopListeningForEvents(int events) { - mEvents &= ~(events & EVENT_ALL); - } - - @Override - public void onPreCheck(Network network) { - Log.d("NetworkCallback onPreCheck"); - if ((mEvents & EVENT_PRECHECK) == EVENT_PRECHECK) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_PRECHECK), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onAvailable(Network network) { - Log.d("NetworkCallback onAvailable"); - if ((mEvents & EVENT_AVAILABLE) == EVENT_AVAILABLE) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_AVAILABLE), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onLosing(Network network, int maxMsToLive) { - Log.d("NetworkCallback onLosing"); - if ((mEvents & EVENT_LOSING) == EVENT_LOSING) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_LOSING), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - maxMsToLive)); - } - } - - @Override - public void onLost(Network network) { - Log.d("NetworkCallback onLost"); - if ((mEvents & EVENT_LOST) == EVENT_LOST) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_LOST), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onUnavailable() { - Log.d("NetworkCallback onUnavailable"); - if ((mEvents & EVENT_UNAVAILABLE) == EVENT_UNAVAILABLE) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_UNAVAILABLE), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onCapabilitiesChanged(Network network, - NetworkCapabilities networkCapabilities) { - Log.d("NetworkCallback onCapabilitiesChanged. RSSI:" + - networkCapabilities.getSignalStrength()); - if ((mEvents & EVENT_CAPABILITIES_CHANGED) == EVENT_CAPABILITIES_CHANGED) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_CAPABILITIES_CHANGED), - networkCapabilities.getSignalStrength(), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onNetworkSuspended(Network network) { - Log.d("NetworkCallback onNetworkSuspended"); - if ((mEvents & EVENT_SUSPENDED) == EVENT_SUSPENDED) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_SUSPENDED), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onLinkPropertiesChanged(Network network, - LinkProperties linkProperties) { - Log.d("NetworkCallback onLinkPropertiesChanged"); - if ((mEvents & EVENT_LINK_PROPERTIES_CHANGED) == EVENT_LINK_PROPERTIES_CHANGED) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_LINK_PROPERTIES_CHANGED), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - - @Override - public void onNetworkResumed(Network network) { - Log.d("NetworkCallback onNetworkResumed"); - if ((mEvents & EVENT_RESUMED) == EVENT_RESUMED) { - mEventFacade.postEvent( - TelephonyConstants.EventNetworkCallback, - new TelephonyEvents.NetworkCallbackEvent( - mId, - getNetworkCallbackEventString(EVENT_RESUMED), - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE, - TelephonyEvents.NetworkCallbackEvent.INVALID_VALUE)); - } - } - } - - private static int getNetworkCallbackEvent(String event) { - switch (event) { - case TelephonyConstants.NetworkCallbackPreCheck: - return NetworkCallback.EVENT_PRECHECK; - case TelephonyConstants.NetworkCallbackAvailable: - return NetworkCallback.EVENT_AVAILABLE; - case TelephonyConstants.NetworkCallbackLosing: - return NetworkCallback.EVENT_LOSING; - case TelephonyConstants.NetworkCallbackLost: - return NetworkCallback.EVENT_LOST; - case TelephonyConstants.NetworkCallbackUnavailable: - return NetworkCallback.EVENT_UNAVAILABLE; - case TelephonyConstants.NetworkCallbackCapabilitiesChanged: - return NetworkCallback.EVENT_CAPABILITIES_CHANGED; - case TelephonyConstants.NetworkCallbackSuspended: - return NetworkCallback.EVENT_SUSPENDED; - case TelephonyConstants.NetworkCallbackResumed: - return NetworkCallback.EVENT_RESUMED; - case TelephonyConstants.NetworkCallbackLinkPropertiesChanged: - return NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED; - } - return NetworkCallback.EVENT_INVALID; - } - - private static String getNetworkCallbackEventString(int event) { - switch (event) { - case NetworkCallback.EVENT_PRECHECK: - return TelephonyConstants.NetworkCallbackPreCheck; - case NetworkCallback.EVENT_AVAILABLE: - return TelephonyConstants.NetworkCallbackAvailable; - case NetworkCallback.EVENT_LOSING: - return TelephonyConstants.NetworkCallbackLosing; - case NetworkCallback.EVENT_LOST: - return TelephonyConstants.NetworkCallbackLost; - case NetworkCallback.EVENT_UNAVAILABLE: - return TelephonyConstants.NetworkCallbackUnavailable; - case NetworkCallback.EVENT_CAPABILITIES_CHANGED: - return TelephonyConstants.NetworkCallbackCapabilitiesChanged; - case NetworkCallback.EVENT_SUSPENDED: - return TelephonyConstants.NetworkCallbackSuspended; - case NetworkCallback.EVENT_RESUMED: - return TelephonyConstants.NetworkCallbackResumed; - case NetworkCallback.EVENT_LINK_PROPERTIES_CHANGED: - return TelephonyConstants.NetworkCallbackLinkPropertiesChanged; - } - return TelephonyConstants.NetworkCallbackInvalid; - } - - private static int getPacketKeepaliveReceiverEvent(String event) { - switch (event) { - case TelephonyConstants.PacketKeepaliveCallbackStarted: - return PacketKeepaliveReceiver.EVENT_STARTED; - case TelephonyConstants.PacketKeepaliveCallbackStopped: - return PacketKeepaliveReceiver.EVENT_STOPPED; - case TelephonyConstants.PacketKeepaliveCallbackError: - return PacketKeepaliveReceiver.EVENT_ERROR; - } - return PacketKeepaliveReceiver.EVENT_INVALID; - } - - private static String getPacketKeepaliveReceiverEventString(int event) { - switch (event) { - case PacketKeepaliveReceiver.EVENT_STARTED: - return TelephonyConstants.PacketKeepaliveCallbackStarted; - case PacketKeepaliveReceiver.EVENT_STOPPED: - return TelephonyConstants.PacketKeepaliveCallbackStopped; - case PacketKeepaliveReceiver.EVENT_ERROR: - return TelephonyConstants.PacketKeepaliveCallbackError; - } - return TelephonyConstants.PacketKeepaliveCallbackInvalid; - } - - private final ConnectivityManager mManager; - private final Service mService; - private final Context mContext; - private final ConnectivityReceiver mConnectivityReceiver; - private final EventFacade mEventFacade; - private PacketKeepalive mPacketKeepalive; - private NetworkCallback mNetworkCallback; - private static HashMap<String, PacketKeepaliveReceiver> mPacketKeepaliveReceiverMap = - new HashMap<String, PacketKeepaliveReceiver>(); - private static HashMap<String, NetworkCallback> mNetworkCallbackMap = - new HashMap<String, NetworkCallback>(); - private boolean mTrackingConnectivityStateChange; - - public ConnectivityManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContext = mService.getBaseContext(); - mManager = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - mConnectivityReceiver = new ConnectivityReceiver(); - mTrackingConnectivityStateChange = false; - } - - @Rpc(description = "Listen for connectivity changes") - public void connectivityStartTrackingConnectivityStateChange() { - if (!mTrackingConnectivityStateChange) { - mTrackingConnectivityStateChange = true; - mContext.registerReceiver(mConnectivityReceiver, - new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); - } - } - - @Rpc(description = "start natt keep alive") - public String connectivityStartNattKeepalive(Integer intervalSeconds, String srcAddrString, - Integer srcPort, String dstAddrString) throws UnknownHostException { - try { - Network mNetwork = mManager.getActiveNetwork(); - InetAddress srcAddr = InetAddress.getByName(srcAddrString); - InetAddress dstAddr = InetAddress.getByName(dstAddrString); - Log.d("startNattKeepalive srcAddr:" + srcAddr.getHostAddress()); - Log.d("startNattKeepalive dstAddr:" + dstAddr.getHostAddress()); - Log.d("startNattKeepalive srcPort:" + srcPort); - Log.d("startNattKeepalive intervalSeconds:" + intervalSeconds); - PacketKeepaliveReceiver mPacketKeepaliveReceiver = new PacketKeepaliveReceiver( - PacketKeepaliveReceiver.EVENT_ALL); - mPacketKeepalive = mManager.startNattKeepalive(mNetwork, (int) intervalSeconds, - mPacketKeepaliveReceiver, srcAddr, (int) srcPort, dstAddr); - if (mPacketKeepalive != null) { - mPacketKeepaliveReceiver.mPacketKeepalive = mPacketKeepalive; - String key = mPacketKeepaliveReceiver.mId; - mPacketKeepaliveReceiverMap.put(key, mPacketKeepaliveReceiver); - return key; - } else { - Log.e("startNattKeepalive fail, startNattKeepalive return null"); - return null; - } - } catch (UnknownHostException e) { - Log.e("startNattKeepalive UnknownHostException"); - return null; - } - } - - @Rpc(description = "stop natt keep alive") - public Boolean connectivityStopNattKeepalive(String key) { - PacketKeepaliveReceiver mPacketKeepaliveReceiver = - mPacketKeepaliveReceiverMap.get(key); - if (mPacketKeepaliveReceiver != null) { - mPacketKeepaliveReceiverMap.remove(key); - mPacketKeepaliveReceiver.mPacketKeepalive.stop(); - return true; - } else { - return false; - } - } - - @Rpc(description = "start listening for NattKeepalive Event") - public Boolean connectivityNattKeepaliveStartListeningForEvent(String key, String eventString) { - PacketKeepaliveReceiver mPacketKeepaliveReceiver = - mPacketKeepaliveReceiverMap.get(key); - if (mPacketKeepaliveReceiver != null) { - int event = getPacketKeepaliveReceiverEvent(eventString); - if (event == PacketKeepaliveReceiver.EVENT_INVALID) { - return false; - } - mPacketKeepaliveReceiver.startListeningForEvents(event); - return true; - } else { - return false; - } - } - - @Rpc(description = "stop listening for NattKeepalive Event") - public Boolean connectivityNattKeepaliveStopListeningForEvent(String key, String eventString) { - PacketKeepaliveReceiver mPacketKeepaliveReceiver = - mPacketKeepaliveReceiverMap.get(key); - if (mPacketKeepaliveReceiver != null) { - int event = getPacketKeepaliveReceiverEvent(eventString); - if (event == PacketKeepaliveReceiver.EVENT_INVALID) { - return false; - } - mPacketKeepaliveReceiver.stopListeningForEvents(event); - return true; - } else { - return false; - } - } - - @Rpc(description = "start listening for NetworkCallback Event") - public Boolean connectivityNetworkCallbackStartListeningForEvent(String key, String eventString) { - NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); - if (mNetworkCallback != null) { - int event = getNetworkCallbackEvent(eventString); - if (event == NetworkCallback.EVENT_INVALID) { - return false; - } - mNetworkCallback.startListeningForEvents(event); - return true; - } else { - return false; - } - } - - @Rpc(description = "stop listening for NetworkCallback Event") - public Boolean connectivityNetworkCallbackStopListeningForEvent(String key, String eventString) { - NetworkCallback mNetworkCallback = mNetworkCallbackMap.get(key); - if (mNetworkCallback != null) { - int event = getNetworkCallbackEvent(eventString); - if (event == NetworkCallback.EVENT_INVALID) { - return false; - } - mNetworkCallback.stopListeningForEvents(event); - return true; - } else { - return false; - } - } - - @Rpc(description = "Set Rssi Threshold Monitor") - public String connectivitySetRssiThresholdMonitor(Integer rssi) { - Log.d("SL4A:setRssiThresholdMonitor rssi = " + rssi); - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - builder.setSignalStrength((int) rssi); - builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - NetworkRequest networkRequest = builder.build(); - mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); - mManager.registerNetworkCallback(networkRequest, mNetworkCallback); - String key = mNetworkCallback.mId; - mNetworkCallbackMap.put(key, mNetworkCallback); - return key; - } - - @Rpc(description = "Stop Rssi Threshold Monitor") - public Boolean connectivityStopRssiThresholdMonitor(String key) { - Log.d("SL4A:stopRssiThresholdMonitor key = " + key); - return connectivityUnregisterNetworkCallback(key); - } - - private NetworkRequest buildNetworkRequestFromJson(JSONObject configJson) - throws JSONException { - NetworkRequest.Builder builder = new NetworkRequest.Builder(); - - if (configJson.has("TransportType")) { - Log.d("build TransportType" + configJson.getInt("TransportType")); - builder.addTransportType(configJson.getInt("TransportType")); - } - if (configJson.has("SignalStrength")) { - Log.d("build SignalStrength" + configJson.getInt("SignalStrength")); - builder.setSignalStrength(configJson.getInt("SignalStrength")); - } - if (configJson.has("Capability")) { - JSONArray capabilities = configJson.getJSONArray("Capability"); - for (int i = 0; i < capabilities.length(); i++) { - Log.d("build Capability" + capabilities.getInt(i)); - builder.addCapability(capabilities.getInt(i)); - } - } - if (configJson.has("LinkUpstreamBandwidthKbps")) { - Log.d("build LinkUpstreamBandwidthKbps" + configJson.getInt( - "LinkUpstreamBandwidthKbps")); - builder.setLinkUpstreamBandwidthKbps(configJson.getInt( - "LinkUpstreamBandwidthKbps")); - } - if (configJson.has("LinkDownstreamBandwidthKbps")) { - Log.d("build LinkDownstreamBandwidthKbps" + configJson.getInt( - "LinkDownstreamBandwidthKbps")); - builder.setLinkDownstreamBandwidthKbps(configJson.getInt( - "LinkDownstreamBandwidthKbps")); - } - if (configJson.has("NetworkSpecifier")) { - Log.d("build NetworkSpecifier" + configJson.getString("NetworkSpecifier")); - builder.setNetworkSpecifier(configJson.getString( - "NetworkSpecifier")); - } - NetworkRequest networkRequest = builder.build(); - return networkRequest; - } - - @Rpc(description = "register a network callback") - public String connectivityRegisterNetworkCallback(@RpcParameter(name = "configJson") - JSONObject configJson) throws JSONException { - NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); - mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); - mManager.registerNetworkCallback(networkRequest, mNetworkCallback); - String key = mNetworkCallback.mId; - mNetworkCallbackMap.put(key, mNetworkCallback); - return key; - } - - @Rpc(description = "unregister a network callback") - public Boolean connectivityUnregisterNetworkCallback(@RpcParameter(name = "key") - String key) { - mNetworkCallback = mNetworkCallbackMap.get(key); - if (mNetworkCallback != null) { - mNetworkCallbackMap.remove(key); - mManager.unregisterNetworkCallback(mNetworkCallback); - return true; - } else { - return false; - } - } - - @Rpc(description = "request a network") - public String connectivityRequestNetwork(@RpcParameter(name = "configJson") - JSONObject configJson) throws JSONException { - NetworkRequest networkRequest = buildNetworkRequestFromJson(configJson); - mNetworkCallback = new NetworkCallback(NetworkCallback.EVENT_ALL); - mManager.requestNetwork(networkRequest, mNetworkCallback); - String key = mNetworkCallback.mId; - mNetworkCallbackMap.put(key, mNetworkCallback); - return key; - } - - @Rpc(description = "Stop listening for connectivity changes") - public void connectivityStopTrackingConnectivityStateChange() { - if (mTrackingConnectivityStateChange) { - mTrackingConnectivityStateChange = false; - mContext.unregisterReceiver(mConnectivityReceiver); - } - } - - @Rpc(description = "Get the extra information about the network state provided by lower network layers.") - public String connectivityNetworkGetActiveConnectionExtraInfo() { - NetworkInfo current = mManager.getActiveNetworkInfo(); - if (current == null) { - Log.d("No network is active at the moment."); - return null; - } - return current.getExtraInfo(); - } - - @Rpc(description = "Return the subtype name of the current network, null if not connected") - public String connectivityNetworkGetActiveConnectionSubtypeName() { - NetworkInfo current = mManager.getActiveNetworkInfo(); - if (current == null) { - Log.d("No network is active at the moment."); - return null; - } - return current.getSubtypeName(); - } - - @Rpc(description = "Return a human-readable name describe the type of the network, e.g. WIFI") - public String connectivityNetworkGetActiveConnectionTypeName() { - NetworkInfo current = mManager.getActiveNetworkInfo(); - if (current == null) { - Log.d("No network is active at the moment."); - return null; - } - return current.getTypeName(); - } - - @Rpc(description = "Get connection status information about all network types supported by the device.") - public NetworkInfo[] connectivityNetworkGetAllInfo() { - return mManager.getAllNetworkInfo(); - } - - @Rpc(description = "Check whether the active network is connected to the Internet.") - public Boolean connectivityNetworkIsConnected() { - NetworkInfo current = mManager.getActiveNetworkInfo(); - if (current == null) { - Log.d("No network is active at the moment."); - return false; - } - return current.isConnected(); - } - - @Rpc(description = "Checks the airplane mode setting.", - returns = "True if airplane mode is enabled.") - public Boolean connectivityCheckAirplaneMode() { - try { - return android.provider.Settings.System.getInt(mService.getContentResolver(), - android.provider.Settings.Global.AIRPLANE_MODE_ON) == AIRPLANE_MODE_ON; - } catch (SettingNotFoundException e) { - return false; - } - } - - @Rpc(description = "Toggles airplane mode on and off.", - returns = "True if airplane mode is enabled.") - public void connectivityToggleAirplaneMode(@RpcParameter(name = "enabled") - @RpcOptional - Boolean enabled) { - if (enabled == null) { - enabled = !connectivityCheckAirplaneMode(); - } - mManager.setAirplaneMode(enabled); - } - - @Rpc(description = "Check if tethering supported or not.", - returns = "True if tethering is supported.") - public boolean connectivityIsTetheringSupported() { - return mManager.isTetheringSupported(); - } - - @Override - public void shutdown() { - connectivityStopTrackingConnectivityStateChange(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ContactsFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ContactsFacade.java deleted file mode 100644 index 4ab4a1d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ContactsFacade.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.provider.ContactsContract; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.ArrayList; -import java.util.List; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Provides access to contacts related functionality. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com - */ -public class ContactsFacade extends RpcReceiver { - private static final Uri CONTACTS_URI = Uri.parse("content://contacts/people"); - private final ContentResolver mContentResolver; - private final Service mService; - private final CommonIntentsFacade mCommonIntentsFacade; - public Uri mPhoneContent = null; - public String mContactId; - public String mPrimary; - public String mPhoneNumber; - public String mHasPhoneNumber; - - public ContactsFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContentResolver = mService.getContentResolver(); - mCommonIntentsFacade = manager.getReceiver(CommonIntentsFacade.class); - try { - // Backward compatibility... get contract stuff using reflection - Class<?> phone = Class.forName("android.provider.ContactsContract$CommonDataKinds$Phone"); - mPhoneContent = (Uri) phone.getField("CONTENT_URI").get(null); - mContactId = (String) phone.getField("CONTACT_ID").get(null); - mPrimary = (String) phone.getField("IS_PRIMARY").get(null); - mPhoneNumber = (String) phone.getField("NUMBER").get(null); - mHasPhoneNumber = (String) phone.getField("HAS_PHONE_NUMBER").get(null); - } catch (Exception e) { - } - } - - private Uri buildUri(Integer id) { - Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id); - return uri; - } - - @Rpc(description = "Displays a list of contacts to pick from.", returns = "A map of result values.") - public Intent pickContact() throws JSONException { - return mCommonIntentsFacade.pick("content://contacts/people"); - } - - @Rpc(description = "Displays a list of phone numbers to pick from.", returns = "The selected phone number.") - public String pickPhone() throws JSONException { - String result = null; - Intent data = mCommonIntentsFacade.pick("content://contacts/phones"); - if (data != null) { - Uri phoneData = data.getData(); - Cursor cursor = mService.getContentResolver().query(phoneData, null, null, null, null); - if (cursor != null) { - if (cursor.moveToFirst()) { - result = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.PhoneLookup.NUMBER)); - } - cursor.close(); - } - } - return result; - } - - @Rpc(description = "Returns a List of all possible attributes for contacts.") - public List<String> contactsGetAttributes() { - List<String> result = new ArrayList<String>(); - Cursor cursor = mContentResolver.query(CONTACTS_URI, null, null, null, null); - if (cursor != null) { - String[] columns = cursor.getColumnNames(); - for (int i = 0; i < columns.length; i++) { - result.add(columns[i]); - } - cursor.close(); - } - return result; - } - - // TODO(MeanEYE.rcf): Add ability to narrow selection by providing named pairs of attributes. - @Rpc(description = "Returns a List of all contact IDs.") - public List<Integer> contactsGetIds() { - List<Integer> result = new ArrayList<Integer>(); - String[] columns = { "_id" }; - Cursor cursor = mContentResolver.query(CONTACTS_URI, columns, null, null, null); - if (cursor != null) { - while (cursor.moveToNext()) { - result.add(cursor.getInt(0)); - } - cursor.close(); - } - return result; - } - - @Rpc(description = "Returns a List of all contacts.", returns = "a List of contacts as Maps") - public List<JSONObject> contactsGet( - @RpcParameter(name = "attributes") @RpcOptional JSONArray attributes) throws JSONException { - List<JSONObject> result = new ArrayList<JSONObject>(); - String[] columns; - if (attributes == null || attributes.length() == 0) { - // In case no attributes are specified we set the default ones. - columns = new String[] { "_id", "name", "primary_phone", "primary_email", "type" }; - } else { - // Convert selected attributes list into usable string list. - columns = new String[attributes.length()]; - for (int i = 0; i < attributes.length(); i++) { - columns[i] = attributes.getString(i); - } - } - List<String> queryList = new ArrayList<String>(); - for (String s : columns) { - queryList.add(s); - } - if (!queryList.contains("_id")) { - queryList.add("_id"); - } - - String[] query = queryList.toArray(new String[queryList.size()]); - Cursor cursor = mContentResolver.query(CONTACTS_URI, query, null, null, null); - if (cursor != null) { - int idIndex = cursor.getColumnIndex("_id"); - while (cursor.moveToNext()) { - String id = cursor.getString(idIndex); - JSONObject message = new JSONObject(); - for (int i = 0; i < columns.length; i++) { - String key = columns[i]; - String value = cursor.getString(cursor.getColumnIndex(key)); - if (mPhoneNumber != null) { - if (key.equals("primary_phone")) { - value = findPhone(id); - } - } - message.put(key, value); - } - result.add(message); - } - cursor.close(); - } - return result; - } - - private String findPhone(String id) { - String result = null; - if (id == null || id.equals("")) { - return result; - } - try { - if (Integer.parseInt(id) > 0) { - Cursor pCur = - mContentResolver.query(mPhoneContent, new String[] { mPhoneNumber }, mContactId - + " = ? and " + mPrimary + "=1", new String[] { id }, null); - if (pCur != null) { - pCur.getColumnNames(); - while (pCur.moveToNext()) { - result = pCur.getString(0); - break; - } - } - pCur.close(); - } - } catch (Exception e) { - return null; - } - return result; - } - - @Rpc(description = "Returns contacts by ID.") - public JSONObject contactsGetById(@RpcParameter(name = "id") Integer id, - @RpcParameter(name = "attributes") @RpcOptional JSONArray attributes) throws JSONException { - JSONObject result = null; - Uri uri = buildUri(id); - String[] columns; - if (attributes == null || attributes.length() == 0) { - // In case no attributes are specified we set the default ones. - columns = new String[] { "_id", "name", "primary_phone", "primary_email", "type" }; - } else { - // Convert selected attributes list into usable string list. - columns = new String[attributes.length()]; - for (int i = 0; i < attributes.length(); i++) { - columns[i] = attributes.getString(i); - } - } - Cursor cursor = mContentResolver.query(uri, columns, null, null, null); - if (cursor != null) { - result = new JSONObject(); - cursor.moveToFirst(); - for (int i = 0; i < columns.length; i++) { - result.put(columns[i], cursor.getString(i)); - } - cursor.close(); - } - return result; - } - - // TODO(MeanEYE.rcf): Add ability to narrow selection by providing named pairs of attributes. - @Rpc(description = "Returns the number of contacts.") - public Integer contactsGetCount() { - Integer result = 0; - Cursor cursor = mContentResolver.query(CONTACTS_URI, null, null, null, null); - if (cursor != null) { - result = cursor.getCount(); - cursor.close(); - } - return result; - } - - private String[] jsonToArray(JSONArray array) throws JSONException { - String[] result = null; - if (array != null && array.length() > 0) { - result = new String[array.length()]; - for (int i = 0; i < array.length(); i++) { - result[i] = array.getString(i); - } - } - return result; - } - - /** - * Exactly as per <a href= - * "http://developer.android.com/reference/android/content/ContentResolver.html#query%28android.net.Uri,%20java.lang.String[],%20java.lang.String,%20java.lang.String[],%20java.lang.String%29" - * >ContentResolver.query</a> - */ - @Rpc(description = "Content Resolver Query", returns = "result of query as Maps") - public List<JSONObject> queryContent( - @RpcParameter(name = "uri", description = "The URI, using the content:// scheme, for the content to retrieve.") String uri, - @RpcParameter(name = "attributes", description = "A list of which columns to return. Passing null will return all columns") @RpcOptional JSONArray attributes, - @RpcParameter(name = "selection", description = "A filter declaring which rows to return") @RpcOptional String selection, - @RpcParameter(name = "selectionArgs", description = "You may include ?s in selection, which will be replaced by the values from selectionArgs") @RpcOptional JSONArray selectionArgs, - @RpcParameter(name = "order", description = "How to order the rows") @RpcOptional String order) - throws JSONException { - List<JSONObject> result = new ArrayList<JSONObject>(); - String[] columns = jsonToArray(attributes); - String[] args = jsonToArray(selectionArgs); - Cursor cursor = mContentResolver.query(Uri.parse(uri), columns, selection, args, order); - if (cursor != null) { - String[] names = cursor.getColumnNames(); - while (cursor.moveToNext()) { - JSONObject message = new JSONObject(); - for (int i = 0; i < cursor.getColumnCount(); i++) { - String key = names[i]; - String value = cursor.getString(i); - message.put(key, value); - } - result.add(message); - } - cursor.close(); - } - return result; - } - - @Rpc(description = "Content Resolver Query Attributes", returns = "a list of available columns for a given content uri") - public JSONArray queryAttributes( - @RpcParameter(name = "uri", description = "The URI, using the content:// scheme, for the content to retrieve.") String uri) - throws JSONException { - JSONArray result = new JSONArray(); - Cursor cursor = mContentResolver.query(Uri.parse(uri), null, "1=0", null, null); - if (cursor != null) { - String[] names = cursor.getColumnNames(); - for (String name : names) { - result.put(name); - } - cursor.close(); - } - return result; - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java deleted file mode 100644 index d0c472c..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/DisplayFacade.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import java.util.HashMap; - -import android.app.Service; -import android.content.Context; -import android.graphics.Point; -import android.hardware.display.DisplayManager; -import android.util.DisplayMetrics; -import android.view.Display; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class DisplayFacade extends RpcReceiver { - - private final Service mService; - private final DisplayManager mDisplayManager; - private HashMap<Integer, Display> mDisplays; - - public DisplayFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mDisplayManager = (DisplayManager) mService.getSystemService(Context.DISPLAY_SERVICE); - updateDisplays(mDisplayManager.getDisplays()); - } - - private void updateDisplays(Display[] displays) { - if (mDisplays == null) { - mDisplays = new HashMap<Integer, Display>(); - } - mDisplays.clear(); - for(Display d : displays) { - mDisplays.put(d.getDisplayId(), d); - } - } - - @Rpc(description = "Get a list of IDs of the logical displays connected." - + "Also updates the cached displays.") - public Integer[] displayGetDisplays() { - Display[] displays = mDisplayManager.getDisplays(); - updateDisplays(displays); - Integer[] results = new Integer[displays.length]; - for(int i = 0; i < displays.length; i++) { - results[i] = displays[i].getDisplayId(); - } - return results; - } - - @Rpc(description = "Get the size of the specified display in pixels.") - public Point displayGetSize( - @RpcParameter(name = "displayId") - @RpcDefault(value = "0") - Integer displayId) { - Point outSize = new Point(); - Display d = mDisplays.get(displayId); - d.getSize(outSize); - return outSize; - } - - @Rpc(description = "Get the maximum screen size dimension that will happen.") - public Integer displayGetMaximumSizeDimension( - @RpcParameter(name = "displayId") - @RpcDefault(value = "0") - Integer displayId) { - Display d = mDisplays.get(displayId); - return d.getMaximumSizeDimension(); - } - - @Rpc(description = "Get display metrics based on the real size of this display.") - public DisplayMetrics displayGetRealMetrics( - @RpcParameter(name = "displayId") - @RpcDefault(value = "0") - Integer displayId) { - Display d = mDisplays.get(displayId); - DisplayMetrics outMetrics = new DisplayMetrics(); - d.getRealMetrics(outMetrics); - return outMetrics; - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java deleted file mode 100644 index 36e620d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/EventFacade.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import java.util.HashMap; -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.TimeUnit; - -import org.json.JSONException; - -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.event.Event; -import com.googlecode.android_scripting.event.EventObserver; -import com.googlecode.android_scripting.event.EventServer; -import com.googlecode.android_scripting.future.FutureResult; -import com.googlecode.android_scripting.jsonrpc.JsonBuilder; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcName; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Manage the event queue. <br> - * <br> - * <b>Usage Notes:</b><br> - * EventFacade APIs interact with the Event Queue (a data buffer containing up to 1024 event - * entries).<br> - * Events are automatically entered into the Event Queue following API calls such as startSensing() - * and startLocating().<br> - * The Event Facade provides control over how events are entered into (and removed from) the Event - * Queue.<br> - * The Event Queue provides a useful means of recording background events (such as sensor data) when - * the phone is busy with foreground activities. - * - * @author Felix Arends (felix.arends@gmail.com) - */ -public class EventFacade extends RpcReceiver { - /** - * The maximum length of the event queue. Old events will be discarded when this limit is - * exceeded. - */ - private static final int MAX_QUEUE_SIZE = 1024; - private final Queue<Event> mEventQueue = new ConcurrentLinkedQueue<Event>(); - private final CopyOnWriteArrayList<EventObserver> mGlobalEventObservers = - new CopyOnWriteArrayList<EventObserver>(); - private final Multimap<String, EventObserver> mNamedEventObservers = Multimaps - .synchronizedListMultimap(ArrayListMultimap.<String, EventObserver> create()); - private EventServer mEventServer = null; - private final HashMap<String, BroadcastListener> mBroadcastListeners = - new HashMap<String, BroadcastListener>(); - private final Context mContext; - private boolean bEventServerRunning; - - public EventFacade(FacadeManager manager) { - super(manager); - mContext = manager.getService().getApplicationContext(); - Log.v("Creating new EventFacade Instance()"); - bEventServerRunning = false; - } - - /** - * Example (python): droid.eventClearBuffer() - */ - @Rpc(description = "Clears all events from the event buffer.") - public void eventClearBuffer() { - mEventQueue.clear(); - } - - /** - * Registers a listener for a new broadcast signal - */ - @Rpc(description = "Registers a listener for a new broadcast signal") - public boolean eventRegisterForBroadcast( - @RpcParameter(name = "category") String category, - @RpcParameter(name = "enqueue", - description = "Should this events be added to the event queue or only dispatched") @RpcDefault(value = "true") Boolean enqueue) { - if (mBroadcastListeners.containsKey(category)) { - return false; - } - - BroadcastListener b = new BroadcastListener(this, enqueue.booleanValue()); - IntentFilter c = new IntentFilter(category); - mContext.registerReceiver(b, c); - mBroadcastListeners.put(category, b); - - return true; - } - - @Rpc(description = "Stop listening for a broadcast signal") - public void eventUnregisterForBroadcast( - @RpcParameter(name = "category") String category) { - if (!mBroadcastListeners.containsKey(category)) { - return; - } - - mContext.unregisterReceiver(mBroadcastListeners.get(category)); - mBroadcastListeners.remove(category); - } - - @Rpc(description = "Lists all the broadcast signals we are listening for") - public Set<String> eventGetBrodcastCategories() { - return mBroadcastListeners.keySet(); - } - - /** - * Actual data returned in the map will depend on the type of event. - * - * <pre> - * Example (python): - * import android, time - * droid = android.Android() - * droid.startSensing() - * time.sleep(1) - * droid.eventClearBuffer() - * time.sleep(1) - * e = eventPoll(1).result - * event_entry_number = 0 - * x = e[event_entry_ number]['data']['xforce'] - * </pre> - * - * e has the format:<br> - * [{u'data': {u'accuracy': 0, u'pitch': -0.48766891956329345, u'xmag': -5.6875, u'azimuth': - * 0.3312483489513397, u'zforce': 8.3492730000000002, u'yforce': 4.5628165999999997, u'time': - * 1297072704.813, u'ymag': -11.125, u'zmag': -42.375, u'roll': -0.059393649548292161, - * u'xforce': 0.42223078000000003}, u'name': u'sensors', u'time': 1297072704813000L}]<br> - * x has the string value of the x force data (0.42223078000000003) at the time of the event - * entry. </pre> - */ - - @Rpc(description = "Returns and removes the oldest n events (i.e. location or sensor update, etc.) from the event buffer.", - returns = "A List of Maps of event properties.") - public List<Event> eventPoll( - @RpcParameter(name = "number_of_events") @RpcDefault("1") Integer number_of_events) { - List<Event> events = Lists.newArrayList(); - for (int i = 0; i < number_of_events; i++) { - Event event = mEventQueue.poll(); - if (event == null) { - break; - } - events.add(event); - } - return events; - } - - @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.", - returns = "Map of event properties.") - public Event eventWaitFor( - @RpcParameter(name = "eventName") - final String eventName, - @RpcParameter(name = "removeEvent") - final Boolean removeEvent, - @RpcParameter(name = "timeout", description = "the maximum time to wait (in ms)") @RpcOptional Integer timeout) - throws InterruptedException { - Event result = null; - final FutureResult<Event> futureEvent; - synchronized (mEventQueue) { // First check to make sure it isn't already there - for (Event event : mEventQueue) { - if (event.getName().equals(eventName)) { - result = event; - if (removeEvent) - mEventQueue.remove(event); - return result; - } - } - futureEvent = new FutureResult<Event>(); - addNamedEventObserver(eventName, new EventObserver() { - @Override - public void onEventReceived(Event event) { - if (event.getName().equals(eventName)) { - synchronized (futureEvent) { - if (!futureEvent.isDone()) { - futureEvent.set(event); - // TODO(navtej) Remove log. - Log.v(String.format("Removeing observer (%s) got event (%s)", - this, - event)); - removeEventObserver(this); - } - if (removeEvent) - mEventQueue.remove(event); - } - } - } - }); - } - if (futureEvent != null) { - if (timeout != null) { - result = futureEvent.get(timeout, TimeUnit.MILLISECONDS); - } else { - result = futureEvent.get(); - } - } - return result; - } - - @Rpc(description = "Blocks until an event occurs. The returned event is removed from the buffer.", - returns = "Map of event properties.") - public Event eventWait( - @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout) - throws InterruptedException { - Event result = null; - final FutureResult<Event> futureEvent = new FutureResult<Event>(); - EventObserver observer; - synchronized (mEventQueue) { // Anything in queue? - if (mEventQueue.size() > 0) { - return mEventQueue.poll(); // return it. - } - observer = new EventObserver() { - @Override - public void onEventReceived(Event event) { // set up observer for any events. - synchronized (futureEvent) { - if (!futureEvent.isDone()) { - futureEvent.set(event); - // TODO(navtej) Remove log. - Log.v(String.format("onEventReceived for event (%s)", event)); - } - } - } - }; - addGlobalEventObserver(observer); - } - if (timeout != null) { - result = futureEvent.get(timeout, TimeUnit.MILLISECONDS); - } else { - result = futureEvent.get(); - } - if (result != null) { - mEventQueue.remove(result); - } - // TODO(navtej) Remove log. - Log.v(String.format("Removeing observer (%s) got event (%s)", observer, result)); - if (observer != null) { - removeEventObserver(observer); // Make quite sure this goes away. - } - return result; - } - - /** - * <pre> - * Example: - * import android - * from datetime import datetime - * droid = android.Android() - * t = datetime.now() - * droid.eventPost('Some Event', t) - * </pre> - */ - @Rpc(description = "Post an event to the event queue.") - public void eventPost( - @RpcParameter(name = "name", description = "Name of event") String name, - @RpcParameter(name = "data", description = "Data contained in event.") String data, - @RpcParameter(name = "enqueue", - description = "Set to False if you don't want your events to be added to the event queue, just dispatched.") @RpcOptional @RpcDefault("false") Boolean enqueue) { - postEvent(name, data, enqueue.booleanValue()); - } - - /** - * Post an event and queue it - */ - public void postEvent(String name, Object data) { - postEvent(name, data, true); - } - - /** - * Posts an event with to the event queue. - */ - public void postEvent(String name, Object data, boolean enqueue) { - Event event = new Event(name, data); - if (enqueue != false) { - synchronized (mEventQueue) { - while (mEventQueue.size() >= MAX_QUEUE_SIZE) { - mEventQueue.remove(); - } - mEventQueue.add(event); - } - Log.v(String.format("postEvent(%s)", name)); - } - synchronized (mNamedEventObservers) { - for (EventObserver observer : mNamedEventObservers.get(name)) { - observer.onEventReceived(event); - } - } - synchronized (mGlobalEventObservers) { - // TODO(navtej) Remove log. - Log.v(String.format("mGlobalEventObservers size (%s)", mGlobalEventObservers.size())); - for (EventObserver observer : mGlobalEventObservers) { - observer.onEventReceived(event); - } - } - } - - @RpcDeprecated(value = "eventPost", release = "r4") - @Rpc(description = "Post an event to the event queue.") - @RpcName(name = "postEvent") - public void rpcPostEvent( - @RpcParameter(name = "name") String name, - @RpcParameter(name = "data") String data) { - postEvent(name, data); - } - - @RpcDeprecated(value = "eventPoll", release = "r4") - @Rpc(description = "Returns and removes the oldest event (i.e. location or sensor update, etc.) from the event buffer.", - returns = "Map of event properties.") - public Event receiveEvent() { - return mEventQueue.poll(); - } - - @RpcDeprecated(value = "eventWaitFor", release = "r4") - @Rpc(description = "Blocks until an event with the supplied name occurs. Event is removed from the buffer if removeEvent is True.", - returns = "Map of event properties.") - public Event waitForEvent( - @RpcParameter(name = "eventName") - final String eventName, - @RpcOptional - final Boolean removeEvent, - @RpcParameter(name = "timeout", description = "the maximum time to wait") @RpcOptional Integer timeout) - throws InterruptedException { - return eventWaitFor(eventName, removeEvent, timeout); - } - - @Rpc(description = "Opens up a socket where you can read for events posted") - public int startEventDispatcher( - @RpcParameter(name = "port", description = "Port to use") @RpcDefault("0") @RpcOptional() Integer port) { - if (mEventServer == null) { - if (port == null) { - port = 0; - } - mEventServer = new EventServer(port); - addGlobalEventObserver(mEventServer); - bEventServerRunning = true; - } - return mEventServer.getAddress().getPort(); - } - - @Rpc(description = "sl4a session is shutting down, send terminate event to client.") - public void closeSl4aSession() { - eventClearBuffer(); - postEvent("EventDispatcherShutdown", null); - } - - @Rpc(description = "Stops the event server, you can't read in the port anymore") - public void stopEventDispatcher() throws RuntimeException { - if (bEventServerRunning == true) { - if (mEventServer == null) { - throw new RuntimeException("Not running"); - } - bEventServerRunning = false; - mEventServer.shutdown(); - Log.v(String.format("stopEventDispatcher (%s)", mEventServer)); - removeEventObserver(mEventServer); - mEventServer = null; - } - return; - } - - @Override - public void shutdown() { - - try { - stopEventDispatcher(); - } catch (Exception e) { - Log.e("Exception tearing down event dispatcher", e); - } - mGlobalEventObservers.clear(); - mEventQueue.clear(); - } - - public void addNamedEventObserver(String eventName, EventObserver observer) { - mNamedEventObservers.put(eventName, observer); - } - - public void addGlobalEventObserver(EventObserver observer) { - mGlobalEventObservers.add(observer); - } - - public void removeEventObserver(EventObserver observer) { - mNamedEventObservers.removeAll(observer); - mGlobalEventObservers.remove(observer); - } - - public class BroadcastListener extends android.content.BroadcastReceiver { - private EventFacade mParent; - private boolean mEnQueue; - - public BroadcastListener(EventFacade parent, boolean enqueue) { - mParent = parent; - mEnQueue = enqueue; - } - - @Override - public void onReceive(Context context, Intent intent) { - Bundle data; - if (intent.getExtras() != null) { - data = (Bundle) intent.getExtras().clone(); - } else { - data = new Bundle(); - } - data.putString("action", intent.getAction()); - try { - mParent.eventPost("sl4a", JsonBuilder.build(data).toString(), mEnQueue); - } catch (JSONException e) { - e.printStackTrace(); - } - } - - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManager.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManager.java deleted file mode 100644 index 90de7f9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.Intent; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcMinSdk; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Collection; - -public class FacadeManager extends RpcReceiverManager { - - private final Service mService; - private final Intent mIntent; - private int mSdkLevel; - - public FacadeManager(int sdkLevel, Service service, Intent intent, - Collection<Class<? extends RpcReceiver>> classList) { - super(classList); - mSdkLevel = sdkLevel; - mService = service; - mIntent = intent; - } - - public int getSdkLevel() { - return mSdkLevel; - } - - public Service getService() { - return mService; - } - - public Intent getIntent() { - return mIntent; - } - - @Override - public Object invoke(Class<? extends RpcReceiver> clazz, Method method, Object[] args) - throws Exception { - try { - if (method.isAnnotationPresent(RpcDeprecated.class)) { - String replacedBy = method.getAnnotation(RpcDeprecated.class).value(); - String title = method.getName() + " is deprecated"; - Log.notify(mService, title, title, String.format("Please use %s instead.", replacedBy)); - } else if (method.isAnnotationPresent(RpcMinSdk.class)) { - int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value(); - if (mSdkLevel < requiredSdkLevel) { - throw new Sl4aException(String.format("%s requires API level %d, current level is %d", - method.getName(), requiredSdkLevel, mSdkLevel)); - } - } - return super.invoke(clazz, method, args); - } catch (InvocationTargetException e) { - if (e.getCause() instanceof SecurityException) { - Log.notify(mService, "RPC invoke failed...", mService.getPackageName(), e.getCause() - .getMessage()); - } - throw e; - } - } - - public AndroidFacade.Resources getAndroidFacadeResources() { - return new AndroidFacade.Resources() { - @Override - public int getLogo48() { - // TODO(Alexey): As an alternative, ask application for resource ids. - String packageName = mService.getApplication().getPackageName(); - return mService.getResources().getIdentifier("script_logo_48", "drawable", packageName); - } - }; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManagerFactory.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManagerFactory.java deleted file mode 100644 index e436d03..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/FacadeManagerFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.Intent; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; - -import java.util.HashMap; -import java.util.Collection; -import java.util.Map; - -public class FacadeManagerFactory implements RpcReceiverManagerFactory { - - private final int mSdkLevel; - private final Service mService; - private final Intent mIntent; - private final Collection<Class<? extends RpcReceiver>> mClassList; - private final Map<Integer, RpcReceiverManager> mFacadeManagers; - - public FacadeManagerFactory(int sdkLevel, Service service, Intent intent, - Collection<Class<? extends RpcReceiver>> classList) { - mSdkLevel = sdkLevel; - mService = service; - mIntent = intent; - mClassList = classList; - mFacadeManagers = new HashMap<Integer, RpcReceiverManager>(); - } - - @Override - public FacadeManager create(Integer UID) { - FacadeManager facadeManager = new FacadeManager(mSdkLevel, mService, mIntent, mClassList); - mFacadeManagers.put(UID, facadeManager); - return facadeManager; - } - - @Override - public Map<Integer, RpcReceiverManager> getRpcReceiverManagers() { - return mFacadeManagers; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/LocationFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/LocationFacade.java deleted file mode 100644 index eed244e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/LocationFacade.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.Context; -import android.location.Address; -import android.location.Geocoder; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.os.Bundle; - -import com.google.common.collect.Maps; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.rpc.RpcStartEvent; -import com.googlecode.android_scripting.rpc.RpcStopEvent; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -/** - * This facade exposes the LocationManager related functionality.<br> - * <br> - * <b>Overview</b><br> - * Once activated by 'startLocating' the LocationFacade attempts to return location data collected - * via GPS or the cell network. If neither are available the last known location may be retrieved. - * If both are available the format of the returned data is:<br> - * {u'network': {u'altitude': 0, u'provider': u'network', u'longitude': -0.38509020000000002, - * u'time': 1297079691231L, u'latitude': 52.410557300000001, u'speed': 0, u'accuracy': 75}, u'gps': - * {u'altitude': 51, u'provider': u'gps', u'longitude': -0.38537094593048096, u'time': - * 1297079709000L, u'latitude': 52.41076922416687, u'speed': 0, u'accuracy': 24}}<br> - * If neither are available {} is returned. <br> - * Example (python):<br> - * - * <pre> - * import android, time - * droid = android.Android() - * droid.startLocating() - * time.sleep(15) - * loc = droid.readLocation().result - * if loc = {}: - * loc = getLastKnownLocation().result - * if loc != {}: - * try: - * n = loc['gps'] - * except KeyError: - * n = loc['network'] - * la = n['latitude'] - * lo = n['longitude'] - * address = droid.geocode(la, lo).result - * droid.stopLocating() - * </pre> - * - * The address format is:<br> - * [{u'thoroughfare': u'Some Street', u'locality': u'Some Town', u'sub_admin_area': u'Some Borough', - * u'admin_area': u'Some City', u'feature_name': u'House Numbers', u'country_code': u'GB', - * u'country_name': u'United Kingdom', u'postal_code': u'ST1 1'}] - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Felix Arends (felix.arends@gmail.com) - */ -public class LocationFacade extends RpcReceiver { - private final EventFacade mEventFacade; - private final Service mService; - private final Map<String, Location> mLocationUpdates; - private final LocationManager mLocationManager; - private final Geocoder mGeocoder; - - private final LocationListener mLocationListener = new LocationListener() { - @Override - public synchronized void onLocationChanged(Location location) { - mLocationUpdates.put(location.getProvider(), location); - Map<String, Location> copy = Maps.newHashMap(); - for (Entry<String, Location> entry : mLocationUpdates.entrySet()) { - copy.put(entry.getKey(), entry.getValue()); - } - mEventFacade.postEvent("location", copy); - } - - @Override - public void onProviderDisabled(String provider) { - } - - @Override - public void onProviderEnabled(String provider) { - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) { - } - }; - - public LocationFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mEventFacade = manager.getReceiver(EventFacade.class); - mGeocoder = new Geocoder(mService); - mLocationManager = (LocationManager) mService.getSystemService(Context.LOCATION_SERVICE); - mLocationUpdates = new HashMap<String, Location>(); - } - - @Override - public void shutdown() { - stopLocating(); - } - - @Rpc(description = "Returns availables providers on the phone") - public List<String> locationProviders() { - return mLocationManager.getAllProviders(); - } - - @Rpc(description = "Ask if provider is enabled") - public boolean locationProviderEnabled( - @RpcParameter(name = "provider", description = "Name of location provider") String provider) { - return mLocationManager.isProviderEnabled(provider); - } - - @Rpc(description = "Starts collecting location data.") - @RpcStartEvent("location") - public void startLocating( - @RpcParameter(name = "minDistance", description = "minimum time between updates in milliseconds") @RpcDefault("60000") Integer minUpdateTime, - @RpcParameter(name = "minUpdateDistance", description = "minimum distance between updates in meters") @RpcDefault("30") Integer minUpdateDistance) { - for (String provider : mLocationManager.getAllProviders()) { - mLocationManager.requestLocationUpdates(provider, minUpdateTime, minUpdateDistance, - mLocationListener, mService.getMainLooper()); - } - } - - @Rpc(description = "Returns the current location as indicated by all available providers.", returns = "A map of location information by provider.") - public Map<String, Location> readLocation() { - return mLocationUpdates; - } - - @Rpc(description = "Stops collecting location data.") - @RpcStopEvent("location") - public synchronized void stopLocating() { - mLocationManager.removeUpdates(mLocationListener); - mLocationUpdates.clear(); - } - - @Rpc(description = "Returns the last known location of the device.", returns = "A map of location information by provider.") - public Map<String, Location> getLastKnownLocation() { - Map<String, Location> location = new HashMap<String, Location>(); - for (String provider : mLocationManager.getAllProviders()) { - location.put(provider, mLocationManager.getLastKnownLocation(provider)); - } - return location; - } - - @Rpc(description = "Returns a list of addresses for the given latitude and longitude.", returns = "A list of addresses.") - public List<Address> geocode( - @RpcParameter(name = "latitude") Double latitude, - @RpcParameter(name = "longitude") Double longitude, - @RpcParameter(name = "maxResults", description = "maximum number of results") @RpcDefault("1") Integer maxResults) - throws IOException { - return mGeocoder.getFromLocation(latitude, longitude, maxResults); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/PreferencesFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/PreferencesFacade.java deleted file mode 100644 index 31225ff..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/PreferencesFacade.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.Service; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.IOException; -import java.util.Map; - -/** - * This facade allows access to the Preferences interface. - * - * <br> - * <b>Notes:</b> <br> - * <b>filename</b> - Filename indicates which preference file to refer to. If no filename is - * supplied (the default) then the SharedPreferences uses is the default for the SL4A application.<br> - * <b>prefPutValue</b> - uses "MODE_PRIVATE" when writing to preferences. Save values to the default - * shared preferences is explicitly disallowed.<br> - * <br> - * See <a - * href=http://developer.android.com/reference/java/util/prefs/Preferences.html>Preferences</a> and - * <a href=http://developer.android.com/guide/topics/data/data-storage.html#pref>Shared - * Preferences</a> in the android documentation on how preferences work. - * - * @author Robbie Matthews (rjmatthews62@gmail.com) - */ - -public class PreferencesFacade extends RpcReceiver { - - private Service mService; - - public PreferencesFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - } - - @Rpc(description = "Read a value from shared preferences") - public Object prefGetValue( - @RpcParameter(name = "key") String key, - @RpcParameter(name = "filename", description = "Desired preferences file. If not defined, uses the default Shared Preferences.") @RpcOptional String filename) { - SharedPreferences p = getPref(filename); - return p.getAll().get(key); - } - - @Rpc(description = "Write a value to shared preferences") - public void prefPutValue( - @RpcParameter(name = "key") String key, - @RpcParameter(name = "value") Object value, - @RpcParameter(name = "filename", description = "Desired preferences file. If not defined, uses the default Shared Preferences.") @RpcOptional String filename) - throws IOException { - if (filename == null || filename.equals("")) { - throw new IOException("Can't write to default preferences."); - } - SharedPreferences p = getPref(filename); - Editor e = p.edit(); - if (value instanceof Boolean) { - e.putBoolean(key, (Boolean) value); - } else if (value instanceof Long) { - e.putLong(key, (Long) value); - } else if (value instanceof Integer) { - e.putLong(key, (Integer) value); - } else if (value instanceof Float) { - e.putFloat(key, (Float) value); - } else if (value instanceof Double) { // TODO: Not sure if this is a good idea - e.putFloat(key, ((Double) value).floatValue()); - } else { - e.putString(key, value.toString()); - } - e.commit(); - } - - @Rpc(description = "Get list of Shared Preference Values", returns = "Map of key,value") - public Map<String, ?> prefGetAll( - @RpcParameter(name = "filename", description = "Desired preferences file. If not defined, uses the default Shared Preferences.") @RpcOptional String filename) { - return getPref(filename).getAll(); - } - - private SharedPreferences getPref(String filename) { - if (filename == null || filename.equals("")) { - return PreferenceManager.getDefaultSharedPreferences(mService); - } - return mService.getSharedPreferences(filename, 0); - - } - - @Override - public void shutdown() { - - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/SensorManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/SensorManagerFacade.java deleted file mode 100644 index 6c4c7b7..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/SensorManagerFacade.java +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.os.Bundle; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.rpc.RpcStartEvent; -import com.googlecode.android_scripting.rpc.RpcStopEvent; - -import java.util.Arrays; -import java.util.List; - -/** - * Exposes the SensorManager related functionality. <br> - * <br> - * <b>Guidance notes</b> <br> - * For reasons of economy the sensors on smart phones are usually low cost and, therefore, low - * accuracy (usually represented by 10 bit data). The floating point data values obtained from - * sensor readings have up to 16 decimal places, the majority of which are noise. On many phones the - * accelerometer is limited (by the phone manufacturer) to a maximum reading of 2g. The magnetometer - * (which also provides orientation readings) is strongly affected by the presence of ferrous metals - * and can give large errors in vehicles, on board ship etc. - * - * Following a startSensingTimed(A,B) api call sensor events are entered into the Event Queue (see - * EventFacade). For the A parameter: 1 = All Sensors, 2 = Accelerometer, 3 = Magnetometer and 4 = - * Light. The B parameter is the minimum delay between recordings in milliseconds. To avoid - * duplicate readings the minimum delay should be 20 milliseconds. The light sensor will probably be - * much slower (taking about 1 second to register a change in light level). Note that if the light - * level is constant no sensor events will be registered by the light sensor. - * - * Following a startSensingThreshold(A,B,C) api call sensor events greater than a given threshold - * are entered into the Event Queue. For the A parameter: 1 = Orientation, 2 = Accelerometer, 3 = - * Magnetometer and 4 = Light. The B parameter is the integer value of the required threshold level. - * For orientation sensing the integer threshold value is in milliradians. Since orientation events - * can exceed the threshold value for long periods only crossing and return events are recorded. The - * C parameter is the required axis (XYZ) of the sensor: 0 = No axis, 1 = X, 2 = Y, 3 = X+Y, 4 = Z, - * 5= X+Z, 6 = Y+Z, 7 = X+Y+Z. For orientation X = azimuth, Y = pitch and Z = roll. <br> - * - * <br> - * <b>Example (python)</b> - * - * <pre> - * import android, time - * droid = android.Android() - * droid.startSensingTimed(1, 250) - * time.sleep(1) - * s1 = droid.readSensors().result - * s2 = droid.sensorsGetAccuracy().result - * s3 = droid.sensorsGetLight().result - * s4 = droid.sensorsReadAccelerometer().result - * s5 = droid.sensorsReadMagnetometer().result - * s6 = droid.sensorsReadOrientation().result - * droid.stopSensing() - * </pre> - * - * Returns:<br> - * s1 = {u'accuracy': 3, u'pitch': -0.47323511242866517, u'xmag': 1.75, u'azimuth': - * -0.26701245009899138, u'zforce': 8.4718560000000007, u'yforce': 4.2495484000000001, u'time': - * 1297160391.2820001, u'ymag': -8.9375, u'zmag': -41.0625, u'roll': -0.031366908922791481, - * u'xforce': 0.23154590999999999}<br> - * s2 = 3 (Highest accuracy)<br> - * s3 = None ---(not available on many phones)<br> - * s4 = [0.23154590999999999, 4.2495484000000001, 8.4718560000000007] ----(x, y, z accelerations)<br> - * s5 = [1.75, -8.9375, -41.0625] -----(x, y, z magnetic readings)<br> - * s6 = [-0.26701245009899138, -0.47323511242866517, -0.031366908922791481] ---(azimuth, pitch, roll - * in radians)<br> - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Felix Arends (felix.arends@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - * @author Robbie Mathews (rjmatthews62@gmail.com) - * @author John Karwatzki (jokar49@gmail.com) - */ -public class SensorManagerFacade extends RpcReceiver { - private final EventFacade mEventFacade; - private final SensorManager mSensorManager; - - private volatile Bundle mSensorReadings; - - private volatile Integer mAccuracy; - private volatile Integer mSensorNumber; - private volatile Integer mXAxis = 0; - private volatile Integer mYAxis = 0; - private volatile Integer mZAxis = 0; - private volatile Integer mThreshing = 0; - private volatile Integer mThreshOrientation = 0; - private volatile Integer mXCrossed = 0; - private volatile Integer mYCrossed = 0; - private volatile Integer mZCrossed = 0; - - private volatile Float mThreshold; - private volatile Float mXForce; - private volatile Float mYForce; - private volatile Float mZForce; - - private volatile Float mXMag; - private volatile Float mYMag; - private volatile Float mZMag; - - private volatile Float mLight; - - private volatile Double mAzimuth; - private volatile Double mPitch; - private volatile Double mRoll; - - private volatile Long mLastTime; - private volatile Long mDelayTime; - - private SensorEventListener mSensorListener; - - public SensorManagerFacade(FacadeManager manager) { - super(manager); - mEventFacade = manager.getReceiver(EventFacade.class); - mSensorManager = (SensorManager) manager.getService().getSystemService(Context.SENSOR_SERVICE); - } - - @Rpc(description = "Starts recording sensor data to be available for polling.") - @RpcStartEvent("sensors") - public void startSensingTimed( - @RpcParameter(name = "sensorNumber", description = "1 = All, 2 = Accelerometer, 3 = Magnetometer and 4 = Light") Integer sensorNumber, - @RpcParameter(name = "delayTime", description = "Minimum time between readings in milliseconds") Integer delayTime) { - mSensorNumber = sensorNumber; - if (delayTime < 20) { - delayTime = 20; - } - mDelayTime = (long) (delayTime); - mLastTime = System.currentTimeMillis(); - if (mSensorListener == null) { - mSensorListener = new SensorValuesCollector(); - mSensorReadings = new Bundle(); - switch (mSensorNumber) { - case 1: - for (Sensor sensor : mSensorManager.getSensorList(Sensor.TYPE_ALL)) { - mSensorManager.registerListener(mSensorListener, sensor, - SensorManager.SENSOR_DELAY_FASTEST); - } - break; - case 2: - for (Sensor sensor : mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER)) { - mSensorManager.registerListener(mSensorListener, sensor, - SensorManager.SENSOR_DELAY_FASTEST); - } - break; - case 3: - for (Sensor sensor : mSensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD)) { - mSensorManager.registerListener(mSensorListener, sensor, - SensorManager.SENSOR_DELAY_FASTEST); - } - break; - case 4: - for (Sensor sensor : mSensorManager.getSensorList(Sensor.TYPE_LIGHT)) { - mSensorManager.registerListener(mSensorListener, sensor, - SensorManager.SENSOR_DELAY_FASTEST); - } - } - } - } - - @Rpc(description = "Records to the Event Queue sensor data exceeding a chosen threshold.") - @RpcStartEvent("threshold") - public void startSensingThreshold( - - @RpcParameter(name = "sensorNumber", description = "1 = Orientation, 2 = Accelerometer, 3 = Magnetometer and 4 = Light") Integer sensorNumber, - @RpcParameter(name = "threshold", description = "Threshold level for chosen sensor (integer)") Integer threshold, - @RpcParameter(name = "axis", description = "0 = No axis, 1 = X, 2 = Y, 3 = X+Y, 4 = Z, 5= X+Z, 6 = Y+Z, 7 = X+Y+Z") Integer axis) { - mSensorNumber = sensorNumber; - mXAxis = axis & 1; - mYAxis = axis & 2; - mZAxis = axis & 4; - if (mSensorNumber == 1) { - mThreshing = 0; - mThreshOrientation = 1; - mThreshold = ((float) threshold) / ((float) 1000); - } else { - mThreshing = 1; - mThreshold = (float) threshold; - } - startSensingTimed(mSensorNumber, 20); - } - - @Rpc(description = "Returns the most recently recorded sensor data.") - public Bundle readSensors() { - if (mSensorReadings == null) { - return null; - } - synchronized (mSensorReadings) { - return new Bundle(mSensorReadings); - } - } - - @Rpc(description = "Stops collecting sensor data.") - @RpcStopEvent("sensors") - public void stopSensing() { - mSensorManager.unregisterListener(mSensorListener); - mSensorListener = null; - mSensorReadings = null; - mThreshing = 0; - mThreshOrientation = 0; - } - - @Rpc(description = "Returns the most recently received accuracy value.") - public Integer sensorsGetAccuracy() { - return mAccuracy; - } - - @Rpc(description = "Returns the most recently received light value.") - public Float sensorsGetLight() { - return mLight; - } - - @Rpc(description = "Returns the most recently received accelerometer values.", returns = "a List of Floats [(acceleration on the) X axis, Y axis, Z axis].") - public List<Float> sensorsReadAccelerometer() { - synchronized (mSensorReadings) { - return Arrays.asList(mXForce, mYForce, mZForce); - } - } - - @Rpc(description = "Returns the most recently received magnetic field values.", returns = "a List of Floats [(magnetic field value for) X axis, Y axis, Z axis].") - public List<Float> sensorsReadMagnetometer() { - synchronized (mSensorReadings) { - return Arrays.asList(mXMag, mYMag, mZMag); - } - } - - @Rpc(description = "Returns the most recently received orientation values.", returns = "a List of Doubles [azimuth, pitch, roll].") - public List<Double> sensorsReadOrientation() { - synchronized (mSensorReadings) { - return Arrays.asList(mAzimuth, mPitch, mRoll); - } - } - - @Rpc(description = "Starts recording sensor data to be available for polling.") - @RpcDeprecated(value = "startSensingTimed or startSensingThreshhold", release = "4") - public void startSensing( - @RpcParameter(name = "sampleSize", description = "number of samples for calculating average readings") @RpcDefault("5") Integer sampleSize) { - if (mSensorListener == null) { - startSensingTimed(1, 220); - } - } - - @Override - public void shutdown() { - stopSensing(); - } - - private class SensorValuesCollector implements SensorEventListener { - private final static int MATRIX_SIZE = 9; - - private final RollingAverage mmAzimuth; - private final RollingAverage mmPitch; - private final RollingAverage mmRoll; - - private float[] mmGeomagneticValues; - private float[] mmGravityValues; - private float[] mmR; - private float[] mmOrientation; - - public SensorValuesCollector() { - mmAzimuth = new RollingAverage(); - mmPitch = new RollingAverage(); - mmRoll = new RollingAverage(); - } - - private void postEvent() { - mSensorReadings.putDouble("time", System.currentTimeMillis() / 1000.0); - mEventFacade.postEvent("sensors", mSensorReadings.clone()); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - if (mSensorReadings == null) { - return; - } - synchronized (mSensorReadings) { - mSensorReadings.putInt("accuracy", accuracy); - mAccuracy = accuracy; - - } - } - - @Override - public void onSensorChanged(SensorEvent event) { - if (mSensorReadings == null) { - return; - } - synchronized (mSensorReadings) { - switch (event.sensor.getType()) { - case Sensor.TYPE_ACCELEROMETER: - mXForce = event.values[0]; - mYForce = event.values[1]; - mZForce = event.values[2]; - if (mThreshing == 0) { - mSensorReadings.putFloat("xforce", mXForce); - mSensorReadings.putFloat("yforce", mYForce); - mSensorReadings.putFloat("zforce", mZForce); - if ((mSensorNumber == 2) && (System.currentTimeMillis() > (mDelayTime + mLastTime))) { - mLastTime = System.currentTimeMillis(); - postEvent(); - } - } - if ((mThreshing == 1) && (mSensorNumber == 2)) { - if ((Math.abs(mXForce) > mThreshold) && (mXAxis == 1)) { - mSensorReadings.putFloat("xforce", mXForce); - postEvent(); - } - - if ((Math.abs(mYForce) > mThreshold) && (mYAxis == 2)) { - mSensorReadings.putFloat("yforce", mYForce); - postEvent(); - } - - if ((Math.abs(mZForce) > mThreshold) && (mZAxis == 4)) { - mSensorReadings.putFloat("zforce", mZForce); - postEvent(); - } - } - - mmGravityValues = event.values.clone(); - break; - case Sensor.TYPE_MAGNETIC_FIELD: - mXMag = event.values[0]; - mYMag = event.values[1]; - mZMag = event.values[2]; - if (mThreshing == 0) { - mSensorReadings.putFloat("xMag", mXMag); - mSensorReadings.putFloat("yMag", mYMag); - mSensorReadings.putFloat("zMag", mZMag); - if ((mSensorNumber == 3) && (System.currentTimeMillis() > (mDelayTime + mLastTime))) { - mLastTime = System.currentTimeMillis(); - postEvent(); - } - } - if ((mThreshing == 1) && (mSensorNumber == 3)) { - if ((Math.abs(mXMag) > mThreshold) && (mXAxis == 1)) { - mSensorReadings.putFloat("xforce", mXMag); - postEvent(); - } - if ((Math.abs(mYMag) > mThreshold) && (mYAxis == 2)) { - mSensorReadings.putFloat("yforce", mYMag); - postEvent(); - } - if ((Math.abs(mZMag) > mThreshold) && (mZAxis == 4)) { - mSensorReadings.putFloat("zforce", mZMag); - postEvent(); - } - } - mmGeomagneticValues = event.values.clone(); - break; - case Sensor.TYPE_LIGHT: - mLight = event.values[0]; - if (mThreshing == 0) { - mSensorReadings.putFloat("light", mLight); - if ((mSensorNumber == 4) && (System.currentTimeMillis() > (mDelayTime + mLastTime))) { - mLastTime = System.currentTimeMillis(); - postEvent(); - } - } - if ((mThreshing == 1) && (mSensorNumber == 4)) { - if (mLight > mThreshold) { - mSensorReadings.putFloat("light", mLight); - postEvent(); - } - } - break; - - } - if (mSensorNumber == 1) { - if (mmGeomagneticValues != null && mmGravityValues != null) { - if (mmR == null) { - mmR = new float[MATRIX_SIZE]; - } - if (SensorManager.getRotationMatrix(mmR, null, mmGravityValues, mmGeomagneticValues)) { - if (mmOrientation == null) { - mmOrientation = new float[3]; - } - SensorManager.getOrientation(mmR, mmOrientation); - mmAzimuth.add(mmOrientation[0]); - mmPitch.add(mmOrientation[1]); - mmRoll.add(mmOrientation[2]); - - mAzimuth = mmAzimuth.get(); - mPitch = mmPitch.get(); - mRoll = mmRoll.get(); - if (mThreshOrientation == 0) { - mSensorReadings.putDouble("azimuth", mAzimuth); - mSensorReadings.putDouble("pitch", mPitch); - mSensorReadings.putDouble("roll", mRoll); - if ((mSensorNumber == 1) && (System.currentTimeMillis() > (mDelayTime + mLastTime))) { - mLastTime = System.currentTimeMillis(); - postEvent(); - } - } - if ((mThreshOrientation == 1) && (mSensorNumber == 1)) { - if ((mXAxis == 1) && (mXCrossed == 0)) { - if (Math.abs(mAzimuth) > ((double) mThreshold)) { - mSensorReadings.putDouble("azimuth", mAzimuth); - postEvent(); - mXCrossed = 1; - } - } - if ((mXAxis == 1) && (mXCrossed == 1)) { - if (Math.abs(mAzimuth) < ((double) mThreshold)) { - mSensorReadings.putDouble("azimuth", mAzimuth); - postEvent(); - mXCrossed = 0; - } - } - if ((mYAxis == 2) && (mYCrossed == 0)) { - if (Math.abs(mPitch) > ((double) mThreshold)) { - mSensorReadings.putDouble("pitch", mPitch); - postEvent(); - mYCrossed = 1; - } - } - if ((mYAxis == 2) && (mYCrossed == 1)) { - if (Math.abs(mPitch) < ((double) mThreshold)) { - mSensorReadings.putDouble("pitch", mPitch); - postEvent(); - mYCrossed = 0; - } - } - if ((mZAxis == 4) && (mZCrossed == 0)) { - if (Math.abs(mRoll) > ((double) mThreshold)) { - mSensorReadings.putDouble("roll", mRoll); - postEvent(); - mZCrossed = 1; - } - } - if ((mZAxis == 4) && (mZCrossed == 1)) { - if (Math.abs(mRoll) < ((double) mThreshold)) { - mSensorReadings.putDouble("roll", mRoll); - postEvent(); - mZCrossed = 0; - } - } - } - } - } - } - } - } - } - - static class RollingAverage { - private final int mmSampleSize; - private final double mmData[]; - private int mmIndex = 0; - private boolean mmFilled = false; - private double mmSum = 0.0; - - public RollingAverage() { - mmSampleSize = 5; - mmData = new double[mmSampleSize]; - } - - public void add(double value) { - mmSum -= mmData[mmIndex]; - mmData[mmIndex] = value; - mmSum += mmData[mmIndex]; - ++mmIndex; - mmIndex %= mmSampleSize; - mmFilled = (!mmFilled) ? mmIndex == 0 : mmFilled; - } - - public double get() throws IllegalStateException { - if (!mmFilled && mmIndex == 0) { - throw new IllegalStateException("No values to average."); - } - return (mmFilled) ? (mmSum / mmSampleSize) : (mmSum / mmIndex); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java deleted file mode 100644 index 42e2fd9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/SettingsFacade.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.app.AlarmManager; -import android.app.Service; -import android.app.admin.DevicePolicyManager; -import android.content.Context; -import android.content.Intent; -import android.media.AudioManager; -import android.os.PowerManager; -import android.os.SystemClock; -import android.os.UserHandle; -import android.provider.Settings.SettingNotFoundException; -import android.view.WindowManager; - -import com.android.internal.widget.LockPatternUtils; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Exposes phone settings functionality. - * - * @author Frank Spychalski (frank.spychalski@gmail.com) - */ -public class SettingsFacade extends RpcReceiver { - - private final Service mService; - private final AndroidFacade mAndroidFacade; - private final AudioManager mAudio; - private final PowerManager mPower; - private final AlarmManager mAlarm; - private final LockPatternUtils mLockPatternUtils; - - /** - * Creates a new SettingsFacade. - * - * @param service is the {@link Context} the APIs will run under - */ - public SettingsFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - mAudio = (AudioManager) mService.getSystemService(Context.AUDIO_SERVICE); - mPower = (PowerManager) mService.getSystemService(Context.POWER_SERVICE); - mAlarm = (AlarmManager) mService.getSystemService(Context.ALARM_SERVICE); - mLockPatternUtils = new LockPatternUtils(mService); - } - - @Rpc(description = "Sets the screen timeout to this number of seconds.", - returns = "The original screen timeout.") - public Integer setScreenTimeout(@RpcParameter(name = "value") Integer value) { - Integer oldValue = getScreenTimeout(); - android.provider.Settings.System.putInt(mService.getContentResolver(), - android.provider.Settings.System.SCREEN_OFF_TIMEOUT, value * 1000); - return oldValue; - } - - @Rpc(description = "Returns the current screen timeout in seconds.", - returns = "the current screen timeout in seconds.") - public Integer getScreenTimeout() { - try { - return android.provider.Settings.System.getInt(mService.getContentResolver(), - android.provider.Settings.System.SCREEN_OFF_TIMEOUT) / 1000; - } catch (SettingNotFoundException e) { - return 0; - } - } - - @Rpc(description = "Checks the ringer silent mode setting.", - returns = "True if ringer silent mode is enabled.") - public Boolean checkRingerSilentMode() { - return mAudio.getRingerMode() == AudioManager.RINGER_MODE_SILENT; - } - - @Rpc(description = "Toggles ringer silent mode on and off.", - returns = "True if ringer silent mode is enabled.") - public Boolean toggleRingerSilentMode( - @RpcParameter(name = "enabled") @RpcOptional Boolean enabled) { - if (enabled == null) { - enabled = !checkRingerSilentMode(); - } - mAudio.setRingerMode(enabled ? AudioManager.RINGER_MODE_SILENT - : AudioManager.RINGER_MODE_NORMAL); - return enabled; - } - - @Rpc(description = "Set the ringer to a specified mode") - public void setRingerMode(@RpcParameter(name = "mode") Integer mode) throws Exception { - if (AudioManager.isValidRingerMode(mode)) { - mAudio.setRingerMode(mode); - } else { - throw new Exception("Ringer mode " + mode + " does not exist."); - } - } - - @Rpc(description = "Returns the current ringtone mode.", - returns = "An integer representing the current ringer mode") - public Integer getRingerMode() { - return mAudio.getRingerMode(); - } - - @Rpc(description = "Returns the maximum ringer volume.") - public int getMaxRingerVolume() { - return mAudio.getStreamMaxVolume(AudioManager.STREAM_RING); - } - - @Rpc(description = "Returns the current ringer volume.") - public int getRingerVolume() { - return mAudio.getStreamVolume(AudioManager.STREAM_RING); - } - - @Rpc(description = "Sets the ringer volume.") - public void setRingerVolume(@RpcParameter(name = "volume") Integer volume) { - mAudio.setStreamVolume(AudioManager.STREAM_RING, volume, 0); - } - - @Rpc(description = "Returns the maximum media volume.") - public int getMaxMediaVolume() { - return mAudio.getStreamMaxVolume(AudioManager.STREAM_MUSIC); - } - - @Rpc(description = "Returns the current media volume.") - public int getMediaVolume() { - return mAudio.getStreamVolume(AudioManager.STREAM_MUSIC); - } - - @Rpc(description = "Sets the media volume.") - public void setMediaVolume(@RpcParameter(name = "volume") Integer volume) { - mAudio.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); - } - - @Rpc(description = "Returns the screen backlight brightness.", - returns = "the current screen brightness between 0 and 255") - public Integer getScreenBrightness() { - try { - return android.provider.Settings.System.getInt(mService.getContentResolver(), - android.provider.Settings.System.SCREEN_BRIGHTNESS); - } catch (SettingNotFoundException e) { - return 0; - } - } - - @Rpc(description = "return the system time since boot in nanoseconds") - public long getSystemElapsedRealtimeNanos() { - return SystemClock.elapsedRealtimeNanos(); - } - - @Rpc(description = "Sets the the screen backlight brightness.", - returns = "the original screen brightness.") - public Integer setScreenBrightness( - @RpcParameter(name = "value", description = "brightness value between 0 and 255") Integer value) { - if (value < 0) { - value = 0; - } else if (value > 255) { - value = 255; - } - final int brightness = value; - Integer oldValue = getScreenBrightness(); - android.provider.Settings.System.putInt(mService.getContentResolver(), - android.provider.Settings.System.SCREEN_BRIGHTNESS, brightness); - - FutureActivityTask<Object> task = new FutureActivityTask<Object>() { - @Override - public void onCreate() { - super.onCreate(); - WindowManager.LayoutParams lp = getActivity().getWindow().getAttributes(); - lp.screenBrightness = brightness * 1.0f / 255; - getActivity().getWindow().setAttributes(lp); - setResult(null); - finish(); - } - }; - - FutureActivityTaskExecutor taskExecutor = - ((BaseApplication) mService.getApplication()).getTaskExecutor(); - taskExecutor.execute(task); - - return oldValue; - } - - @Rpc(description = "Returns true if the device is in an interactive state.") - public Boolean isDeviceInteractive() throws Exception { - return mPower.isInteractive(); - } - - @Rpc(description = "Issues a request to put the device to sleep after a delay.") - public void goToSleep(Integer delay) { - mPower.goToSleep(SystemClock.uptimeMillis() + delay); - } - - @Rpc(description = "Issues a request to put the device to sleep right away.") - public void goToSleepNow() { - mPower.goToSleep(SystemClock.uptimeMillis()); - } - - @Rpc(description = "Issues a request to wake the device up right away.") - public void wakeUpNow() { - mPower.wakeUp(SystemClock.uptimeMillis()); - } - - @Rpc(description = "Get Up time of device.", - returns = "Long value of device up time in milliseconds.") - public long getDeviceUpTime() throws Exception { - return SystemClock.elapsedRealtime(); - } - - @Rpc(description = "Set a string password to the device.") - public void setDevicePassword(@RpcParameter(name = "password") String password) { - // mLockPatternUtils.setLockPatternEnabled(true, UserHandle.myUserId()); - mLockPatternUtils.setLockScreenDisabled(false, UserHandle.myUserId()); - mLockPatternUtils.setCredentialRequiredToDecrypt(true); - mLockPatternUtils.saveLockPassword(password, null, - DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, UserHandle.myUserId()); - } - - @Rpc(description = "Disable screen lock password on the device.") - public void disableDevicePassword() { - mLockPatternUtils.clearEncryptionPassword(); - // mLockPatternUtils.setLockPatternEnabled(false, UserHandle.myUserId()); - mLockPatternUtils.setLockScreenDisabled(true, UserHandle.myUserId()); - mLockPatternUtils.setCredentialRequiredToDecrypt(false); - mLockPatternUtils.clearEncryptionPassword(); - mLockPatternUtils.clearLock(UserHandle.myUserId()); - mLockPatternUtils.setLockScreenDisabled(true, UserHandle.myUserId()); - } - - @Rpc(description = "Set the system time in epoch.") - public void setTime(Long currentTime) { - mAlarm.setTime(currentTime); - } - - @Rpc(description = "Set the system time zone.") - public void setTimeZone(@RpcParameter(name = "timeZone") String timeZone) { - mAlarm.setTimeZone(timeZone); - } - - @Rpc(description = "Show Home Screen") - public void showHomeScreen() { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_HOME); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - mAndroidFacade.startActivityIntent(intent, false); - } catch (RuntimeException e) { - Log.d("showHomeScreen RuntimeException" + e); - } catch (Exception e){ - Log.d("showHomeScreen exception" + e); - } - } - - @Override - public void shutdown() { - // Nothing to do yet. - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/SpeechRecognitionFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/SpeechRecognitionFacade.java deleted file mode 100644 index 5409002..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/SpeechRecognitionFacade.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.content.Intent; -import android.speech.RecognizerIntent; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.ArrayList; - -/** - * A facade containing RPC implementations related to the speech-to-text functionality of Android. - * - * @author Felix Arends (felix.arends@gmail.com) - * - */ -public class SpeechRecognitionFacade extends RpcReceiver { - private final AndroidFacade mAndroidFacade; - - /** - * @param activityLauncher - * a helper object that launches activities in a blocking manner - */ - public SpeechRecognitionFacade(FacadeManager manager) { - super(manager); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - } - - @Rpc(description = "Recognizes user's speech and returns the most likely result.", returns = "An empty string in case the speech cannot be recongnized.") - public String recognizeSpeech( - @RpcParameter(name = "prompt", description = "text prompt to show to the user when asking them to speak") @RpcOptional final String prompt, - @RpcParameter(name = "language", description = "language override to inform the recognizer that it should expect speech in a language different than the one set in the java.util.Locale.getDefault()") @RpcOptional final String language, - @RpcParameter(name = "languageModel", description = "informs the recognizer which speech model to prefer (see android.speech.RecognizeIntent)") @RpcOptional final String languageModel) { - final Intent recognitionIntent = - new Intent(android.speech.RecognizerIntent.ACTION_RECOGNIZE_SPEECH); - - // Setup intent parameters (if provided). - if (language != null) { - recognitionIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, ""); - } - if (languageModel != null) { - recognitionIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, ""); - } - if (prompt != null) { - recognitionIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, ""); - } - - // Run the activity an retrieve the result. - final Intent data = mAndroidFacade.startActivityForResult(recognitionIntent); - - if (data.hasExtra(android.speech.RecognizerIntent.EXTRA_RESULTS)) { - // The result consists of an array-list containing one entry for each - // possible result. The most likely result is the first entry. - ArrayList<String> results = - data.getStringArrayListExtra(android.speech.RecognizerIntent.EXTRA_RESULTS); - return results.get(0); - } - - return ""; - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/TextToSpeechFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/TextToSpeechFacade.java deleted file mode 100644 index 26991fb..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/TextToSpeechFacade.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.os.SystemClock; -import android.speech.tts.TextToSpeech; -import android.speech.tts.TextToSpeech.OnInitListener; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.concurrent.CountDownLatch; - -/** - * Provides Text To Speech services - */ - -public class TextToSpeechFacade extends RpcReceiver { - - private final TextToSpeech mTts; - private final CountDownLatch mOnInitLock; - - public TextToSpeechFacade(FacadeManager manager) { - super(manager); - mOnInitLock = new CountDownLatch(1); - mTts = new TextToSpeech(manager.getService(), new OnInitListener() { - @Override - public void onInit(int arg0) { - mOnInitLock.countDown(); - } - }); - } - - @Override - public void shutdown() { - while (mTts.isSpeaking()) { - SystemClock.sleep(100); - } - mTts.shutdown(); - } - - @Rpc(description = "Speaks the provided message via TTS.") - public void ttsSpeak(@RpcParameter(name = "message") String message) throws InterruptedException { - mOnInitLock.await(); - if (message != null) { - mTts.speak(message, TextToSpeech.QUEUE_ADD, null); - } - } - - @Rpc(description = "Returns True if speech is currently in progress.") - public Boolean ttsIsSpeaking() throws InterruptedException { - mOnInitLock.await(); - return mTts.isSpeaking(); - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ToneGeneratorFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ToneGeneratorFacade.java deleted file mode 100644 index c0bfe5f..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ToneGeneratorFacade.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.media.AudioManager; -import android.media.ToneGenerator; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Generate DTMF tones. - * - */ -public class ToneGeneratorFacade extends RpcReceiver { - - private final ToneGenerator mToneGenerator; - - public ToneGeneratorFacade(FacadeManager manager) { - super(manager); - mToneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 100); - } - - @Rpc(description = "Generate DTMF tones for the given phone number.") - public void generateDtmfTones( - @RpcParameter(name = "phoneNumber") String phoneNumber, - @RpcParameter(name = "toneDuration", description = "duration of each tone in milliseconds") @RpcDefault("100") Integer toneDuration) - throws InterruptedException { - try { - for (int i = 0; i < phoneNumber.length(); i++) { - switch (phoneNumber.charAt(i)) { - case '0': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_0); - Thread.sleep(toneDuration); - break; - case '1': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_1); - Thread.sleep(toneDuration); - break; - case '2': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_2); - Thread.sleep(toneDuration); - break; - case '3': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_3); - Thread.sleep(toneDuration); - break; - case '4': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_4); - Thread.sleep(toneDuration); - break; - case '5': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_5); - Thread.sleep(toneDuration); - break; - case '6': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_6); - Thread.sleep(toneDuration); - break; - case '7': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_7); - Thread.sleep(toneDuration); - break; - case '8': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_8); - Thread.sleep(toneDuration); - break; - case '9': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_9); - Thread.sleep(toneDuration); - break; - case '*': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_S); - Thread.sleep(toneDuration); - break; - case '#': - mToneGenerator.startTone(ToneGenerator.TONE_DTMF_P); - Thread.sleep(toneDuration); - break; - default: - throw new RuntimeException("Cannot generate tone for '" + phoneNumber.charAt(i) + "'"); - } - } - } finally { - mToneGenerator.stopTone(); - } - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/WakeLockFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/WakeLockFacade.java deleted file mode 100644 index 966e286..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/WakeLockFacade.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import android.content.Context; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; - -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -/** - * A facade exposing some of the functionality of the PowerManager, in particular wake locks. - * - * @author Felix Arends (felixarends@gmail.com) - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class WakeLockFacade extends RpcReceiver { - - private final static String WAKE_LOCK_TAG = - "com.googlecode.android_scripting.facade.PowerManagerFacade"; - private final PowerManager mmPowerManager; - - private enum WakeLockType { - FULL, PARTIAL, BRIGHT, DIM - } - - private class WakeLockManager { - private final Map<WakeLockType, WakeLock> mmLocks = new HashMap<WakeLockType, WakeLock>(); - - public WakeLockManager(PowerManager mmPowerManager) { - addWakeLock(WakeLockType.PARTIAL, PowerManager.PARTIAL_WAKE_LOCK); - addWakeLock(WakeLockType.FULL, PowerManager.FULL_WAKE_LOCK - | PowerManager.ON_AFTER_RELEASE); - addWakeLock(WakeLockType.BRIGHT, PowerManager.SCREEN_BRIGHT_WAKE_LOCK - | PowerManager.ON_AFTER_RELEASE); - addWakeLock(WakeLockType.DIM, PowerManager.SCREEN_DIM_WAKE_LOCK - | PowerManager.ON_AFTER_RELEASE); - } - - private void addWakeLock(WakeLockType type, int flags) { - WakeLock full = mmPowerManager.newWakeLock(flags, WAKE_LOCK_TAG); - full.setReferenceCounted(false); - mmLocks.put(type, full); - } - - public void acquire(WakeLockType type) { - mmLocks.get(type).acquire(); - for (Entry<WakeLockType, WakeLock> entry : mmLocks.entrySet()) { - if (entry.getKey() != type) { - entry.getValue().release(); - } - } - } - - public void release() { - for (Entry<WakeLockType, WakeLock> entry : mmLocks.entrySet()) { - entry.getValue().release(); - } - } - } - - private final WakeLockManager mManager; - - public WakeLockFacade(FacadeManager manager) { - super(manager); - mmPowerManager = (PowerManager) manager.getService() - .getSystemService(Context.POWER_SERVICE); - mManager = new WakeLockManager(mmPowerManager); - } - - @Rpc(description = "Acquires a full wake lock (CPU on, screen bright, keyboard bright).") - public void wakeLockAcquireFull() { - mManager.acquire(WakeLockType.FULL); - } - - @Rpc(description = "Acquires a partial wake lock (CPU on).") - public void wakeLockAcquirePartial() { - mManager.acquire(WakeLockType.PARTIAL); - } - - @Rpc(description = "Acquires a bright wake lock (CPU on, screen bright).") - public void wakeLockAcquireBright() { - mManager.acquire(WakeLockType.BRIGHT); - } - - @Rpc(description = "Acquires a dim wake lock (CPU on, screen dim).") - public void wakeLockAcquireDim() { - mManager.acquire(WakeLockType.DIM); - } - - @Rpc(description = "Releases the wake lock.") - public void wakeLockRelease() { - mManager.release(); - } - - @Override - public void shutdown() { - wakeLockRelease(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothA2dpFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothA2dpFacade.java deleted file mode 100644 index 4a98d71..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothA2dpFacade.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.List; - -import android.app.Service; -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothA2dpFacade extends RpcReceiver { - static final ParcelUuid[] SINK_UUIDS = { - BluetoothUuid.AudioSink, BluetoothUuid.AdvAudioDist, - }; - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - - private static boolean sIsA2dpReady = false; - private static BluetoothA2dp sA2dpProfile = null; - - public BluetoothA2dpFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothAdapter.getProfileProxy(mService, new A2dpServiceListener(), - BluetoothProfile.A2DP); - } - - class A2dpServiceListener implements BluetoothProfile.ServiceListener { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - sA2dpProfile = (BluetoothA2dp) proxy; - sIsA2dpReady = true; - } - - @Override - public void onServiceDisconnected(int profile) { - sIsA2dpReady = false; - } - } - - public Boolean a2dpConnect(BluetoothDevice device) { - List<BluetoothDevice> sinks = sA2dpProfile.getConnectedDevices(); - if (sinks != null) { - for (BluetoothDevice sink : sinks) { - sA2dpProfile.disconnect(sink); - } - } - return sA2dpProfile.connect(device); - } - - public Boolean a2dpDisconnect(BluetoothDevice device) { - if (sA2dpProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) { - sA2dpProfile.setPriority(device, BluetoothProfile.PRIORITY_ON); - } - return sA2dpProfile.disconnect(device); - } - - /** - * Checks to see if the A2DP profile is ready for use. - * - * @return Returns true if the A2DP Profile is ready. - */ - @Rpc(description = "Is A2dp profile ready.") - public Boolean bluetoothA2dpIsReady() { - return sIsA2dpReady; - } - - /** - * Connect to remote device using the A2DP profile. - * - * @param deviceId the name or mac address of the remote Bluetooth device. - * @return True if connected successfully. - * @throws Exception - */ - @Rpc(description = "Connect to an A2DP device.") - public Boolean bluetoothA2dpConnect( - @RpcParameter(name = "deviceID", description = "Name or MAC address of a bluetooth device.") - String deviceID) - throws Exception { - if (sA2dpProfile == null) - return false; - BluetoothDevice mDevice = BluetoothFacade.getDevice( - BluetoothFacade.DiscoveredDevices, deviceID); - Log.d("Connecting to device " + mDevice.getAliasName()); - return a2dpConnect(mDevice); - } - - /** - * Disconnect a remote device using the A2DP profile. - * - * @param deviceId the name or mac address of the remote Bluetooth device. - * @return True if connected successfully. - * @throws Exception - */ - @Rpc(description = "Disconnect an A2DP device.") - public Boolean bluetoothA2dpDisconnect( - @RpcParameter(name = "deviceID", description = "Name or MAC address of a device.") - String deviceID) - throws Exception { - if (sA2dpProfile == null) - return false; - List<BluetoothDevice> connectedA2dpDevices = sA2dpProfile.getConnectedDevices(); - Log.d("Connected a2dp devices " + connectedA2dpDevices); - BluetoothDevice mDevice = BluetoothFacade.getDevice(connectedA2dpDevices, deviceID); - return a2dpDisconnect(mDevice); - } - - /** - * Get the list of devices connected through the A2DP profile. - * - * @return List of bluetooth devices that are in one of the following states: - * connected, connecting, and disconnecting. - */ - @Rpc(description = "Get all the devices connected through A2DP.") - public List<BluetoothDevice> bluetoothA2dpGetConnectedDevices() { - while (!sIsA2dpReady); - return sA2dpProfile.getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTING}); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothAvrcpFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothAvrcpFacade.java deleted file mode 100644 index 97dcdff..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothAvrcpFacade.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothAvrcpController; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothAvrcpFacade extends RpcReceiver { - static final ParcelUuid[] AVRCP_UUIDS = { - BluetoothUuid.AvrcpTarget, BluetoothUuid.AvrcpController - }; - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - - private static boolean sIsAvrcpReady = false; - private static BluetoothAvrcpController sAvrcpProfile = null; - - public BluetoothAvrcpFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothAdapter.getProfileProxy(mService, new AvrcpServiceListener(), - BluetoothProfile.AVRCP_CONTROLLER); - } - - class AvrcpServiceListener implements BluetoothProfile.ServiceListener { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - sAvrcpProfile = (BluetoothAvrcpController) proxy; - sIsAvrcpReady = true; - } - - @Override - public void onServiceDisconnected(int profile) { - sIsAvrcpReady = false; - } - } - - @Rpc(description = "Is Avrcp profile ready.") - public Boolean bluetoothAvrcpIsReady() { - return sIsAvrcpReady; - } - - @Rpc(description = "Get all the devices connected through AVRCP.") - public List<BluetoothDevice> bluetoothAvrcpGetConnectedDevices() { - if (!sIsAvrcpReady) { - Log.d("AVRCP profile is not ready."); - return null; - } - return sAvrcpProfile.getConnectedDevices(); - } - - @Rpc(description = "Close AVRCP connection.") - public void bluetoothAvrcpDisconnect() throws NoSuchMethodException, - IllegalAccessException, - IllegalArgumentException, - InvocationTargetException { - if (!sIsAvrcpReady) { - Log.d("AVRCP profile is not ready."); - return; - } - Method m = sAvrcpProfile.getClass().getMethod("close"); - m.invoke(sAvrcpProfile); - } - - @Rpc(description = "Send AVRPC passthrough command.") - public void bluetoothAvrcpSendPassThroughCmd( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID, - @RpcParameter(name = "keyCode") - Integer keyCode, - @RpcParameter(name = "keyState") - Integer keyState) throws Exception { - if (!sIsAvrcpReady) { - Log.d("AVRCP profile is not ready."); - return; - } - BluetoothDevice mDevice = BluetoothFacade.getDevice(sAvrcpProfile.getConnectedDevices(), - deviceID); - sAvrcpProfile.sendPassThroughCmd(mDevice, keyCode, keyState); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothBroadcastHelper.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothBroadcastHelper.java deleted file mode 100644 index dc230cb..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothBroadcastHelper.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -public class BluetoothBroadcastHelper { - - private static BroadcastReceiver mListener; - private final Context mContext; - private final BroadcastReceiver mReceiver; - private final String[] mActions = {BluetoothDevice.ACTION_FOUND, - BluetoothDevice.ACTION_UUID, - BluetoothAdapter.ACTION_DISCOVERY_STARTED, - BluetoothAdapter.ACTION_DISCOVERY_FINISHED}; - - public BluetoothBroadcastHelper(Context context, BroadcastReceiver listener) { - mContext = context; - mListener = listener; - mReceiver = new BluetoothReceiver(); - } - - public void startReceiver() { - IntentFilter mIntentFilter = new IntentFilter(); - for(String action : mActions) { - mIntentFilter.addAction(action); - } - mContext.registerReceiver(mReceiver, mIntentFilter); - } - - public static class BluetoothReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - mListener.onReceive(context, intent); - } - } - - public void stopReceiver() { - mContext.unregisterReceiver(mReceiver); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java deleted file mode 100644 index 7fb768f..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import android.app.Service; -import android.bluetooth.BluetoothA2dp; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothInputDevice; -import android.bluetooth.BluetoothUuid; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothConnectionFacade extends RpcReceiver { - - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - private final BluetoothPairingHelper mPairingHelper; - private final Map<String, BroadcastReceiver> listeningDevices; - private final EventFacade mEventFacade; - - private final IntentFilter mDiscoverConnectFilter; - private final IntentFilter mPairingFilter; - private final IntentFilter mBondFilter; - private final IntentFilter mA2dpStateChangeFilter; - private final IntentFilter mHidStateChangeFilter; - private final IntentFilter mHspStateChangeFilter; - - private final Bundle mGoodNews; - private final Bundle mBadNews; - - private BluetoothA2dpFacade mA2dpProfile; - private BluetoothHidFacade mHidProfile; - private BluetoothHspFacade mHspProfile; - - public BluetoothConnectionFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mPairingHelper = new BluetoothPairingHelper(); - // Use a synchronized map to avoid racing problems - listeningDevices = Collections.synchronizedMap(new HashMap<String, BroadcastReceiver>()); - - mEventFacade = manager.getReceiver(EventFacade.class); - mA2dpProfile = manager.getReceiver(BluetoothA2dpFacade.class); - mHidProfile = manager.getReceiver(BluetoothHidFacade.class); - mHspProfile = manager.getReceiver(BluetoothHspFacade.class); - - mDiscoverConnectFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); - mDiscoverConnectFilter.addAction(BluetoothDevice.ACTION_UUID); - mDiscoverConnectFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); - - mPairingFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); - mPairingFilter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); - mPairingFilter.setPriority(999); - - mBondFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED); - mBondFilter.addAction(BluetoothDevice.ACTION_FOUND); - mBondFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); - - mA2dpStateChangeFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); - mHidStateChangeFilter = new IntentFilter(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); - mHspStateChangeFilter = new IntentFilter(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED); - - mGoodNews = new Bundle(); - mGoodNews.putBoolean("Status", true); - mBadNews = new Bundle(); - mBadNews.putBoolean("Status", false); - } - - private void unregisterCachedListener(String listenerId) { - BroadcastReceiver listener = listeningDevices.remove(listenerId); - if (listener != null) { - mService.unregisterReceiver(listener); - } - } - - /** - * Connect to a specific device upon its discovery - */ - public class DiscoverConnectReceiver extends BroadcastReceiver { - private final String mDeviceID; - private BluetoothDevice mDevice; - - /** - * Constructor - * - * @param deviceID Either the device alias name or mac address. - * @param bond If true, bond the device only. - */ - public DiscoverConnectReceiver(String deviceID) { - super(); - mDeviceID = deviceID; - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - // The specified device is found. - if (action.equals(BluetoothDevice.ACTION_FOUND)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (BluetoothFacade.deviceMatch(device, mDeviceID)) { - Log.d("Found device " + device.getAliasName() + " for connection."); - mBluetoothAdapter.cancelDiscovery(); - mDevice = device; - } - // After discovery stops. - } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { - if (mDevice == null) { - Log.d("Device " + mDeviceID + " not discovered."); - mEventFacade.postEvent("Bond" + mDeviceID, mBadNews); - return; - } - boolean status = mDevice.fetchUuidsWithSdp(); - Log.d("Initiated ACL connection: " + status); - } else if (action.equals(BluetoothDevice.ACTION_UUID)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (BluetoothFacade.deviceMatch(device, mDeviceID)) { - Log.d("Initiating connections."); - connectProfile(device, mDeviceID); - mService.unregisterReceiver(listeningDevices.remove("Connect" + mDeviceID)); - } - } - } - } - - /** - * Connect to a specific device upon its discovery - */ - public class DiscoverBondReceiver extends BroadcastReceiver { - private final String mDeviceID; - private BluetoothDevice mDevice = null; - private boolean started = false; - - /** - * Constructor - * - * @param deviceID Either the device alias name or Mac address. - */ - public DiscoverBondReceiver(String deviceID) { - super(); - mDeviceID = deviceID; - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - // The specified device is found. - if (action.equals(BluetoothDevice.ACTION_FOUND)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (BluetoothFacade.deviceMatch(device, mDeviceID)) { - Log.d("Found device " + device.getAliasName() + " for connection."); - mBluetoothAdapter.cancelDiscovery(); - mDevice = device; - } - // After discovery stops. - } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { - if (mDevice == null) { - Log.d("Device " + mDeviceID + " was not discovered."); - mEventFacade.postEvent("Bond", mBadNews); - return; - } - // Attempt to initiate bonding. - if (!started) { - Log.d("Bond with " + mDevice.getAliasName()); - if (mDevice.createBond()) { - started = true; - Log.d("Bonding started."); - } else { - Log.e("Failed to bond with " + mDevice.getAliasName()); - mEventFacade.postEvent("Bond", mBadNews); - mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID)); - } - } - } else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) { - Log.d("Bond state changing."); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if (BluetoothFacade.deviceMatch(device, mDeviceID)) { - int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1); - Log.d("New state is " + state); - if (state == BluetoothDevice.BOND_BONDED) { - Log.d("Bonding with " + mDeviceID + " successful."); - mEventFacade.postEvent("Bond" + mDeviceID, mGoodNews); - mService.unregisterReceiver(listeningDevices.remove("Bond" + mDeviceID)); - } - } - } - } - } - - public class ConnectStateChangeReceiver extends BroadcastReceiver { - private final String mDeviceID; - - public ConnectStateChangeReceiver(String deviceID) { - mDeviceID = deviceID; - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - // Check if received the specified device - if (!BluetoothFacade.deviceMatch(device, mDeviceID)) { - return; - } - if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1); - if (state == BluetoothA2dp.STATE_CONNECTED) { - Bundle a2dpGoodNews = (Bundle) mGoodNews.clone(); - a2dpGoodNews.putString("Type", "a2dp"); - mEventFacade.postEvent("A2dpConnect" + mDeviceID, a2dpGoodNews); - unregisterCachedListener("A2dpConnecting" + mDeviceID); - } else if (state == BluetoothA2dp.STATE_CONNECTING) { - } - }else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_STATE, -1); - if (state == BluetoothInputDevice.STATE_CONNECTED) { - mEventFacade.postEvent("HidConnect" + mDeviceID, mGoodNews); - unregisterCachedListener("HidConnecting" + mDeviceID); - } - } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1); - if (state == BluetoothHeadset.STATE_CONNECTED) { - mEventFacade.postEvent("HspConnect" + mDeviceID, mGoodNews); - unregisterCachedListener("HspConnecting" + mDeviceID); - } - } - } - } - - private void connectProfile(BluetoothDevice device, String deviceID) { - mService.registerReceiver(mPairingHelper, mPairingFilter); - ParcelUuid[] deviceUuids = device.getUuids(); - Log.d("Device uuid is " + deviceUuids); - if (deviceUuids == null) { - mEventFacade.postEvent("Connect", mBadNews); - } - if (BluetoothUuid.containsAnyUuid(BluetoothA2dpFacade.SINK_UUIDS, deviceUuids)) { - Log.d("Connecting to " + device.getAliasName()); - boolean status = mA2dpProfile.a2dpConnect(device); - if (status) { - Log.d("Connecting A2dp..."); - ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID); - mService.registerReceiver(receiver, mA2dpStateChangeFilter); - listeningDevices.put("A2dpConnecting" + deviceID, receiver); - } else { - Log.d("Failed starting A2dp connection."); - Bundle a2dpBadNews = (Bundle) mBadNews.clone(); - a2dpBadNews.putString("Type", "a2dp"); - mEventFacade.postEvent("Connect", a2dpBadNews); - } - } - if (BluetoothUuid.containsAnyUuid(BluetoothHidFacade.UUIDS, deviceUuids)) { - boolean status = mHidProfile.hidConnect(device); - if (status) { - Log.d("Connecting Hid..."); - ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID); - mService.registerReceiver(receiver, mHidStateChangeFilter); - listeningDevices.put("HidConnecting" + deviceID, receiver); - } else { - Log.d("Failed starting Hid connection."); - mEventFacade.postEvent("HidConnect" + deviceID, mBadNews); - } - } - if (BluetoothUuid.containsAnyUuid(BluetoothHspFacade.UUIDS, deviceUuids)) { - boolean status = mHspProfile.hspConnect(device); - if (status) { - Log.d("Connecting Hsp..."); - ConnectStateChangeReceiver receiver = new ConnectStateChangeReceiver(deviceID); - mService.registerReceiver(receiver, mHspStateChangeFilter); - listeningDevices.put("HspConnecting" + deviceID, receiver); - } else { - Log.d("Failed starting Hsp connection."); - mEventFacade.postEvent("HspConnect" + deviceID, mBadNews); - } - } - mService.unregisterReceiver(mPairingHelper); - } - - @Rpc(description = "Start intercepting all bluetooth connection pop-ups.") - public void bluetoothStartPairingHelper() { - mService.registerReceiver(mPairingHelper, mPairingFilter); - } - - @Rpc(description = "Return a list of devices connected through bluetooth") - public List<BluetoothDevice> bluetoothGetConnectedDevices() { - ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>(); - for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) { - if (bd.isConnected()) { - results.add(bd); - } - } - return results; - } - - @Rpc(description = "Return true if a bluetooth device is connected.") - public Boolean bluetoothIsDeviceConnected(String deviceID) { - for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) { - if (BluetoothFacade.deviceMatch(bd, deviceID)) { - return bd.isConnected(); - } - } - return false; - } - - @Rpc(description = "Connect to a specified device once it's discovered.", - returns = "Whether discovery started successfully.") - public Boolean bluetoothDiscoverAndConnect( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) { - mBluetoothAdapter.cancelDiscovery(); - if (listeningDevices.containsKey(deviceID)) { - Log.d("This device is already in the process of discovery and connecting."); - return true; - } - DiscoverConnectReceiver receiver = new DiscoverConnectReceiver(deviceID); - listeningDevices.put("Connect" + deviceID, receiver); - mService.registerReceiver(receiver, mDiscoverConnectFilter); - return mBluetoothAdapter.startDiscovery(); - } - - @Rpc(description = "Bond to a specified device once it's discovered.", - returns = "Whether discovery started successfully. ") - public Boolean bluetoothDiscoverAndBond( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) { - mBluetoothAdapter.cancelDiscovery(); - if (listeningDevices.containsKey(deviceID)) { - Log.d("This device is already in the process of discovery and bonding."); - return true; - } - if (BluetoothFacade.deviceExists(mBluetoothAdapter.getBondedDevices(), deviceID)) { - Log.d("Device " + deviceID + " is already bonded."); - mEventFacade.postEvent("Bond" + deviceID, mGoodNews); - return true; - } - DiscoverBondReceiver receiver = new DiscoverBondReceiver(deviceID); - if (listeningDevices.containsKey("Bond" + deviceID)) { - mService.unregisterReceiver(listeningDevices.remove("Bond" + deviceID)); - } - listeningDevices.put("Bond" + deviceID, receiver); - mService.registerReceiver(receiver, mBondFilter); - Log.d("Start discovery for bonding."); - return mBluetoothAdapter.startDiscovery(); - } - - @Rpc(description = "Unbond a device.", - returns = "Whether the device was successfully unbonded.") - public Boolean bluetoothUnbond( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) throws Exception { - BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), - deviceID); - return mDevice.removeBond(); - } - - @Rpc(description = "Connect to a device that is already bonded.") - public void bluetoothConnectBonded( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) throws Exception { - BluetoothDevice mDevice = BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(), - deviceID); - connectProfile(mDevice, deviceID); - } - - @Override - public void shutdown() { - for(BroadcastReceiver receiver : listeningDevices.values()) { - mService.unregisterReceiver(receiver); - } - listeningDevices.clear(); - mService.unregisterReceiver(mPairingHelper); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothDiscoveryHelper.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothDiscoveryHelper.java deleted file mode 100644 index f625f03..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothDiscoveryHelper.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; - -import java.util.Set; - -import com.googlecode.android_scripting.Log; - -public class BluetoothDiscoveryHelper { - - public static interface BluetoothDiscoveryListener { - public void addBondedDevice(String name, String address); - - public void addDevice(String name, String address); - - public void scanDone(); - } - - private final Context mContext; - private final BluetoothDiscoveryListener mListener; - private final BroadcastReceiver mReceiver; - - public BluetoothDiscoveryHelper(Context context, BluetoothDiscoveryListener listener) { - mContext = context; - mListener = listener; - mReceiver = new BluetoothReceiver(); - } - - private class BluetoothReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - - if (BluetoothDevice.ACTION_FOUND.equals(action)) { - // Get the BluetoothDevice object from the Intent. - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - Log.d("Found device " + device.getAliasName()); - // If it's already paired, skip it, because it's been listed already. - if (device.getBondState() != BluetoothDevice.BOND_BONDED) { - mListener.addDevice(device.getName(), device.getAddress()); - } - } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { - mListener.scanDone(); - } - } - } - - public void startDiscovery() { - BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (bluetoothAdapter.isDiscovering()) { - bluetoothAdapter.cancelDiscovery(); - } - - Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); - for (BluetoothDevice device : pairedDevices) { - mListener.addBondedDevice(device.getName(), device.getAddress()); - } - - IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); - filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); - mContext.registerReceiver(mReceiver, filter); - - if (!bluetoothAdapter.isEnabled()) { - bluetoothAdapter.enable(); - } - - bluetoothAdapter.startDiscovery(); - } - - public void cancel() { - mContext.unregisterReceiver(mReceiver); - mListener.scanDone(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java deleted file mode 100644 index 474e6d9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothFacade.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import android.app.Service; -import android.bluetooth.BluetoothActivityEnergyInfo; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Basic Bluetooth functions. - */ -public class BluetoothFacade extends RpcReceiver { - private final Service mService; - private final BroadcastReceiver mDiscoveryReceiver; - private final IntentFilter discoveryFilter; - private final EventFacade mEventFacade; - private final BluetoothStateReceiver mStateReceiver; - private final BleStateReceiver mBleStateReceiver; - private Map<String, BluetoothConnection> connections = - new HashMap<String, BluetoothConnection>(); - private BluetoothAdapter mBluetoothAdapter; - - public static ConcurrentHashMap<String, BluetoothDevice> DiscoveredDevices; - - public BluetoothFacade(FacadeManager manager) { - super(manager); - mBluetoothAdapter = MainThread.run(manager.getService(), new Callable<BluetoothAdapter>() { - @Override - public BluetoothAdapter call() throws Exception { - return BluetoothAdapter.getDefaultAdapter(); - } - }); - mEventFacade = manager.getReceiver(EventFacade.class); - mService = manager.getService(); - - DiscoveredDevices = new ConcurrentHashMap<String, BluetoothDevice>(); - discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND); - discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); - mDiscoveryReceiver = new DiscoveryCacheReceiver(); - mStateReceiver = new BluetoothStateReceiver(); - mBleStateReceiver = new BleStateReceiver(); - } - - class DiscoveryCacheReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(BluetoothDevice.ACTION_FOUND)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - Log.d("Found device " + device.getAliasName()); - if (!DiscoveredDevices.containsKey(device.getAddress())) { - String name = device.getAliasName(); - if (name != null) { - DiscoveredDevices.put(device.getAliasName(), device); - } - DiscoveredDevices.put(device.getAddress(), device); - } - } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { - mEventFacade.postEvent("BluetoothDiscoveryFinished", new Bundle()); - mService.unregisterReceiver(mDiscoveryReceiver); - } - } - } - - class BluetoothStateReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { - final int state = mBluetoothAdapter.getState(); - Bundle msg = new Bundle(); - if (state == BluetoothAdapter.STATE_ON) { - msg.putString("State", "ON"); - mEventFacade.postEvent("BluetoothStateChangedOn", msg); - mService.unregisterReceiver(mStateReceiver); - } else if(state == BluetoothAdapter.STATE_OFF) { - msg.putString("State", "OFF"); - mEventFacade.postEvent("BluetoothStateChangedOff", msg); - mService.unregisterReceiver(mStateReceiver); - } - msg.clear(); - } - } - } - - class BleStateReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)) { - int state = mBluetoothAdapter.getLeState(); - if (state == BluetoothAdapter.STATE_BLE_ON) { - mEventFacade.postEvent("BleStateChangedOn", new Bundle()); - mService.unregisterReceiver(mBleStateReceiver); - } else if (state == BluetoothAdapter.STATE_OFF) { - mEventFacade.postEvent("BleStateChangedOff", new Bundle()); - mService.unregisterReceiver(mBleStateReceiver); - } - } - } - } - - - public static boolean deviceMatch(BluetoothDevice device, String deviceID) { - return deviceID.equals(device.getAliasName()) || deviceID.equals(device.getAddress()); - } - - public static <T> BluetoothDevice getDevice(ConcurrentHashMap<String, T> devices, String device) - throws Exception { - if (devices.containsKey(device)) { - return (BluetoothDevice) devices.get(device); - } else { - throw new Exception("Can't find device " + device); - } - } - - public static BluetoothDevice getDevice(Collection<BluetoothDevice> devices, String deviceID) - throws Exception { - Log.d("Looking for " + deviceID); - for (BluetoothDevice bd : devices) { - Log.d(bd.getAliasName() + " " + bd.getAddress()); - if (deviceMatch(bd, deviceID)) { - Log.d("Found match " + bd.getAliasName() + " " + bd.getAddress()); - return bd; - } - } - throw new Exception("Can't find device " + deviceID); - } - - public static boolean deviceExists(Collection<BluetoothDevice> devices, String deviceID) { - for (BluetoothDevice bd : devices) { - if (deviceMatch(bd, deviceID)) { - Log.d("Found match " + bd.getAliasName() + " " + bd.getAddress()); - return true; - } - } - return false; - } - - @Rpc(description = "Requests that the device be made connectable.") - public void bluetoothMakeConnectable() { - mBluetoothAdapter - .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE); - } - - @Rpc(description = "Requests that the device be discoverable for Bluetooth connections.") - public void bluetoothMakeDiscoverable( - @RpcParameter(name = "duration", - description = "period of time, in seconds," - + "during which the device should be discoverable") - @RpcDefault("300") - Integer duration) { - Log.d("Making discoverable for " + duration + " seconds.\n"); - mBluetoothAdapter - .setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, duration); - } - - @Rpc(description = "Requests that the device be not discoverable.") - public void bluetoothMakeUndiscoverable() { - Log.d("Making undiscoverable\n"); - mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE); - } - - @Rpc(description = "Queries a remote device for it's name or null if it can't be resolved") - public String bluetoothGetRemoteDeviceName( - @RpcParameter(name = "address", description = "Bluetooth Address For Target Device") - String address) { - try { - BluetoothDevice mDevice; - mDevice = mBluetoothAdapter.getRemoteDevice(address); - return mDevice.getName(); - } catch (Exception e) { - return null; - } - } - - @Rpc(description = "Get local Bluetooth device name") - public String bluetoothGetLocalName() { - return mBluetoothAdapter.getName(); - } - - @Rpc(description = "Sets the Bluetooth visible device name", returns = "true on success") - public boolean bluetoothSetLocalName( - @RpcParameter(name = "name", description = "New local name") - String name) { - return mBluetoothAdapter.setName(name); - } - - @Rpc(description = "Returns the hardware address of the local Bluetooth adapter. ") - public String bluetoothGetLocalAddress() { - return mBluetoothAdapter.getAddress(); - } - - @Rpc(description = "Returns the UUIDs supported by local Bluetooth adapter.") - public ParcelUuid[] bluetoothGetLocalUuids() { - return mBluetoothAdapter.getUuids(); - } - - @Rpc(description = "Gets the scan mode for the local dongle.\r\n" + "Return values:\r\n" - + "\t-1 when Bluetooth is disabled.\r\n" - + "\t0 if non discoverable and non connectable.\r\n" - + "\r1 connectable non discoverable." + "\r3 connectable and discoverable.") - public int bluetoothGetScanMode() { - if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF - || mBluetoothAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF) { - return -1; - } - switch (mBluetoothAdapter.getScanMode()) { - case BluetoothAdapter.SCAN_MODE_NONE: - return 0; - case BluetoothAdapter.SCAN_MODE_CONNECTABLE: - return 1; - case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: - return 3; - default: - return mBluetoothAdapter.getScanMode() - 20; - } - } - - @Rpc(description = "Return the set of BluetoothDevice that are paired to the local adapter.") - public Set<BluetoothDevice> bluetoothGetBondedDevices() { - return mBluetoothAdapter.getBondedDevices(); - } - - @Rpc(description = "Checks Bluetooth state.", returns = "True if Bluetooth is enabled.") - public Boolean bluetoothCheckState() { - return mBluetoothAdapter.isEnabled(); - } - - @Rpc(description = "Toggle Bluetooth on and off.", returns = "True if Bluetooth is enabled.") - public Boolean bluetoothToggleState(@RpcParameter(name = "enabled") - @RpcOptional - Boolean enabled, - @RpcParameter(name = "prompt", - description = "Prompt the user to confirm changing the Bluetooth state.") - @RpcDefault("false") - Boolean prompt) { - mService.registerReceiver(mStateReceiver, - new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - if (enabled == null) { - enabled = !bluetoothCheckState(); - } - if (enabled) { - mBluetoothAdapter.enable(); - } else { - shutdown(); - mBluetoothAdapter.disable(); - } - return enabled; - } - - - @Rpc(description = "Start the remote device discovery process. ", - returns = "true on success, false on error") - public Boolean bluetoothStartDiscovery() { - DiscoveredDevices.clear(); - mService.registerReceiver(mDiscoveryReceiver, discoveryFilter); - return mBluetoothAdapter.startDiscovery(); - } - - @Rpc(description = "Cancel the current device discovery process.", - returns = "true on success, false on error") - public Boolean bluetoothCancelDiscovery() { - try { - mService.unregisterReceiver(mDiscoveryReceiver); - } catch (IllegalArgumentException e) { - Log.d("IllegalArgumentExeption found when trying to unregister reciever"); - } - return mBluetoothAdapter.cancelDiscovery(); - } - - @Rpc(description = "If the local Bluetooth adapter is currently" - + "in the device discovery process.") - public Boolean bluetoothIsDiscovering() { - return mBluetoothAdapter.isDiscovering(); - } - - @Rpc(description = "Get all the discovered bluetooth devices.") - public Collection<BluetoothDevice> bluetoothGetDiscoveredDevices() { - while (bluetoothIsDiscovering()) - ; - return DiscoveredDevices.values(); - } - - @Rpc(description = "Enable or disable the Bluetooth HCI snoop log") - public boolean bluetoothConfigHciSnoopLog( - @RpcParameter(name = "value", description = "enable or disable log") - Boolean value - ) { - return mBluetoothAdapter.configHciSnoopLog(value); - } - - @Rpc(description = "Get Bluetooth controller activity energy info.") - public String bluetoothGetControllerActivityEnergyInfo( - @RpcParameter(name = "value") - Integer value - ) { - BluetoothActivityEnergyInfo energyInfo = mBluetoothAdapter - .getControllerActivityEnergyInfo(value); - while (energyInfo == null) { - energyInfo = mBluetoothAdapter.getControllerActivityEnergyInfo(value); - } - return energyInfo.toString(); - } - - @Rpc(description = "Return true if hardware has entries" + - "available for matching beacons.") - public boolean bluetoothIsHardwareTrackingFiltersAvailable() { - return mBluetoothAdapter.isHardwareTrackingFiltersAvailable(); - } - - @Rpc(description = "Gets the current state of LE.") - public int bluetoothGetLeState() { - return mBluetoothAdapter.getLeState(); - } - - @Rpc(description = "Enables BLE functionalities.") - public boolean bluetoothEnableBLE() { - mService.registerReceiver(mBleStateReceiver, - new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)); - return mBluetoothAdapter.enableBLE(); - } - - @Rpc(description = "Disables BLE functionalities.") - public boolean bluetoothDisableBLE() { - mService.registerReceiver(mBleStateReceiver, - new IntentFilter(BluetoothAdapter.ACTION_BLE_STATE_CHANGED)); - return mBluetoothAdapter.disableBLE(); - } - - @Override - public void shutdown() { - for (Map.Entry<String, BluetoothConnection> entry : connections.entrySet()) { - entry.getValue().stop(); - } - connections.clear(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java deleted file mode 100644 index 8db50f1..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHidFacade.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.List; - -import android.app.Service; -import android.bluetooth.BluetoothInputDevice; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothHidFacade extends RpcReceiver { - public final static ParcelUuid[] UUIDS = { BluetoothUuid.Hid }; - - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - - private static boolean sIsHidReady = false; - private static BluetoothInputDevice sHidProfile = null; - - public BluetoothHidFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothAdapter.getProfileProxy(mService, new HidServiceListener(), - BluetoothProfile.INPUT_DEVICE); - } - - class HidServiceListener implements BluetoothProfile.ServiceListener { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - sHidProfile = (BluetoothInputDevice) proxy; - sIsHidReady = true; - } - - @Override - public void onServiceDisconnected(int profile) { - sIsHidReady = false; - } - } - - public Boolean hidConnect(BluetoothDevice device) { - if (sHidProfile == null) return false; - return sHidProfile.connect(device); - } - - public Boolean hidDisconnect(BluetoothDevice device) { - if (sHidProfile == null) return false; - return sHidProfile.disconnect(device); - } - - @Rpc(description = "Is Hid profile ready.") - public Boolean bluetoothHidIsReady() { - return sIsHidReady; - } - - @Rpc(description = "Connect to an HID device.") - public Boolean bluetoothHidConnect( - @RpcParameter(name = "device", description = "Name or MAC address of a bluetooth device.") - String device) - throws Exception { - if (sHidProfile == null) - return false; - BluetoothDevice mDevice = BluetoothFacade.getDevice(BluetoothFacade.DiscoveredDevices, device); - Log.d("Connecting to device " + mDevice.getAliasName()); - return hidConnect(mDevice); - } - - @Rpc(description = "Disconnect an HID device.") - public Boolean bluetoothHidDisconnect( - @RpcParameter(name = "device", description = "Name or MAC address of a device.") - String device) - throws Exception { - if (sHidProfile == null) - return false; - Log.d("Connected devices: " + sHidProfile.getConnectedDevices()); - BluetoothDevice mDevice = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(), - device); - return hidDisconnect(mDevice); - } - - @Rpc(description = "Get all the devices connected through HID.") - public List<BluetoothDevice> bluetoothHidGetConnectedDevices() { - while (!sIsHidReady); - return sHidProfile.getConnectedDevices(); - } - - @Rpc(description = "Get the connection status of a device.") - public Integer bluetoothHidGetConnectionStatus( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) { - if (sHidProfile == null) { - return BluetoothProfile.STATE_DISCONNECTED; - } - List<BluetoothDevice> deviceList = sHidProfile.getConnectedDevices(); - BluetoothDevice device; - try { - device = BluetoothFacade.getDevice(deviceList, deviceID); - } catch (Exception e) { - return BluetoothProfile.STATE_DISCONNECTED; - } - return sHidProfile.getConnectionState(device); - } - - @Rpc(description = "Send Set_Report command to the connected HID input device.") - public Boolean bluetoothHidSetReport( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID, - @RpcParameter(name = "type") - @RpcDefault(value = "1") - String type, - @RpcParameter(name = "report") - String report) throws Exception { - BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(), - deviceID); - Log.d("type " + type.getBytes()[0]); - return sHidProfile.setReport(device, type.getBytes()[0], report); - } - - @Rpc(description = "Send Get_Report command to the connected HID input device.") - public Boolean bluetoothHidGetReport( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID, - @RpcParameter(name = "type") - @RpcDefault(value = "1") - String type, - @RpcParameter(name = "reportId") - String reportId, - @RpcParameter(name = "buffSize") - Integer buffSize) throws Exception { - BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(), - deviceID); - Log.d("type " + type.getBytes()[0] + "reportId " + reportId.getBytes()[0]); - return sHidProfile.getReport(device, type.getBytes()[0], reportId.getBytes()[0], buffSize); - } - - @Rpc(description = "Send data to a connected HID device.") - public Boolean bluetoothHidSendData( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID, - @RpcParameter(name = "report") - String report) throws Exception { - BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(), - deviceID); - return sHidProfile.sendData(device, report); - } - - @Rpc(description = "Send virtual unplug to a connected HID device.") - public Boolean bluetoothHidVirtualUnplug( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) throws Exception { - BluetoothDevice device = BluetoothFacade.getDevice(sHidProfile.getConnectedDevices(), - deviceID); - return sHidProfile.virtualUnplug(device); - } - - @Rpc(description = "Test byte transfer.") - public byte[] testByte() { - byte[] bts = {0b01,0b10,0b11,0b100}; - return bts; - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHspFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHspFacade.java deleted file mode 100644 index f4514cc..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothHspFacade.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.List; - -import android.app.Service; -import android.bluetooth.BluetoothHeadset; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothHspFacade extends RpcReceiver { - static final ParcelUuid[] UUIDS = { - BluetoothUuid.HSP, BluetoothUuid.Handsfree - }; - - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - - private static boolean sIsHspReady = false; - private static BluetoothHeadset sHspProfile = null; - - public BluetoothHspFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothAdapter.getProfileProxy(mService, new HspServiceListener(), - BluetoothProfile.HEADSET); - } - - class HspServiceListener implements BluetoothProfile.ServiceListener { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - sHspProfile = (BluetoothHeadset) proxy; - sIsHspReady = true; - } - - @Override - public void onServiceDisconnected(int profile) { - sIsHspReady = false; - } - } - - public Boolean hspConnect(BluetoothDevice device) { - if (sHspProfile == null) return false; - return sHspProfile.connect(device); - } - - public Boolean hspDisconnect(BluetoothDevice device) { - if (sHspProfile == null) return false; - return sHspProfile.disconnect(device); - } - - @Rpc(description = "Is Hsp profile ready.") - public Boolean bluetoothHspIsReady() { - return sIsHspReady; - } - - @Rpc(description = "Connect to an HSP device.") - public Boolean bluetoothHspConnect( - @RpcParameter(name = "device", description = "Name or MAC address of a bluetooth device.") - String device) - throws Exception { - if (sHspProfile == null) - return false; - BluetoothDevice mDevice = BluetoothFacade.getDevice(BluetoothFacade.DiscoveredDevices, device); - Log.d("Connecting to device " + mDevice.getAliasName()); - return hspConnect(mDevice); - } - - @Rpc(description = "Disconnect an HSP device.") - public Boolean bluetoothHspDisconnect( - @RpcParameter(name = "device", description = "Name or MAC address of a device.") - String device) - throws Exception { - if (sHspProfile == null) - return false; - Log.d("Connected devices: " + sHspProfile.getConnectedDevices()); - BluetoothDevice mDevice = BluetoothFacade.getDevice(sHspProfile.getConnectedDevices(), - device); - return hspDisconnect(mDevice); - } - - @Rpc(description = "Get all the devices connected through HSP.") - public List<BluetoothDevice> bluetoothHspGetConnectedDevices() { - while (!sIsHspReady); - return sHspProfile.getConnectedDevices(); - } - - @Rpc(description = "Get the connection status of a device.") - public Integer bluetoothHspGetConnectionStatus( - @RpcParameter(name = "deviceID", - description = "Name or MAC address of a bluetooth device.") - String deviceID) { - if (sHspProfile == null) { - return BluetoothProfile.STATE_DISCONNECTED; - } - List<BluetoothDevice> deviceList = sHspProfile.getConnectedDevices(); - BluetoothDevice device; - try { - device = BluetoothFacade.getDevice(deviceList, deviceID); - } catch (Exception e) { - return BluetoothProfile.STATE_DISCONNECTED; - } - return sHspProfile.getConnectionState(device); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeAdvertiseFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeAdvertiseFacade.java deleted file mode 100644 index 3537c9a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeAdvertiseFacade.java +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.Callable; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.le.AdvertiseCallback; -import android.bluetooth.le.AdvertiseData; -import android.bluetooth.le.AdvertiseData.Builder; -import android.bluetooth.le.AdvertiseSettings; -import android.bluetooth.le.BluetoothLeAdvertiser; -import android.os.Bundle; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.ConvertUtils; - -/** - * BluetoothLe Advertise functions. - */ - -public class BluetoothLeAdvertiseFacade extends RpcReceiver { - - private final EventFacade mEventFacade; - private BluetoothAdapter mBluetoothAdapter; - private static int BleAdvertiseCallbackCount; - private static int BleAdvertiseSettingsCount; - private static int BleAdvertiseDataCount; - private final HashMap<Integer, myAdvertiseCallback> mAdvertiseCallbackList; - private final BluetoothLeAdvertiser mAdvertise; - private final Service mService; - private Builder mAdvertiseDataBuilder; - private android.bluetooth.le.AdvertiseSettings.Builder mAdvertiseSettingsBuilder; - private final HashMap<Integer, AdvertiseData> mAdvertiseDataList; - private final HashMap<Integer, AdvertiseSettings> mAdvertiseSettingsList; - - public BluetoothLeAdvertiseFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = MainThread.run(mService, - new Callable<BluetoothAdapter>() { - @Override - public BluetoothAdapter call() throws Exception { - return BluetoothAdapter.getDefaultAdapter(); - } - }); - mEventFacade = manager.getReceiver(EventFacade.class); - mAdvertiseCallbackList = new HashMap<Integer, myAdvertiseCallback>(); - mAdvertise = mBluetoothAdapter.getBluetoothLeAdvertiser(); - mAdvertiseDataList = new HashMap<Integer, AdvertiseData>(); - mAdvertiseSettingsList = new HashMap<Integer, AdvertiseSettings>(); - mAdvertiseDataBuilder = new Builder(); - mAdvertiseSettingsBuilder = new android.bluetooth.le.AdvertiseSettings.Builder(); - } - - /** - * Constructs a myAdvertiseCallback obj and returns its index - * - * @return myAdvertiseCallback.index - */ - @Rpc(description = "Generate a new myAdvertisement Object") - public Integer bleGenBleAdvertiseCallback() { - BleAdvertiseCallbackCount += 1; - int index = BleAdvertiseCallbackCount; - myAdvertiseCallback mCallback = new myAdvertiseCallback(index); - mAdvertiseCallbackList.put(mCallback.index, - mCallback); - return mCallback.index; - } - - /** - * Constructs a AdvertiseData obj and returns its index - * - * @return index - */ - @Rpc(description = "Constructs a new Builder obj for AdvertiseData and returns its index") - public Integer bleBuildAdvertiseData() { - BleAdvertiseDataCount += 1; - int index = BleAdvertiseDataCount; - mAdvertiseDataList.put(index, - mAdvertiseDataBuilder.build()); - mAdvertiseDataBuilder = new Builder(); - return index; - } - - /** - * Constructs a Advertise Settings obj and returns its index - * - * @return index - */ - @Rpc(description = "Constructs a new Builder obj for AdvertiseData and returns its index") - public Integer bleBuildAdvertiseSettings() { - BleAdvertiseSettingsCount += 1; - int index = BleAdvertiseSettingsCount; - mAdvertiseSettingsList.put(index, - mAdvertiseSettingsBuilder.build()); - mAdvertiseSettingsBuilder = new android.bluetooth.le.AdvertiseSettings.Builder(); - return index; - } - - /** - * Stops a ble advertisement - * - * @param index the id of the advertisement to stop advertising on - * @throws Exception - */ - @Rpc(description = "Stops an ongoing ble advertisement") - public void bleStopBleAdvertising( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseCallbackList.get(index) != null) { - Log.d("bluetooth_le mAdvertise " + index); - mAdvertise.stopAdvertising(mAdvertiseCallbackList - .get(index)); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Starts ble advertising - * - * @param callbackIndex The advertisementCallback index - * @param dataIndex the AdvertiseData index - * @param settingsIndex the advertisementsettings index - * @throws Exception - */ - @Rpc(description = "Starts ble advertisement") - public void bleStartBleAdvertising( - @RpcParameter(name = "callbackIndex") - Integer callbackIndex, - @RpcParameter(name = "dataIndex") - Integer dataIndex, - @RpcParameter(name = "settingsIndex") - Integer settingsIndex - ) throws Exception { - AdvertiseData mData = new AdvertiseData.Builder().build(); - AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build(); - if (mAdvertiseDataList.get(dataIndex) != null) { - mData = mAdvertiseDataList.get(dataIndex); - } else { - throw new Exception("Invalid dataIndex input:" + Integer.toString(dataIndex)); - } - if (mAdvertiseSettingsList.get(settingsIndex) != null) { - mSettings = mAdvertiseSettingsList.get(settingsIndex); - } else { - throw new Exception("Invalid settingsIndex input:" + Integer.toString(settingsIndex)); - } - if (mAdvertiseCallbackList.get(callbackIndex) != null) { - Log.d("bluetooth_le starting a background advertisement on callback index: " - + Integer.toString(callbackIndex)); - mAdvertise - .startAdvertising(mSettings, mData, mAdvertiseCallbackList.get(callbackIndex)); - } else { - throw new Exception("Invalid callbackIndex input" + Integer.toString(callbackIndex)); - } - } - - /** - * Starts ble advertising with a scanResponse. ScanResponses are created in the same way - * AdvertiseData is created since they share the same object type. - * - * @param callbackIndex The advertisementCallback index - * @param dataIndex the AdvertiseData index - * @param settingsIndex the advertisementsettings index - * @param scanResponseIndex the scanResponse index - * @throws Exception - */ - @Rpc(description = "Starts ble advertisement") - public void bleStartBleAdvertisingWithScanResponse( - @RpcParameter(name = "callbackIndex") - Integer callbackIndex, - @RpcParameter(name = "dataIndex") - Integer dataIndex, - @RpcParameter(name = "settingsIndex") - Integer settingsIndex, - @RpcParameter(name = "scanResponseIndex") - Integer scanResponseIndex - ) throws Exception { - AdvertiseData mData = new AdvertiseData.Builder().build(); - AdvertiseSettings mSettings = new AdvertiseSettings.Builder().build(); - AdvertiseData mScanResponse = new AdvertiseData.Builder().build(); - - if (mAdvertiseDataList.get(dataIndex) != null) { - mData = mAdvertiseDataList.get(dataIndex); - } else { - throw new Exception("Invalid dataIndex input:" + Integer.toString(dataIndex)); - } - if (mAdvertiseSettingsList.get(settingsIndex) != null) { - mSettings = mAdvertiseSettingsList.get(settingsIndex); - } else { - throw new Exception("Invalid settingsIndex input:" + Integer.toString(settingsIndex)); - } - if (mAdvertiseDataList.get(scanResponseIndex) != null) { - mScanResponse = mAdvertiseDataList.get(scanResponseIndex); - } else { - throw new Exception("Invalid scanResponseIndex input:" - + Integer.toString(settingsIndex)); - } - if (mAdvertiseCallbackList.get(callbackIndex) != null) { - Log.d("bluetooth_le starting a background advertise on callback index: " - + Integer.toString(callbackIndex)); - mAdvertise - .startAdvertising(mSettings, mData, mScanResponse, - mAdvertiseCallbackList.get(callbackIndex)); - } else { - throw new Exception("Invalid callbackIndex input" + Integer.toString(callbackIndex)); - } - } - - /** - * Get ble advertisement settings mode - * - * @param index the advertise settings object to use - * @return the mode of the advertise settings object - * @throws Exception - */ - @Rpc(description = "Get ble advertisement settings mode") - public int bleGetAdvertiseSettingsMode( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseSettingsList.get(index) != null) { - AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); - return mSettings.getMode(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement settings tx power level - * - * @param index the advertise settings object to use - * @return the tx power level of the advertise settings object - * @throws Exception - */ - @Rpc(description = "Get ble advertisement settings tx power level") - public int bleGetAdvertiseSettingsTxPowerLevel( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseSettingsList.get(index) != null) { - AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); - return mSettings.getTxPowerLevel(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement settings isConnectable value - * - * @param index the advertise settings object to use - * @return the boolean value whether the advertisement will indicate - * connectable. - * @throws Exception - */ - @Rpc(description = "Get ble advertisement settings isConnectable value") - public boolean bleGetAdvertiseSettingsIsConnectable( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseSettingsList.get(index) != null) { - AdvertiseSettings mSettings = mAdvertiseSettingsList.get(index); - return mSettings.isConnectable(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement data include tx power level - * - * @param index the advertise data object to use - * @return True if include tx power level, false otherwise - * @throws Exception - */ - @Rpc(description = "Get ble advertisement data include tx power level") - public Boolean bleGetAdvertiseDataIncludeTxPowerLevel( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseDataList.get(index) != null) { - AdvertiseData mData = mAdvertiseDataList.get(index); - return mData.getIncludeTxPowerLevel(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement data manufacturer specific data - * - * @param index the advertise data object to use - * @param manufacturerId the id that corresponds to the manufacturer specific data. - * @return the corresponding manufacturer specific data to the manufacturer id. - * @throws Exception - */ - @Rpc(description = "Get ble advertisement data manufacturer specific data") - public String bleGetAdvertiseDataManufacturerSpecificData( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "manufacturerId") - Integer manufacturerId) throws Exception { - if (mAdvertiseDataList.get(index) != null) { - AdvertiseData mData = mAdvertiseDataList.get(index); - if (mData.getManufacturerSpecificData() != null) { - return ConvertUtils.convertByteArrayToString(mData.getManufacturerSpecificData().get(manufacturerId)); - } else { - throw new Exception("Invalid manufacturerId input:" + Integer.toString(manufacturerId)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - - } - } - - /** - * Get ble advertisement data include device name - * - * @param index the advertise data object to use - * @return the advertisement data's include device name - * @throws Exception - */ - @Rpc(description = "Get ble advertisement include device name") - public Boolean bleGetAdvertiseDataIncludeDeviceName( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseDataList.get(index) != null) { - AdvertiseData mData = mAdvertiseDataList.get(index); - return mData.getIncludeDeviceName(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement Service Data - * - * @param index the advertise data object to use - * @param serviceUuid the uuid corresponding to the service data. - * @return the advertisement data's service data - * @throws Exception - */ - @Rpc(description = "Get ble advertisement Service Data") - public String bleGetAdvertiseDataServiceData( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "serviceUuid") - String serviceUuid) throws Exception { - ParcelUuid uuidKey = ParcelUuid.fromString(serviceUuid); - if (mAdvertiseDataList.get(index) != null) { - AdvertiseData mData = mAdvertiseDataList.get(index); - if (mData.getServiceData().containsKey(uuidKey)) { - return ConvertUtils.convertByteArrayToString(mData.getServiceData().get(uuidKey)); - } else { - throw new Exception("Invalid serviceUuid input:" + serviceUuid); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ble advertisement Service Uuids - * - * @param index the advertise data object to use - * @return the advertisement data's Service Uuids - * @throws Exception - */ - @Rpc(description = "Get ble advertisement Service Uuids") - public List<ParcelUuid> bleGetAdvertiseDataServiceUuids( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mAdvertiseDataList.get(index) != null) { - AdvertiseData mData = mAdvertiseDataList.get(index); - return mData.getServiceUuids(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Set ble advertisement data service uuids - * - * @param uuidList - * @throws Exception - */ - @Rpc(description = "Set ble advertisement data service uuids") - public void bleSetAdvertiseDataSetServiceUuids( - @RpcParameter(name = "uuidList") - String[] uuidList - ) { - for (String uuid : uuidList) { - mAdvertiseDataBuilder.addServiceUuid(ParcelUuid.fromString(uuid)); - } - } - - /** - * Set ble advertise data service uuids - * - * @param serviceDataUuid - * @param serviceData - * @throws Exception - */ - @Rpc(description = "Set ble advertise data service uuids") - public void bleAddAdvertiseDataServiceData( - @RpcParameter(name = "serviceDataUuid") - String serviceDataUuid, - @RpcParameter(name = "serviceData") - String serviceData - ) { - mAdvertiseDataBuilder.addServiceData( - ParcelUuid.fromString(serviceDataUuid), - ConvertUtils.convertStringToByteArray(serviceData)); - } - - /** - * Set ble advertise data manufacturer id - * - * @param manufacturerId the manufacturer id to set - * @param manufacturerSpecificData the manufacturer specific data to set - * @throws Exception - */ - @Rpc(description = "Set ble advertise data manufacturerId") - public void bleAddAdvertiseDataManufacturerId( - @RpcParameter(name = "manufacturerId") - Integer manufacturerId, - @RpcParameter(name = "manufacturerSpecificData") - String manufacturerSpecificData - ) { - mAdvertiseDataBuilder.addManufacturerData(manufacturerId, - ConvertUtils.convertStringToByteArray(manufacturerSpecificData)); - } - - /** - * Set ble advertise settings advertise mode - * - * @param advertiseMode - * @throws Exception - */ - @Rpc(description = "Set ble advertise settings advertise mode") - public void bleSetAdvertiseSettingsAdvertiseMode( - @RpcParameter(name = "advertiseMode") - Integer advertiseMode - ) { - mAdvertiseSettingsBuilder.setAdvertiseMode(advertiseMode); - } - - /** - * Set ble advertise settings tx power level - * - * @param txPowerLevel the tx power level to set - * @throws Exception - */ - @Rpc(description = "Set ble advertise settings tx power level") - public void bleSetAdvertiseSettingsTxPowerLevel( - @RpcParameter(name = "txPowerLevel") - Integer txPowerLevel - ) { - mAdvertiseSettingsBuilder.setTxPowerLevel(txPowerLevel); - } - - /** - * Set ble advertise settings the isConnectable value - * - * @param type the isConnectable value - * @throws Exception - */ - @Rpc(description = "Set ble advertise settings isConnectable value") - public void bleSetAdvertiseSettingsIsConnectable( - @RpcParameter(name = "value") - Boolean value - ) { - mAdvertiseSettingsBuilder.setConnectable(value); - } - - /** - * Set ble advertisement data include tx power level - * - * @param includeTxPowerLevel boolean whether to include the tx power level or not in the - * advertisement - */ - @Rpc(description = "Set ble advertisement data include tx power level") - public void bleSetAdvertiseDataIncludeTxPowerLevel( - @RpcParameter(name = "includeTxPowerLevel") - Boolean includeTxPowerLevel - ) { - mAdvertiseDataBuilder.setIncludeTxPowerLevel(includeTxPowerLevel); - } - - /** - * Set ble advertisement settings set timeout - * - * @param timeoutSeconds Limit advertising to a given amount of time. - */ - @Rpc(description = "Set ble advertisement data include tx power level") - public void bleSetAdvertiseSettingsTimeout( - @RpcParameter(name = "timeoutSeconds") - Integer timeoutSeconds - ) { - mAdvertiseSettingsBuilder.setTimeout(timeoutSeconds); - } - - /** - * Set ble advertisement data include device name - * - * @param includeDeviceName boolean whether to include device name or not in the - * advertisement - */ - @Rpc(description = "Set ble advertisement data include device name") - public void bleSetAdvertiseDataIncludeDeviceName( - @RpcParameter(name = "includeDeviceName") - Boolean includeDeviceName - ) { - mAdvertiseDataBuilder.setIncludeDeviceName(includeDeviceName); - } - - private class myAdvertiseCallback extends AdvertiseCallback { - public Integer index; - private final Bundle mResults; - String mEventType; - - public myAdvertiseCallback(int idx) { - index = idx; - mEventType = "BleAdvertise"; - mResults = new Bundle(); - } - - @Override - public void onStartSuccess(AdvertiseSettings settingsInEffect) { - Log.d("bluetooth_le_advertisement onSuccess " + mEventType + " " - + index); - mResults.putString("Type", "onSuccess"); - mResults.putParcelable("SettingsInEffect", settingsInEffect); - mEventFacade.postEvent(mEventType + index + "onSuccess", mResults.clone()); - mResults.clear(); - } - - @Override - public void onStartFailure(int errorCode) { - String errorString = "UNKNOWN_ERROR_CODE"; - if (errorCode == AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED) { - errorString = "ADVERTISE_FAILED_ALREADY_STARTED"; - } else if (errorCode == AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE) { - errorString = "ADVERTISE_FAILED_DATA_TOO_LARGE"; - } else if (errorCode == AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED) { - errorString = "ADVERTISE_FAILED_FEATURE_UNSUPPORTED"; - } else if (errorCode == AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR) { - errorString = "ADVERTISE_FAILED_INTERNAL_ERROR"; - } else if (errorCode == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) { - errorString = "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS"; - } - Log.d("bluetooth_le_advertisement onFailure " + mEventType + " " - + index + " error " + errorString); - mResults.putString("Type", "onFailure"); - mResults.putInt("ErrorCode", errorCode); - mResults.putString("Error", errorString); - mEventFacade.postEvent(mEventType + index + "onFailure", - mResults.clone()); - mResults.clear(); - } - } - - @Override - public void shutdown() { - if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { - for (myAdvertiseCallback mAdvertise : mAdvertiseCallbackList - .values()) { - if (mAdvertise != null) { - try{ - mBluetoothAdapter.getBluetoothLeAdvertiser() - .stopAdvertising(mAdvertise); - } catch (NullPointerException e) { - Log.e("Failed to stop ble advertising.", e); - } - } - } - } - mAdvertiseCallbackList.clear(); - mAdvertiseSettingsList.clear(); - mAdvertiseDataList.clear(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java deleted file mode 100644 index 7ae78a2..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothLeScanFacade.java +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.Callable; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.le.BluetoothLeScanner; -import android.bluetooth.le.ScanCallback; -import android.bluetooth.le.ScanFilter; -import android.bluetooth.BluetoothAdapter.LeScanCallback; -import android.bluetooth.le.ScanFilter.Builder; -import android.bluetooth.le.ScanResult; -import android.bluetooth.le.ScanSettings; -import android.os.Bundle; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.ConvertUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * BluetoothLe Scan functions. - */ - -public class BluetoothLeScanFacade extends RpcReceiver { - - private final EventFacade mEventFacade; - - private BluetoothAdapter mBluetoothAdapter; - private static int ScanCallbackCount; - private static int FilterListCount; - private static int LeScanCallbackCount; - private static int ScanSettingsCount; - private final Service mService; - private final BluetoothLeScanner mScanner; - private android.bluetooth.le.ScanSettings.Builder mScanSettingsBuilder; - private Builder mScanFilterBuilder; - private final HashMap<Integer, myScanCallback> mScanCallbackList; - private final HashMap<Integer, myLeScanCallback> mLeScanCallbackList; - private final HashMap<Integer, ArrayList<ScanFilter>> mScanFilterList; - private final HashMap<Integer, ScanSettings> mScanSettingsList; - - public BluetoothLeScanFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = MainThread.run(mService, - new Callable<BluetoothAdapter>() { - @Override - public BluetoothAdapter call() throws Exception { - return BluetoothAdapter.getDefaultAdapter(); - } - }); - mScanner = mBluetoothAdapter.getBluetoothLeScanner(); - mEventFacade = manager.getReceiver(EventFacade.class); - mScanFilterList = new HashMap<Integer, ArrayList<ScanFilter>>(); - mLeScanCallbackList = new HashMap<Integer, myLeScanCallback>(); - mScanSettingsList = new HashMap<Integer, ScanSettings>(); - mScanCallbackList = new HashMap<Integer, myScanCallback>(); - mScanFilterBuilder = new Builder(); - mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder(); - } - - /** - * Constructs a myScanCallback obj and returns its index - * - * @return Integer myScanCallback.index - */ - @Rpc(description = "Generate a new myScanCallback Object") - public Integer bleGenScanCallback() { - ScanCallbackCount += 1; - int index = ScanCallbackCount; - myScanCallback mScan = new myScanCallback(index); - mScanCallbackList.put(mScan.index, mScan); - return mScan.index; - } - - /** - * Constructs a myLeScanCallback obj and returns its index - * - * @return Integer myScanCallback.index - */ - @Rpc(description = "Generate a new myScanCallback Object") - public Integer bleGenLeScanCallback() { - LeScanCallbackCount += 1; - int index = LeScanCallbackCount; - myLeScanCallback mScan = new myLeScanCallback(index); - mLeScanCallbackList.put(mScan.index, mScan); - return mScan.index; - } - - /** - * Constructs a new filter list array and returns its index - * - * @return Integer index - */ - @Rpc(description = "Generate a new Filter list") - public Integer bleGenFilterList() { - FilterListCount += 1; - int index = FilterListCount; - mScanFilterList.put(index, new ArrayList<ScanFilter>()); - return index; - } - - /** - * Constructs a new filter list array and returns its index - * - * @return Integer index - */ - @Rpc(description = "Generate a new Filter list") - public Integer bleBuildScanFilter( - @RpcParameter(name = "filterIndex") - Integer filterIndex - ) { - mScanFilterList.get(filterIndex).add(mScanFilterBuilder.build()); - mScanFilterBuilder = new Builder(); - return mScanFilterList.get(filterIndex).size()-1; - } - - /** - * Constructs a new scan setting and returns its index - * - * @return Integer index - */ - @Rpc(description = "Generate a new scan settings Object") - public Integer bleBuildScanSetting() { - ScanSettingsCount += 1; - int index = ScanSettingsCount; - mScanSettingsList.put(index, mScanSettingsBuilder.build()); - mScanSettingsBuilder = new android.bluetooth.le.ScanSettings.Builder(); - return index; - } - - /** - * Stops a ble scan - * - * @param index the id of the myScan whose ScanCallback to stop - * @throws Exception - */ - @Rpc(description = "Stops an ongoing ble advertisement scan") - public void bleStopBleScan( - @RpcParameter(name = "index") - Integer index) throws Exception { - Log.d("bluetooth_le_scan mScanCallback " + index); - if (mScanCallbackList.get(index) != null) { - myScanCallback mScanCallback = mScanCallbackList.get(index); - mScanner.stopScan(mScanCallback); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Stops a classic ble scan - * - * @param index the id of the myScan whose LeScanCallback to stop - * @throws Exception - */ - @Rpc(description = "Stops an ongoing classic ble scan") - public void bleStopClassicBleScan( - @RpcParameter(name = "index") - Integer index) throws Exception { - Log.d("bluetooth_le_scan mLeScanCallback " + index); - if (mLeScanCallbackList.get(index) != null) { - myLeScanCallback mLeScanCallback = mLeScanCallbackList.get(index); - mBluetoothAdapter.stopLeScan(mLeScanCallback); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Starts a ble scan - * - * @param index the id of the myScan whose ScanCallback to start - * @throws Exception - */ - @Rpc(description = "Starts a ble advertisement scan") - public void bleStartBleScan( - @RpcParameter(name = "filterListIndex") - Integer filterListIndex, - @RpcParameter(name = "scanSettingsIndex") - Integer scanSettingsIndex, - @RpcParameter(name = "callbackIndex") - Integer callbackIndex - ) throws Exception { - Log.d("bluetooth_le_scan starting a background scan"); - ArrayList<ScanFilter> mScanFilters = new ArrayList<ScanFilter>(); - mScanFilters.add(new ScanFilter.Builder().build()); - ScanSettings mScanSettings = new ScanSettings.Builder().build(); - if (mScanFilterList.get(filterListIndex) != null) { - mScanFilters = mScanFilterList.get(filterListIndex); - } else { - throw new Exception("Invalid filterListIndex input:" - + Integer.toString(filterListIndex)); - } - if (mScanSettingsList.get(scanSettingsIndex) != null) { - mScanSettings = mScanSettingsList.get(scanSettingsIndex); - } else if (!mScanSettingsList.isEmpty()) { - throw new Exception("Invalid scanSettingsIndex input:" - + Integer.toString(scanSettingsIndex)); - } - if (mScanCallbackList.get(callbackIndex) != null) { - mScanner.startScan(mScanFilters, mScanSettings, mScanCallbackList.get(callbackIndex)); - } else { - throw new Exception("Invalid filterListIndex input:" - + Integer.toString(filterListIndex)); - } - } - - /** - * Starts a classic ble scan - * - * @param index the id of the myScan whose ScanCallback to start - * @throws Exception - */ - @Rpc(description = "Starts a classic ble advertisement scan") - public boolean bleStartClassicBleScan( - @RpcParameter(name = "leCallbackIndex") - Integer leCallbackIndex - ) throws Exception { - Log.d("bluetooth_le_scan starting a background scan"); - boolean result = false; - if (mLeScanCallbackList.get(leCallbackIndex) != null) { - result = mBluetoothAdapter.startLeScan(mLeScanCallbackList.get(leCallbackIndex)); - } else { - throw new Exception("Invalid leCallbackIndex input:" - + Integer.toString(leCallbackIndex)); - } - return result; - } - - /** - * Starts a classic ble scan with service Uuids - * - * @param index the id of the myScan whose ScanCallback to start - * @throws Exception - */ - @Rpc(description = "Starts a classic ble advertisement scan with service Uuids") - public boolean bleStartClassicBleScanWithServiceUuids( - @RpcParameter(name = "leCallbackIndex") - Integer leCallbackIndex, - @RpcParameter(name = "serviceUuids") - String[] serviceUuidList - ) throws Exception { - Log.d("bluetooth_le_scan starting a background scan"); - UUID[] serviceUuids = new UUID[serviceUuidList.length]; - for (int i = 0; i < serviceUuidList.length; i++) { - serviceUuids[i] = UUID.fromString(serviceUuidList[i]); - } - boolean result = false; - if (mLeScanCallbackList.get(leCallbackIndex) != null) { - result = mBluetoothAdapter.startLeScan(serviceUuids, - mLeScanCallbackList.get(leCallbackIndex)); - System.out.println(result); - } else { - throw new Exception("Invalid leCallbackIndex input:" - + Integer.toString(leCallbackIndex)); - } - System.out.println(result); - return result; - } - - /** - * Trigger onBatchScanResults - * - * @throws Exception - */ - @Rpc(description = "Gets the results of the ble ScanCallback") - public void bleFlushPendingScanResults( - @RpcParameter(name = "callbackIndex") - Integer callbackIndex - ) throws Exception { - if (mScanCallbackList.get(callbackIndex) != null) { - mBluetoothAdapter - .getBluetoothLeScanner().flushPendingScanResults( - mScanCallbackList.get(callbackIndex)); - } else { - throw new Exception("Invalid callbackIndex input:" - + Integer.toString(callbackIndex)); - } - } - - /** - * Set scanSettings for ble scan. Note: You have to set all variables at once. - * - * @param callbackType Bluetooth LE scan callback type - * @param reportDelaySeconds Time of delay for reporting the scan result - * @param scanMode Bluetooth LE scan mode. - * @param scanResultType Bluetooth LE scan result type - * @throws Exception - */ - - /** - * Set the scan setting's callback type - * @param callbackType Bluetooth LE scan callback type - */ - @Rpc(description = "Set the scan setting's callback type") - public void bleSetScanSettingsCallbackType( - @RpcParameter(name = "callbackType") - Integer callbackType) { - mScanSettingsBuilder.setCallbackType(callbackType); - } - - /** - * Set the scan setting's report delay millis - * @param reportDelayMillis Time of delay for reporting the scan result - */ - @Rpc(description = "Set the scan setting's report delay millis") - public void bleSetScanSettingsReportDelayMillis( - @RpcParameter(name = "reportDelayMillis") - Long reportDelayMillis) { - mScanSettingsBuilder.setReportDelay(reportDelayMillis); - } - - /** - * Set the scan setting's scan mode - * @param scanMode Bluetooth LE scan mode. - */ - @Rpc(description = "Set the scan setting's scan mode") - public void bleSetScanSettingsScanMode( - @RpcParameter(name = "scanMode") - Integer scanMode) { - mScanSettingsBuilder.setScanMode(scanMode); - } - - /** - * Set the scan setting's scan result type - * @param scanResultType Bluetooth LE scan result type - */ - @Rpc(description = "Set the scan setting's scan result type") - public void bleSetScanSettingsResultType( - @RpcParameter(name = "scanResultType") - Integer scanResultType) { - mScanSettingsBuilder.setScanResultType(scanResultType); - } - /** - * Get ScanSetting's callback type - * - * @param index the ScanSetting object to use - * @return the ScanSetting's callback type - * @throws Exception - */ - @Rpc(description = "Get ScanSetting's callback type") - public Integer bleGetScanSettingsCallbackType( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mScanSettingsList.get(index) != null) { - ScanSettings mScanSettings = mScanSettingsList.get(index); - return mScanSettings.getCallbackType(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanSetting's report delay in milli seconds - * - * @param index the ScanSetting object to useSystemClock - * @return the ScanSetting's report delay in milliseconds - * @throws Exception - */ - @Rpc(description = "Get ScanSetting's report delay milliseconds") - public Long bleGetScanSettingsReportDelayMillis( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mScanSettingsList.get(index) != null) { - ScanSettings mScanSettings = mScanSettingsList.get(index); - return mScanSettings.getReportDelayMillis(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanSetting's scan mode - * - * @param index the ScanSetting object to use - * @return the ScanSetting's scan mode - * @throws Exception - */ - @Rpc(description = "Get ScanSetting's scan mode") - public Integer bleGetScanSettingsScanMode( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mScanSettingsList.get(index) != null) { - ScanSettings mScanSettings = mScanSettingsList.get(index); - return mScanSettings.getScanMode(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanSetting's scan result type - * - * @param index the ScanSetting object to use - * @return the ScanSetting's scan result type - * @throws Exception - */ - @Rpc(description = "Get ScanSetting's scan result type") - public Integer bleGetScanSettingsScanResultType( - @RpcParameter(name = "index") - Integer index) throws Exception { - if (mScanSettingsList.get(index) != null) { - ScanSettings mScanSettings = mScanSettingsList.get(index); - return mScanSettings.getScanResultType(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's Manufacturer Id - * - * @param index the ScanFilter object to use - * @return the ScanFilter's manufacturer id - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's Manufacturer Id") - public Integer bleGetScanFilterManufacturerId( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return mScanFilterList.get(index) - .get(filterIndex).getManufacturerId(); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's device address - * - * @param index the ScanFilter object to use - * @return the ScanFilter's device address - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's device address") - public String bleGetScanFilterDeviceAddress( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return mScanFilterList.get(index).get(filterIndex).getDeviceAddress(); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's device name - * - * @param index the ScanFilter object to use - * @return the ScanFilter's device name - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's device name") - public String bleGetScanFilterDeviceName( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return mScanFilterList.get(index).get(filterIndex).getDeviceName(); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's manufacturer data - * - * @param index the ScanFilter object to use - * @return the ScanFilter's manufacturer data - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's manufacturer data") - public String bleGetScanFilterManufacturerData( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return ConvertUtils.convertByteArrayToString(mScanFilterList.get(index) - .get(filterIndex).getManufacturerData()); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's manufacturer data mask - * - * @param index the ScanFilter object to use - * @return the ScanFilter's manufacturer data mask - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's manufacturer data mask") - public String bleGetScanFilterManufacturerDataMask( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return ConvertUtils.convertByteArrayToString(mScanFilterList.get(index) - .get(filterIndex).getManufacturerDataMask()); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's service data - * - * @param index the ScanFilter object to use - * @return the ScanFilter's service data - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's service data") - public String bleGetScanFilterServiceData( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return ConvertUtils.convertByteArrayToString(mScanFilterList - .get(index).get(filterIndex).getServiceData()); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's service data mask - * - * @param index the ScanFilter object to use - * @return the ScanFilter's service data mask - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's service data mask") - public String bleGetScanFilterServiceDataMask( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - return ConvertUtils.convertByteArrayToString(mScanFilterList.get(index) - .get(filterIndex).getServiceDataMask()); - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's service uuid - * - * @param index the ScanFilter object to use - * @return the ScanFilter's service uuid - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's service uuid") - public String bleGetScanFilterServiceUuid( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - if (mScanFilterList.get(index).get(filterIndex).getServiceUuid() != null) { - return mScanFilterList.get(index).get(filterIndex).getServiceUuid().toString(); - } else { - throw new Exception("No Service Uuid set for filter:" - + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get ScanFilter's service uuid mask - * - * @param index the ScanFilter object to use - * @return the ScanFilter's service uuid mask - * @throws Exception - */ - @Rpc(description = "Get ScanFilter's service uuid mask") - public String bleGetScanFilterServiceUuidMask( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "filterIndex") - Integer filterIndex) - throws Exception { - if (mScanFilterList.get(index) != null) { - if (mScanFilterList.get(index).get(filterIndex) != null) { - if (mScanFilterList.get(index).get(filterIndex).getServiceUuidMask() != null) { - return mScanFilterList.get(index).get(filterIndex).getServiceUuidMask() - .toString(); - } else { - throw new Exception("No Service Uuid Mask set for filter:" - + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid filterIndex input:" + Integer.toString(filterIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Add filter "macAddress" to existing ScanFilter - * - * @param macAddress the macAddress to filter against - * @throws Exception - */ - @Rpc(description = "Add filter \"macAddress\" to existing ScanFilter") - public void bleSetScanFilterDeviceAddress( - @RpcParameter(name = "macAddress") - String macAddress - ) { - mScanFilterBuilder.setDeviceAddress(macAddress); - } - - /** - * Add filter "manufacturereDataId and/or manufacturerData" to existing ScanFilter - * - * @param manufacturerDataId the manufacturer data id to filter against - * @param manufacturerDataMask the manufacturere data mask to filter against - * @throws Exception - */ - @Rpc(description = "Add filter \"manufacturereDataId and/or manufacturerData\" to existing ScanFilter") - public void bleSetScanFilterManufacturerData( - @RpcParameter(name = "manufacturerDataId") - Integer manufacturerDataId, - @RpcParameter(name = "manufacturerData") - String manufacturerData, - @RpcParameter(name = "manufacturerDataMask") - @RpcOptional - String manufacturerDataMask - ){ - if (manufacturerDataMask != null) { - mScanFilterBuilder.setManufacturerData(manufacturerDataId, - ConvertUtils.convertStringToByteArray(manufacturerData), - ConvertUtils.convertStringToByteArray(manufacturerDataMask)); - } else { - mScanFilterBuilder.setManufacturerData(manufacturerDataId, - ConvertUtils.convertStringToByteArray(manufacturerData)); - } - } - - /** - * Add filter "serviceData and serviceDataMask" to existing ScanFilter - * - * @param serviceData the service data to filter against - * @param serviceDataMask the servie data mask to filter against - * @throws Exception - */ - @Rpc(description = "Add filter \"serviceData and serviceDataMask\" to existing ScanFilter ") - public void bleSetScanFilterServiceData( - @RpcParameter(name = "serviceUuid") - String serviceUuid, - @RpcParameter(name = "serviceData") - String serviceData, - @RpcParameter(name = "serviceDataMask") - @RpcOptional - String serviceDataMask - ) { - if (serviceDataMask != null) { - mScanFilterBuilder - .setServiceData( - ParcelUuid.fromString(serviceUuid), - ConvertUtils.convertStringToByteArray(serviceData), - ConvertUtils.convertStringToByteArray( - serviceDataMask)); - } else { - mScanFilterBuilder.setServiceData(ParcelUuid.fromString(serviceUuid), - ConvertUtils.convertStringToByteArray(serviceData)); - } - } - - /** - * Add filter "serviceUuid and/or serviceMask" to existing ScanFilter - * - * @param serviceUuid the service uuid to filter against - * @param serviceMask the service mask to filter against - * @throws Exception - */ - @Rpc(description = "Add filter \"serviceUuid and/or serviceMask\" to existing ScanFilter") - public void bleSetScanFilterServiceUuid( - @RpcParameter(name = "serviceUuid") - String serviceUuid, - @RpcParameter(name = "serviceMask") - @RpcOptional - String serviceMask - ) { - if (serviceMask != null) { - mScanFilterBuilder - .setServiceUuid(ParcelUuid.fromString(serviceUuid), - ParcelUuid.fromString(serviceMask)); - } else { - mScanFilterBuilder.setServiceUuid(ParcelUuid.fromString(serviceUuid)); - } - } - - /** - * Add filter "device name" to existing ScanFilter - * - * @param name the device name to filter against - * @throws Exception - */ - @Rpc(description = "Sets the scan filter's device name") - public void bleSetScanFilterDeviceName( - @RpcParameter(name = "name") - String name - ) { - mScanFilterBuilder.setDeviceName(name); - } - - @Rpc(description = "Set the scan setting's match mode") - public void bleSetScanSettingsMatchMode( - @RpcParameter(name = "mode") Integer mode) { - mScanSettingsBuilder.setMatchMode(mode); - } - - @Rpc(description = "Get the scan setting's match mode") - public int bleGetScanSettingsMatchMode( - @RpcParameter(name = "scanSettingsIndex") Integer scanSettingsIndex - ) { - return mScanSettingsList.get(scanSettingsIndex).getMatchMode(); - } - - @Rpc(description = "Set the scan setting's number of matches") - public void bleSetScanSettingsNumOfMatches( - @RpcParameter(name = "matches") Integer matches) { - mScanSettingsBuilder.setNumOfMatches(matches); - } - - @Rpc(description = "Get the scan setting's number of matches") - public int bleGetScanSettingsNumberOfMatches( - @RpcParameter(name = "scanSettingsIndex") - Integer scanSettingsIndex) { - return mScanSettingsList.get(scanSettingsIndex).getNumOfMatches(); - } - - private class myScanCallback extends ScanCallback { - public Integer index; - String mEventType; - private final Bundle mResults; - - public myScanCallback(Integer idx) { - index = idx; - mEventType = "BleScan"; - mResults = new Bundle(); - } - - @Override - public void onScanFailed(int errorCode) { - String errorString = "UNKNOWN_ERROR_CODE"; - if (errorCode == ScanCallback.SCAN_FAILED_ALREADY_STARTED) { - errorString = "SCAN_FAILED_ALREADY_STARTED"; - } else if (errorCode == ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) { - errorString = "SCAN_FAILED_APPLICATION_REGISTRATION_FAILED"; - } else if (errorCode == ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED) { - errorString = "SCAN_FAILED_FEATURE_UNSUPPORTED"; - } else if (errorCode == ScanCallback.SCAN_FAILED_INTERNAL_ERROR) { - errorString = "SCAN_FAILED_INTERNAL_ERROR"; - } - Log.d("bluetooth_le_scan change onScanFailed " + mEventType + " " + index + " error " - + errorString); - mResults.putInt("ID", index); - mResults.putString("Type", "onScanFailed"); - mResults.putInt("ErrorCode", errorCode); - mResults.putString("Error", errorString); - mEventFacade.postEvent(mEventType + index + "onScanFailed", - mResults.clone()); - mResults.clear(); - } - - @Override - public void onScanResult(int callbackType, ScanResult result) { - Log.d("bluetooth_le_scan change onUpdate " + mEventType + " " + index); - mResults.putInt("ID", index); - mResults.putInt("CallbackType", callbackType); - mResults.putString("Type", "onScanResult"); - mResults.putParcelable("Result", result); - mEventFacade.postEvent(mEventType + index + "onScanResults", mResults.clone()); - mResults.clear(); - } - - @Override - public void onBatchScanResults(List<ScanResult> results) { - Log.d("reportResult " + mEventType + " " + index); - mResults.putLong("Timestamp", System.currentTimeMillis() / 1000); - mResults.putInt("ID", index); - mResults.putString("Type", "onBatchScanResults"); - mResults.putParcelableList("Results", results); - mEventFacade.postEvent(mEventType + index + "onBatchScanResult", mResults.clone()); - mResults.clear(); - } - } - - private class myLeScanCallback implements LeScanCallback { - public Integer index; - String mEventType; - private final Bundle mResults; - - public myLeScanCallback(Integer idx) { - index = idx; - mEventType = "ClassicBleScan"; - mResults = new Bundle(); - } - - @Override - public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { - Log.d("bluetooth_classic_le_scan " + mEventType + " " + index); - mResults.putParcelable("Device", device); - mResults.putInt("Rssi", rssi); - mResults.putString("ScanRecord", ConvertUtils.convertByteArrayToString(scanRecord)); - mResults.putString("Type", "onLeScan"); - mEventFacade.postEvent(mEventType + index + "onLeScan", mResults.clone()); - mResults.clear(); - } - } - - @Override - public void shutdown() { - if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { - for (myScanCallback mScanCallback : mScanCallbackList.values()) { - if (mScanCallback != null) { - try { - mBluetoothAdapter.getBluetoothLeScanner() - .stopScan(mScanCallback); - } catch (NullPointerException e) { - Log.e("Failed to stop ble scan callback.", e); - } - } - } - for (myLeScanCallback mLeScanCallback : mLeScanCallbackList.values()) { - if (mLeScanCallback != null) { - try { - mBluetoothAdapter.stopLeScan(mLeScanCallback); - } catch (NullPointerException e) { - Log.e("Failed to stop classic ble scan callback.", e); - } - } - } - } - mScanCallbackList.clear(); - mScanFilterList.clear(); - mScanSettingsList.clear(); - mLeScanCallbackList.clear(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothMapFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothMapFacade.java deleted file mode 100644 index f1a593d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothMapFacade.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.List; - -import android.app.Service; -import android.bluetooth.BluetoothMap; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothProfile; -import android.bluetooth.BluetoothUuid; -import android.os.ParcelUuid; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class BluetoothMapFacade extends RpcReceiver { - static final ParcelUuid[] MAP_UUIDS = { - BluetoothUuid.MAP, - BluetoothUuid.MNS, - BluetoothUuid.MAS, - }; - private final Service mService; - private final BluetoothAdapter mBluetoothAdapter; - - private static boolean sIsMapReady = false; - private static BluetoothMap sMapProfile = null; - - public BluetoothMapFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - mBluetoothAdapter.getProfileProxy(mService, new MapServiceListener(), - BluetoothProfile.MAP); - } - - class MapServiceListener implements BluetoothProfile.ServiceListener { - @Override - public void onServiceConnected(int profile, BluetoothProfile proxy) { - sMapProfile = (BluetoothMap) proxy; - sIsMapReady = true; - } - - @Override - public void onServiceDisconnected(int profile) { - sIsMapReady = false; - } - } - - public Boolean mapDisconnect(BluetoothDevice device) { - if (sMapProfile.getPriority(device) > BluetoothProfile.PRIORITY_ON) { - sMapProfile.setPriority(device, BluetoothProfile.PRIORITY_ON); - } - return sMapProfile.disconnect(device); - } - - @Rpc(description = "Is Map profile ready.") - public Boolean bluetoothMapIsReady() { - return sIsMapReady; - } - - @Rpc(description = "Disconnect an MAP device.") - public Boolean bluetoothMapDisconnect( - @RpcParameter(name = "deviceID", description = "Name or MAC address of a device.") - String deviceID) - throws Exception { - if (sMapProfile == null) return false; - List<BluetoothDevice> connectedMapDevices = sMapProfile.getConnectedDevices(); - Log.d("Connected map devices: " + connectedMapDevices); - BluetoothDevice mDevice = BluetoothFacade.getDevice(connectedMapDevices, deviceID); - if (!connectedMapDevices.isEmpty() && connectedMapDevices.get(0).equals(mDevice)) { - if (sMapProfile.getPriority(mDevice) > BluetoothProfile.PRIORITY_ON) { - sMapProfile.setPriority(mDevice, BluetoothProfile.PRIORITY_ON); - } - return sMapProfile.disconnect(mDevice); - } else { - return false; - } - } - - @Rpc(description = "Get all the devices connected through MAP.") - public List<BluetoothDevice> bluetoothMapGetConnectedDevices() { - while (!sIsMapReady); - return sMapProfile.getDevicesMatchingConnectionStates( - new int[] {BluetoothProfile.STATE_CONNECTED, - BluetoothProfile.STATE_CONNECTING, - BluetoothProfile.STATE_DISCONNECTING}); - } - - @Rpc(description = "Get the currently connected remote Bluetooth device (PCE).") - public BluetoothDevice bluetoothMapGetClient() { - if (sMapProfile == null) { return null; } - return sMapProfile.getClient(); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothPairingHelper.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothPairingHelper.java deleted file mode 100644 index dbefd70..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothPairingHelper.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import android.bluetooth.BluetoothDevice; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.googlecode.android_scripting.Log; - -public class BluetoothPairingHelper extends BroadcastReceiver { - public BluetoothPairingHelper() { - super(); - Log.d("Pairing helper created."); - } - /** - * Blindly confirm bluetooth connection/bonding requests. - */ - @Override - public void onReceive(Context c, Intent intent) { - String action = intent.getAction(); - Log.d("Bluetooth pairing intent received: " + action); - BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - if(action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) { - int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR); - Log.d("Processing Action Paring Request with type " + type); - if(type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION || - type == BluetoothDevice.PAIRING_VARIANT_CONSENT) { - mDevice.setPairingConfirmation(true); - Log.d("Connection confirmed"); - abortBroadcast(); // Abort the broadcast so Settings app doesn't get it. - } - } - else if(action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST)) { - int type = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.ERROR); - Log.d("Processing Action Connection Access Request type " + type); - if(type == BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS || - type == BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS || - type == BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION) { - Intent newIntent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); - String mReturnPackage = intent.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME); - String mReturnClass = intent.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME); - int mRequestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, - BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); - if (mReturnPackage != null && mReturnClass != null) { - newIntent.setClassName(mReturnPackage, mReturnClass); - } - newIntent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, - BluetoothDevice.CONNECTION_ACCESS_YES); - newIntent.putExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, true); - newIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice); - newIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, mRequestType); - Log.d("Sending connection access acceptance intent."); - abortBroadcast(); - c.sendBroadcast(newIntent, android.Manifest.permission.BLUETOOTH_ADMIN); - } - } - } -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java deleted file mode 100644 index 484fba5..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothRfcommFacade.java +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothServerSocket; -import android.bluetooth.BluetoothSocket; -import android.content.IntentFilter; -import android.os.ParcelFileDescriptor; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.lang.reflect.Field; - -import org.apache.commons.codec.binary.Base64Codec; - -/** - * Bluetooth functions. - * - */ -// Discovery functions added by Eden Sayag - -public class BluetoothRfcommFacade extends RpcReceiver { - - // UUID for SL4A. - private static final String DEFAULT_UUID = "457807c0-4897-11df-9879-0800200c9a66"; - private static final String SDP_NAME = "SL4A"; - private final Service mService; - private final BluetoothPairingHelper mPairingReceiver; - private final BluetoothAdapter mBluetoothAdapter; - private Map<String, BluetoothConnection> - connections = new HashMap<String, BluetoothConnection>(); - - public BluetoothRfcommFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mPairingReceiver = new BluetoothPairingHelper(); - mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - } - - private BluetoothConnection getConnection(String connID) throws IOException { - BluetoothConnection conn = null; - if (connID.trim().length() > 0) { - conn = connections.get(connID); - } else if (connections.size() == 1) { - conn = (BluetoothConnection) connections.values().toArray()[0]; - } - if (conn == null) { - throw new IOException("Bluetooth not ready for this connID."); - } - return conn; - } - - private String addConnection(BluetoothConnection conn) { - String uuid = UUID.randomUUID().toString(); - connections.put(uuid, conn); - conn.setUUID(uuid); - return uuid; - } - - @Rpc(description = "Connect to a device over Bluetooth. " - + "Blocks until the connection is established or fails.", - returns = "True if the connection was established successfully.") - public String bluetoothRfcommConnect( - @RpcParameter(name = "address", description = "The mac address of the device to connect to.") - String address, - @RpcParameter(name = "uuid", - description = "The UUID passed here must match the UUID used by the server device.") - @RpcDefault(DEFAULT_UUID) - String uuid) - throws IOException { - BluetoothDevice mDevice; - BluetoothSocket mSocket; - BluetoothConnection conn; - mDevice = mBluetoothAdapter.getRemoteDevice(address); - mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid)); - - // Register a broadcast receiver to bypass manual confirmation - IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); - mService.registerReceiver(mPairingReceiver, filter); - - // Always cancel discovery because it will slow down a connection. - mBluetoothAdapter.cancelDiscovery(); - mSocket.connect(); - conn = new BluetoothConnection(mSocket); - - mService.unregisterReceiver(mPairingReceiver); - return addConnection(conn); - } - - @Rpc(description = "Returns active Bluetooth connections.") - public Map<String, String> bluetoothRfcommActiveConnections() { - Map<String, String> out = new HashMap<String, String>(); - for (Map.Entry<String, BluetoothConnection> entry : connections.entrySet()) { - if (entry.getValue().isConnected()) { - out.put(entry.getKey(), entry.getValue().getRemoteBluetoothAddress()); - } - } - return out; - } - - @Rpc(description = "Returns the name of the connected device.") - public String bluetoothRfcommGetConnectedDeviceName( - @RpcParameter(name = "connID", description = "Connection id") - @RpcOptional @RpcDefault("") - String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - return conn.getConnectedDeviceName(); - } - - @Rpc(description = "Listens for and accepts a Bluetooth connection." - + "Blocks until the connection is established or fails.") - public String bluetoothRfcommAccept( - @RpcParameter(name = "uuid") @RpcDefault(DEFAULT_UUID) String uuid, - @RpcParameter(name = "timeout", - description = "How long to wait for a new connection, 0 is wait for ever") - @RpcDefault("0") Integer timeout) - throws IOException { - Log.d("Accept bluetooth connection"); - BluetoothServerSocket mServerSocket; - mServerSocket = - mBluetoothAdapter.listenUsingRfcommWithServiceRecord(SDP_NAME, UUID.fromString(uuid)); - // Register a broadcast receiver to bypass manual confirmation - IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); - mService.registerReceiver(mPairingReceiver, filter); - - BluetoothSocket mSocket = mServerSocket.accept(timeout.intValue()); - BluetoothConnection conn = new BluetoothConnection(mSocket, mServerSocket); - mService.unregisterReceiver(mPairingReceiver); - return addConnection(conn); - } - - @Rpc(description = "Sends ASCII characters over the currently open Bluetooth connection.") - public void bluetoothRfcommWrite(@RpcParameter(name = "ascii") String ascii, - @RpcParameter(name = "connID", description = "Connection id") @RpcDefault("") String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - try { - conn.write(ascii); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Read up to bufferSize ASCII characters.") - public String bluetoothRfcommRead( - @RpcParameter(name = "bufferSize") @RpcDefault("4096") Integer bufferSize, - @RpcParameter(name = "connID", description = "Connection id") @RpcOptional @RpcDefault("") - String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - try { - return conn.read(bufferSize); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Send bytes over the currently open Bluetooth connection.") - public void bluetoothRfcommWriteBinary( - @RpcParameter(name = "base64", - description = "A base64 encoded String of the bytes to be sent.") - String base64, - @RpcParameter(name = "connID", description = "Connection id") - @RpcDefault("") @RpcOptional - String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - try { - conn.write(Base64Codec.decodeBase64(base64)); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Read up to bufferSize bytes and return a chunked, base64 encoded string.") - public String bluetoothRfcommReadBinary( - @RpcParameter(name = "bufferSize") @RpcDefault("4096") Integer bufferSize, - @RpcParameter(name = "connID", description = "Connection id") - @RpcDefault("") @RpcOptional - String connID) - throws IOException { - - BluetoothConnection conn = getConnection(connID); - try { - return Base64Codec.encodeBase64String(conn.readBinary(bufferSize)); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Returns True if the next read is guaranteed not to block.") - public Boolean bluetoothRfcommReadReady( - @RpcParameter(name = "connID", description = "Connection id") @RpcDefault("") @RpcOptional - String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - try { - return conn.readReady(); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Read the next line.") - public String bluetoothRfcommReadLine( - @RpcParameter(name = "connID", description = "Connection id") @RpcOptional @RpcDefault("") - String connID) - throws IOException { - BluetoothConnection conn = getConnection(connID); - try { - return conn.readLine(); - } catch (IOException e) { - connections.remove(conn.getUUID()); - throw e; - } - } - - @Rpc(description = "Stops Bluetooth connection.") - public void bluetoothRfcommStop( - @RpcParameter - (name = "connID", description = "Connection id") @RpcOptional @RpcDefault("") - String connID) { - BluetoothConnection conn; - try { - conn = getConnection(connID); - } catch (IOException e) { - e.printStackTrace(); - return; - } - if (conn == null) { - return; - } - - conn.stop(); - connections.remove(conn.getUUID()); - } - - @Override - public void shutdown() { - for (Map.Entry<String, BluetoothConnection> entry : connections.entrySet()) { - entry.getValue().stop(); - } - connections.clear(); - } -} - -class BluetoothConnection { - private BluetoothSocket mSocket; - private BluetoothDevice mDevice; - private OutputStream mOutputStream; - private InputStream mInputStream; - private BufferedReader mReader; - private BluetoothServerSocket mServerSocket; - private String UUID; - - public BluetoothConnection(BluetoothSocket mSocket) throws IOException { - this(mSocket, null); - } - - public BluetoothConnection(BluetoothSocket mSocket, BluetoothServerSocket mServerSocket) - throws IOException { - this.mSocket = mSocket; - mOutputStream = mSocket.getOutputStream(); - mInputStream = mSocket.getInputStream(); - mDevice = mSocket.getRemoteDevice(); - mReader = new BufferedReader(new InputStreamReader(mInputStream, "ASCII")); - this.mServerSocket = mServerSocket; - } - - public void setUUID(String UUID) { - this.UUID = UUID; - } - - public String getUUID() { - return UUID; - } - - public String getRemoteBluetoothAddress() { - return mDevice.getAddress(); - } - - public boolean isConnected() { - if (mSocket == null) { - return false; - } - try { - mSocket.getRemoteDevice(); - mInputStream.available(); - mReader.ready(); - return true; - } catch (Exception e) { - return false; - } - } - - public void write(byte[] out) throws IOException { - if (mOutputStream != null) { - mOutputStream.write(out); - } else { - throw new IOException("Bluetooth not ready."); - } - } - - public void write(String out) throws IOException { - this.write(out.getBytes()); - } - - public Boolean readReady() throws IOException { - if (mReader != null) { - return mReader.ready(); - } - throw new IOException("Bluetooth not ready."); - } - - public byte[] readBinary() throws IOException { - return this.readBinary(4096); - } - - public byte[] readBinary(int bufferSize) throws IOException { - if (mReader != null) { - byte[] buffer = new byte[bufferSize]; - int bytesRead = mInputStream.read(buffer); - if (bytesRead == -1) { - Log.e("Read failed."); - throw new IOException("Read failed."); - } - byte[] truncatedBuffer = new byte[bytesRead]; - System.arraycopy(buffer, 0, truncatedBuffer, 0, bytesRead); - return truncatedBuffer; - } - - throw new IOException("Bluetooth not ready."); - - } - - public String read() throws IOException { - return this.read(4096); - } - - public String read(int bufferSize) throws IOException { - if (mReader != null) { - char[] buffer = new char[bufferSize]; - int bytesRead = mReader.read(buffer); - if (bytesRead == -1) { - Log.e("Read failed."); - throw new IOException("Read failed."); - } - return new String(buffer, 0, bytesRead); - } - throw new IOException("Bluetooth not ready."); - } - - public String readLine() throws IOException { - if (mReader != null) { - return mReader.readLine(); - } - throw new IOException("Bluetooth not ready."); - } - - public String getConnectedDeviceName() { - return mDevice.getName(); - } - - private synchronized void clearFileDescriptor() { - try { - Field field = BluetoothSocket.class.getDeclaredField("mPfd"); - field.setAccessible(true); - ParcelFileDescriptor mPfd = (ParcelFileDescriptor) field.get(mSocket); - if (mPfd == null) - return; - mPfd.close(); - mPfd = null; - try { field.set(mSocket, mPfd); } - catch(Exception e) { - Log.d("Exception setting mPfd = null in cleanCloseFix(): " + e.toString()); - } - } catch (Exception e) { - Log.w("ParcelFileDescriptor could not be cleanly closed.", e); - } - } - - public void stop() { - if (mSocket != null) { - try { - clearFileDescriptor(); - mSocket.close(); - } catch (IOException e) { - Log.e(e); - } - } - mSocket = null; - if (mServerSocket != null) { - try { - mServerSocket.close(); - } catch (IOException e) { - Log.e(e); - } - } - mServerSocket = null; - - if (mInputStream != null) { - try { - mInputStream.close(); - } catch (IOException e) { - Log.e(e); - } - } - mInputStream = null; - if (mOutputStream != null) { - try { - mOutputStream.close(); - } catch (IOException e) { - Log.e(e); - } - } - mOutputStream = null; - if (mReader != null) { - try { - mReader.close(); - } catch (IOException e) { - Log.e(e); - } - } - mReader = null; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java deleted file mode 100644 index 0a96cd9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattClientFacade.java +++ /dev/null @@ -1,956 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.Callable; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCallback; -import android.bluetooth.BluetoothManager; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattDescriptor; -import android.bluetooth.BluetoothGattService; -import android.bluetooth.BluetoothProfile; -import android.content.Context; -import android.os.Bundle; - -import com.googlecode.android_scripting.ConvertUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.rpc.RpcStopEvent; - -public class GattClientFacade extends RpcReceiver { - private final EventFacade mEventFacade; - private BluetoothAdapter mBluetoothAdapter; - private BluetoothManager mBluetoothManager; - private final Service mService; - private final Context mContext; - private final HashMap<Integer, myBluetoothGattCallback> mGattCallbackList; - private final HashMap<Integer, BluetoothGatt> mBluetoothGattList; - private final HashMap<Integer, BluetoothGattCharacteristic> mCharacteristicList; - private final HashMap<Integer, BluetoothGattDescriptor> mDescriptorList; - private final HashMap<Integer, BluetoothGattService> mGattServiceList; - private final HashMap<Integer, List<BluetoothGattService>> mBluetoothGattDiscoveredServicesList; - private final HashMap<Integer, List<BluetoothDevice>> mGattServerDiscoveredDevicesList; - private static int GattCallbackCount; - private static int BluetoothGattDiscoveredServicesCount; - private static int BluetoothGattCount; - private static int CharacteristicCount; - private static int DescriptorCount; - private static int GattServerCallbackCount; - private static int GattServerCount; - private static int GattServiceCount; - - public GattClientFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContext = mService.getApplicationContext(); - mBluetoothAdapter = MainThread.run(mService, - new Callable<BluetoothAdapter>() { - @Override - public BluetoothAdapter call() throws Exception { - return BluetoothAdapter.getDefaultAdapter(); - } - }); - mBluetoothManager = (BluetoothManager) mContext.getSystemService(Service.BLUETOOTH_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - mGattCallbackList = new HashMap<Integer, myBluetoothGattCallback>(); - mCharacteristicList = new HashMap<Integer, BluetoothGattCharacteristic>(); - mBluetoothGattList = new HashMap<Integer, BluetoothGatt>(); - mDescriptorList = new HashMap<Integer, BluetoothGattDescriptor>(); - mGattServiceList = new HashMap<Integer, BluetoothGattService>(); - mBluetoothGattDiscoveredServicesList = new HashMap<Integer, List<BluetoothGattService>>(); - mGattServerDiscoveredDevicesList = new HashMap<Integer, List<BluetoothDevice>>(); - } - - /** - * Create a BluetoothGatt connection - * - * @param index of the callback to start a connection on - * @param macAddress the mac address of the ble device - * @param autoConnect Whether to directly connect to the remote device (false) or to - * automatically connect as soon as the remote device becomes available (true) - * @return the index of the BluetoothGatt object - * @throws Exception - */ - @Rpc(description = "Create a gatt connection") - public int gattClientConnectGatt( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "macAddress") - String macAddress, - @RpcParameter(name = "autoConnect") - Boolean autoConnect - ) throws Exception { - if (mGattCallbackList.get(index) != null) { - BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress); - BluetoothGatt mBluetoothGatt = device.connectGatt(mService.getApplicationContext(), - autoConnect, - mGattCallbackList.get(index)); - BluetoothGattCount += 1; - mBluetoothGattList.put(BluetoothGattCount, mBluetoothGatt); - return BluetoothGattCount; - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Trigger discovering of services on the BluetoothGatt object - * - * @param index The BluetoothGatt object index - * @return true, if the remote service discovery has been started - * @throws Exception - */ - @Rpc(description = "Trigger discovering of services on the BluetoothGatt object") - public boolean gattClientDiscoverServices( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).discoverServices(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get the services from the BluetoothGatt object - * - * @param index The BluetoothGatt object index - * @return a list of BluetoothGattServices - * @throws Exception - */ - @Rpc(description = "Get the services from the BluetoothGatt object") - public List<BluetoothGattService> gattClientGetServices( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).getServices(); - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Abort reliable write of a bluetooth gatt - * - * @param index the bluetooth gatt index - * @throws Exception - */ - @Rpc(description = "Abort reliable write of a bluetooth gatt") - public void gattClientAbortReliableWrite( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - mBluetoothGattList.get(index).abortReliableWrite(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Begin reliable write of a bluetooth gatt - * - * @param index the bluetooth gatt index - * @return - * @throws Exception - */ - @Rpc(description = "Begin reliable write of a bluetooth gatt") - public boolean gattClientBeginReliableWrite( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).beginReliableWrite(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Configure a bluetooth gatt's MTU - * - * @param index the bluetooth gatt index - * @param mtu the MTU to set - * @return - * @throws Exception - */ - @Rpc(description = "true, if the new MTU value has been requested successfully") - public boolean gattClientRequestMtu( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "mtu") - Integer mtu - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).requestMtu(mtu); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Disconnect a bluetooth gatt - * - * @param index the bluetooth gatt index - * @throws Exception - */ - @Rpc(description = "Disconnect a bluetooth gatt") - @RpcStopEvent("GattConnect") - public void gattClientDisconnect( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - mBluetoothGattList.get(index).disconnect(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Execute reliable write on a bluetooth gatt - * - * @param index the bluetooth gatt index - * @return true, if the request to execute the transaction has been sent - * @throws Exception - */ - @Rpc(description = "Execute reliable write on a bluetooth gatt") - public boolean gattExecuteReliableWrite( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).executeReliableWrite(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get a list of Bluetooth Devices connnected to the bluetooth gatt - * - * @param index the bluetooth gatt index - * @return List of BluetoothDevice Objects - * @throws Exception - */ - @Rpc(description = "Get a list of Bluetooth Devices connnected to the bluetooth gatt") - public List<BluetoothDevice> gattClientGetConnectedDevices( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).getConnectedDevices(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get the remote bluetooth device this GATT client targets to - * - * @param index the bluetooth gatt index - * @return the remote bluetooth device this gatt client targets to - * @throws Exception - */ - @Rpc(description = "Get the remote bluetooth device this GATT client targets to") - public BluetoothDevice gattGetDevice( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).getDevice(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get the bluetooth devices matching input connection states - * - * @param index the bluetooth gatt index - * @param states the list of states to match - * @return The list of BluetoothDevice objects that match the states - * @throws Exception - */ - @Rpc(description = "Get the bluetooth devices matching input connection states") - public List<BluetoothDevice> gattClientGetDevicesMatchingConnectionStates( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "states") - int[] states - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).getDevicesMatchingConnectionStates(states); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get the service from an input UUID - * - * @param index the bluetooth gatt index - * @return BluetoothGattService related to the bluetooth gatt - * @throws Exception - */ - @Rpc(description = "Get the service from an input UUID") - public ArrayList<String> gattClientGetServiceUuidList( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - ArrayList<String> serviceUuidList = new ArrayList<String>(); - for (BluetoothGattService service : mBluetoothGattList.get(index).getServices()) { - serviceUuidList.add(service.getUuid().toString()); - } - return serviceUuidList; - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Reads the requested characteristic from the associated remote device. - * @param gattIndex the BluetoothGatt server accociated with the device - * @param discoveredServiceListIndex the index returned from the discovered - * services callback - * @param serviceIndex the service index of the discovered services - * @param characteristicUuid the characteristic uuid to read - * @return true, if the read operation was initiated successfully - * @throws Exception - */ - @Rpc(description = "Reads the requested characteristic from the associated remote device.") - public boolean gattClientReadCharacteristic( - @RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception { - BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex); - if (bluetoothGatt == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = discoveredServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - return bluetoothGatt.readCharacteristic(gattCharacteristic); - } - - /** - * Reads the value for a given descriptor from the associated remote device - * @param gattIndex - the gatt index to use - * @param discoveredServiceListIndex - the discvered serivice list index - * @param serviceIndex - the servce index of the discoveredServiceListIndex - * @param characteristicUuid - the characteristic uuid in which the descriptor is - * @param descriptorUuid - the descriptor uuid to read - * @return - * @throws Exception - */ - @Rpc(description = "Reads the value for a given descriptor from the associated remote device") - public boolean gattClientReadDescriptor(@RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid, - @RpcParameter(name = "descriptorUuid") String descriptorUuid) throws Exception { - BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex); - if (bluetoothGatt == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> gattServiceList = mBluetoothGattDiscoveredServicesList.get( - discoveredServiceListIndex); - if (gattServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = gattServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - UUID dUuid = UUID.fromString(descriptorUuid); - BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid); - if (gattDescriptor == null) { - throw new Exception("Invalid descriptor uuid: " + descriptorUuid); - } - return bluetoothGatt.readDescriptor(gattDescriptor); - } - - /** - * Write the value of a given descriptor to the associated remote device - * - * @param index the bluetooth gatt index - * @param serviceIndex the service index to write to - * @param characteristicUuid the uuid where the descriptor lives - * @param descriptorIndex the descriptor index - * @return true, if the write operation was initiated successfully - * @throws Exception - */ - @Rpc(description = "Write the value of a given descriptor to the associated remote device") - public boolean gattClientWriteDescriptor(@RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid, - @RpcParameter(name = "descriptorUuid") String descriptorUuid) throws Exception { - BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex); - if (bluetoothGatt == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = discoveredServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - UUID dUuid = UUID.fromString(descriptorUuid); - BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid); - if (gattDescriptor == null) { - throw new Exception("Invalid descriptor uuid: " + descriptorUuid); - } - return bluetoothGatt.writeDescriptor(gattDescriptor); - } - - /** - * Write the value to a discovered descriptor. - * @param gattIndex - the gatt index to use - * @param discoveredServiceListIndex - the discovered service list index - * @param serviceIndex - the service index of the discoveredServiceListIndex - * @param characteristicUuid - the characteristic uuid in which the descriptor is - * @param descriptorUuid - the descriptor uuid to read - * @param value - the value to set the descriptor to - * @return true is the value was set to the descriptor - * @throws Exception - */ - @Rpc(description = "Write the value of a given descriptor to the associated remote device") - public boolean gattClientDescriptorSetValue(@RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid, - @RpcParameter(name = "descriptorUuid") String descriptorUuid, - @RpcParameter(name = "value") String value) throws Exception { - if (mBluetoothGattList.get(gattIndex) == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = discoveredServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - UUID dUuid = UUID.fromString(descriptorUuid); - BluetoothGattDescriptor gattDescriptor = gattCharacteristic.getDescriptor(dUuid); - if (gattDescriptor == null) { - throw new Exception("Invalid descriptor uuid: " + descriptorUuid); - } - byte[] byteArray = ConvertUtils.convertStringToByteArray(value); - return gattDescriptor.setValue(byteArray); - } - - /** - * Write the value of a given characteristic to the associated remote device - * - * @param index the bluetooth gatt index - * @param serviceIndex the service where the characteristic lives - * @param characteristicUuid the characteristic uuid to write to - * @return true, if the write operation was successful - * @throws Exception - */ - @Rpc(description = "Write the value of a given characteristic to the associated remote device") - public boolean gattClientWriteCharacteristic(@RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid) throws Exception { - BluetoothGatt bluetoothGatt = mBluetoothGattList.get(gattIndex); - if (bluetoothGatt == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = discoveredServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - return bluetoothGatt.writeCharacteristic(gattCharacteristic); - } - - /** - * Write the value to a discovered characteristic. - * @param gattIndex - the gatt index to use - * @param discoveredServiceListIndex - the discovered service list index - * @param serviceIndex - the service index of the discoveredServiceListIndex - * @param characteristicUuid - the characteristic uuid in which the descriptor is - * @param value - the value to set the characteristic to - * @return true, if the value was set to the characteristic - * @throws Exception - */ - @Rpc(description = "Write the value of a given characteristic to the associated remote device") - public boolean gattClientCharacteristicSetValue(@RpcParameter(name = "gattIndex") Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") String characteristicUuid, - @RpcParameter(name = "value") String value) throws Exception { - if (mBluetoothGattList.get(gattIndex) == null) { - throw new Exception("Invalid gattIndex " + gattIndex); - } - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList == null) { - throw new Exception("Invalid discoveredServiceListIndex " + discoveredServiceListIndex); - } - BluetoothGattService gattService = discoveredServiceList.get(serviceIndex); - if (gattService == null) { - throw new Exception("Invalid serviceIndex " + serviceIndex); - } - UUID cUuid = UUID.fromString(characteristicUuid); - BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(cUuid); - if (gattCharacteristic == null) { - throw new Exception("Invalid characteristic uuid: " + characteristicUuid); - } - byte[] byteArray = ConvertUtils.convertStringToByteArray(value); - return gattCharacteristic.setValue(byteArray); - } - /** - * Read the RSSI for a connected remote device - * - * @param index the bluetooth gatt index - * @return true, if the RSSI value has been requested successfully - * @throws Exception - */ - @Rpc(description = "Read the RSSI for a connected remote device") - public boolean gattClientReadRSSI( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).readRemoteRssi(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Clears the internal cache and forces a refresh of the services from the remote device - * - * @param index the bluetooth gatt index - * @return Clears the internal cache and forces a refresh of the services from the remote - * device. - * @throws Exception - */ - @Rpc(description = "Clears the internal cache and forces a refresh of the services from the remote device") - public boolean gattClientRefresh( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattList.get(index) != null) { - return mBluetoothGattList.get(index).refresh(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Request a connection parameter update. - * @param index the bluetooth gatt index - * @param connectionPriority connection priority - * @return boolean True if successful False otherwise. - * @throws Exception - */ - @Rpc(description = "Request a connection parameter update. from the Bluetooth Gatt") - public boolean gattClientRequestConnectionPriority( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "connectionPriority") - Integer connectionPriority - ) throws Exception { - boolean result = false; - if (mBluetoothGattList.get(index) != null) { - result = mBluetoothGattList.get(index).requestConnectionPriority( - connectionPriority); - } else { - throw new Exception("Invalid index input:" + index); - } - return result; - } - - /** - * Sets the characteristic notification of a bluetooth gatt - * - * @param index the bluetooth gatt index - * @param characteristicIndex the characteristic index - * @param enable Enable or disable notifications/indications for a given characteristic - * @return true, if the requested notification status was set successfully - * @throws Exception - */ - @Rpc(description = "Sets the characteristic notification of a bluetooth gatt") - public boolean gattClientSetCharacteristicNotification( - @RpcParameter(name = "gattIndex") - Integer gattIndex, - @RpcParameter(name = "discoveredServiceListIndex") - Integer discoveredServiceListIndex, - @RpcParameter(name = "serviceIndex") - Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") - String characteristicUuid, - @RpcParameter(name = "enable") - Boolean enable - ) throws Exception { - if (mBluetoothGattList.get(gattIndex) != null) { - if(mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex) != null) { - List<BluetoothGattService> discoveredServiceList = - mBluetoothGattDiscoveredServicesList.get(discoveredServiceListIndex); - if (discoveredServiceList.get(serviceIndex) != null) { - UUID cUuid = UUID.fromString(characteristicUuid); - if (discoveredServiceList.get(serviceIndex).getCharacteristic(cUuid) != null) { - return mBluetoothGattList.get(gattIndex).setCharacteristicNotification( - discoveredServiceList.get(serviceIndex).getCharacteristic(cUuid), enable); - } else { - throw new Exception ("Invalid characteristic uuid: " + characteristicUuid); - } - } else { - throw new Exception ("Invalid serviceIndex " + serviceIndex); - } - } else { - throw new Exception("Invalid discoveredServiceListIndex: " + discoveredServiceListIndex); - } - } else { - throw new Exception("Invalid gattIndex input: " + gattIndex); - } - } - - /** - * Create a new GattCallback object - * - * @return the index of the callback object - */ - @Rpc(description = "Create a new GattCallback object") - public Integer gattCreateGattCallback() { - GattCallbackCount += 1; - int index = GattCallbackCount; - mGattCallbackList.put(index, new myBluetoothGattCallback(index)); - return index; - } - - /** - * Returns the list of discovered Bluetooth Gatt Services. - * @throws Exception - */ - @Rpc(description = "Get Bluetooth Gatt Services") - public int gattClientGetDiscoveredServicesCount ( - @RpcParameter(name = "index") - Integer index - ) throws Exception { - if (mBluetoothGattDiscoveredServicesList.get(index) != null) { - return mBluetoothGattDiscoveredServicesList.get(index).size(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Returns the discovered Bluetooth Gatt Service Uuid. - * @throws Exception - */ - @Rpc(description = "Get Bluetooth Gatt Service Uuid") - public String gattClientGetDiscoveredServiceUuid ( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "serviceIndex") - Integer serviceIndex - ) throws Exception { - List<BluetoothGattService> mBluetoothServiceList = - mBluetoothGattDiscoveredServicesList.get(index); - if (mBluetoothServiceList != null) { - return mBluetoothServiceList.get(serviceIndex).getUuid().toString(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get discovered characteristic uuids from the pheripheral device. - * @param index the index of the bluetooth gatt discovered services list - * @param serviceIndex the service to get - * @return the list of characteristic uuids - * @throws Exception - */ - @Rpc(description = "Get Bluetooth Gatt Services") - public ArrayList<String> gattClientGetDiscoveredCharacteristicUuids ( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "serviceIndex") - Integer serviceIndex - ) throws Exception { - if (mBluetoothGattDiscoveredServicesList.get(index) != null) { - if (mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex) != null) { - ArrayList<String> uuidList = new ArrayList<String>(); - List<BluetoothGattCharacteristic> charList = mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex).getCharacteristics(); - for (BluetoothGattCharacteristic mChar : charList) { - uuidList.add(mChar.getUuid().toString()); - } - return uuidList; - } else { - throw new Exception("Invalid serviceIndex input:" + index); - } - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get discovered descriptor uuids from the pheripheral device. - * @param index the discovered services list index - * @param serviceIndex the service index of the discovered services list - * @param characteristicUuid the characteristicUuid to select from the - * discovered service which contains the list of descriptors. - * @return the list of descriptor uuids - * @throws Exception - */ - @Rpc(description = "Get Bluetooth Gatt Services") - public ArrayList<String> gattClientGetDiscoveredDescriptorUuids ( - @RpcParameter(name = "index") - Integer index, - @RpcParameter(name = "serviceIndex") - Integer serviceIndex, - @RpcParameter(name = "characteristicUuid") - String characteristicUuid - ) throws Exception { - if (mBluetoothGattDiscoveredServicesList.get(index) != null) { - if (mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex) != null) { - BluetoothGattService service = mBluetoothGattDiscoveredServicesList.get(index).get(serviceIndex); - UUID cUuid = UUID.fromString(characteristicUuid); - if (service.getCharacteristic(cUuid) != null) { - ArrayList<String> uuidList = new ArrayList<String>(); - for (BluetoothGattDescriptor mDesc : service.getCharacteristic(cUuid).getDescriptors()) { - uuidList.add(mDesc.getUuid().toString()); - } - return uuidList; - } else { - throw new Exception("Invalid characeristicUuid : " - + characteristicUuid); - } - } else { - throw new Exception("Invalid serviceIndex input:" - + index); - } - } else { - throw new Exception("Invalid index input:" - + index); - } - } - - private class myBluetoothGattCallback extends BluetoothGattCallback { - private final Bundle mResults; - private final int index; - private final String mEventType; - - public myBluetoothGattCallback(int idx) { - mResults = new Bundle(); - mEventType = "GattConnect"; - index = idx; - } - - @Override - public void onConnectionStateChange(BluetoothGatt gatt, int status, - int newState) { - Log.d("gatt_connect change onConnectionStateChange " + mEventType + " " + index); - if (newState == BluetoothProfile.STATE_CONNECTED) { - Log.d("State Connected to mac address " - + gatt.getDevice().getAddress() + " status " + status); - } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - Log.d("State Disconnected from mac address " - + gatt.getDevice().getAddress() + " status " + status); - } else if (newState == BluetoothProfile.STATE_CONNECTING) { - Log.d("State Connecting to mac address " - + gatt.getDevice().getAddress() + " status " + status); - } else if (newState == BluetoothProfile.STATE_DISCONNECTING) { - Log.d("State Disconnecting from mac address " - + gatt.getDevice().getAddress() + " status " + status); - } - mResults.putInt("Status", status); - mResults.putInt("State", newState); - mEventFacade - .postEvent(mEventType + index + "onConnectionStateChange", mResults.clone()); - mResults.clear(); - } - - @Override - public void onServicesDiscovered(BluetoothGatt gatt, int status) { - Log.d("gatt_connect change onServicesDiscovered " + mEventType + " " + index); - int idx = BluetoothGattDiscoveredServicesCount++; - mBluetoothGattDiscoveredServicesList.put(idx, gatt.getServices()); - mResults.putInt("ServicesIndex", idx); - mResults.putInt("Status", status); - for (BluetoothGattService se: gatt.getServices()) { - System.out.println("SWAG: " + se.getUuid().toString()); - } - mEventFacade - .postEvent(mEventType + index + "onServicesDiscovered", mResults.clone()); - mResults.clear(); - } - - @Override - public void onCharacteristicRead(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, - int status) { - Log.d("gatt_connect change onCharacteristicRead " + mEventType + " " + index); - mResults.putInt("Status", status); - mResults.putString("CharacteristicUuid", characteristic.getUuid().toString()); - mEventFacade - .postEvent(mEventType + index + "onCharacteristicRead", mResults.clone()); - mResults.clear(); - } - - @Override - public void onCharacteristicWrite(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic, int status) { - Log.d("gatt_connect change onCharacteristicWrite " + mEventType + " " + index); - mResults.putInt("Status", status); - mResults.putString("CharacteristicUuid", characteristic.getUuid().toString()); - mEventFacade - .postEvent(mEventType + index + "onCharacteristicWrite", mResults.clone()); - mResults.clear(); - } - - @Override - public void onCharacteristicChanged(BluetoothGatt gatt, - BluetoothGattCharacteristic characteristic) { - Log.d("gatt_connect change onCharacteristicChanged " + mEventType + " " + index); - mResults.putInt("ID", index); - mResults.putString("CharacteristicUuid", characteristic.getUuid().toString()); - mEventFacade - .postEvent(mEventType + index + "onCharacteristicChanged", mResults.clone()); - mResults.clear(); - } - - @Override - public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, - int status) { - Log.d("gatt_connect change onServicesDiscovered " + mEventType + " " + index); - mResults.putInt("Status", status); - mResults.putString("DescriptorUuid", descriptor.getUuid().toString()); - mEventFacade - .postEvent(mEventType + index + "onDescriptorRead", mResults.clone()); - mResults.clear(); - } - - @Override - public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, - int status) { - Log.d("gatt_connect change onDescriptorWrite " + mEventType + " " + index); - mResults.putInt("ID", index); - mResults.putInt("Status", status); - mResults.putString("DescriptorUuid", descriptor.getUuid().toString()); - mEventFacade - .postEvent(mEventType + index + "onDescriptorWrite", mResults.clone()); - mResults.clear(); - } - - @Override - public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { - Log.d("gatt_connect change onReliableWriteCompleted " + mEventType + " " - + index); - mResults.putInt("Status", status); - mEventFacade - .postEvent(mEventType + index + "onReliableWriteCompleted", mResults.clone()); - mResults.clear(); - } - - @Override - public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { - Log.d("gatt_connect change onReadRemoteRssi " + mEventType + " " + index); - mResults.putInt("Status", status); - mResults.putInt("Rssi", rssi); - mEventFacade - .postEvent(mEventType + index + "onReadRemoteRssi", mResults.clone()); - mResults.clear(); - } - - @Override - public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { - Log.d("gatt_connect change onMtuChanged " + mEventType + " " + index); - mResults.putInt("Status", status); - mResults.putInt("MTU", mtu); - mEventFacade - .postEvent(mEventType + index + "onMtuChanged", mResults.clone()); - mResults.clear(); - } - } - - @Override - public void shutdown() { - if (!mBluetoothGattList.isEmpty()) { - if (mBluetoothGattList.values() != null) { - for (BluetoothGatt mBluetoothGatt : mBluetoothGattList.values()) { - mBluetoothGatt.close(); - } - } - } - mGattCallbackList.clear(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java deleted file mode 100644 index df03fe2..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/bluetooth/GattServerFacade.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.bluetooth; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.Callable; - -import android.app.Service; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattServer; -import android.bluetooth.BluetoothManager; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattServerCallback; -import android.bluetooth.BluetoothGattDescriptor; -import android.bluetooth.BluetoothGattService; -import android.bluetooth.BluetoothProfile; -import android.content.Context; -import android.os.Bundle; - -import com.googlecode.android_scripting.ConvertUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -public class GattServerFacade extends RpcReceiver { - private final EventFacade mEventFacade; - private BluetoothAdapter mBluetoothAdapter; - private BluetoothManager mBluetoothManager; - private final Service mService; - private final Context mContext; - private final HashMap<Integer, BluetoothGattCharacteristic> mCharacteristicList; - private final HashMap<Integer, BluetoothGattDescriptor> mDescriptorList; - private final HashMap<Integer, BluetoothGattServer> mBluetoothGattServerList; - private final HashMap<Integer, myBluetoothGattServerCallback> mBluetoothGattServerCallbackList; - private final HashMap<Integer, BluetoothGattService> mGattServiceList; - private final HashMap<Integer, List<BluetoothGattService>> mBluetoothGattDiscoveredServicesList; - private final HashMap<Integer, List<BluetoothDevice>> mGattServerDiscoveredDevicesList; - private static int CharacteristicCount; - private static int DescriptorCount; - private static int GattServerCallbackCount; - private static int GattServerCount; - private static int GattServiceCount; - - public GattServerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContext = mService.getApplicationContext(); - mBluetoothAdapter = MainThread.run(mService, new Callable<BluetoothAdapter>() { - @Override - public BluetoothAdapter call() throws Exception { - return BluetoothAdapter.getDefaultAdapter(); - } - }); - mBluetoothManager = (BluetoothManager) mContext.getSystemService(Service.BLUETOOTH_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - mCharacteristicList = new HashMap<Integer, BluetoothGattCharacteristic>(); - mDescriptorList = new HashMap<Integer, BluetoothGattDescriptor>(); - mBluetoothGattServerList = new HashMap<Integer, BluetoothGattServer>(); - mBluetoothGattServerCallbackList = new HashMap<Integer, myBluetoothGattServerCallback>(); - mGattServiceList = new HashMap<Integer, BluetoothGattService>(); - mBluetoothGattDiscoveredServicesList = new HashMap<Integer, List<BluetoothGattService>>(); - mGattServerDiscoveredDevicesList = new HashMap<Integer, List<BluetoothDevice>>(); - } - - /** - * Open a new Gatt server. - * - * @param index the bluetooth gatt server callback to open on - * @return the index of the newly opened gatt server - * @throws Exception - */ - @Rpc(description = "Open new gatt server") - public int gattServerOpenGattServer(@RpcParameter(name = "index") Integer index) - throws Exception { - if (mBluetoothGattServerCallbackList.get(index) != null) { - BluetoothGattServer mGattServer = - mBluetoothManager.openGattServer(mContext, mBluetoothGattServerCallbackList.get(index)); - GattServerCount += 1; - int in = GattServerCount; - mBluetoothGattServerList.put(in, mGattServer); - return in; - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Add a service to a bluetooth gatt server - * - * @param index the bluetooth gatt server to add a service to - * @param serviceIndex the service to add to the bluetooth gatt server - * @throws Exception - */ - @Rpc(description = "Add service to bluetooth gatt server") - public void gattServerAddService(@RpcParameter(name = "index") Integer index, - @RpcParameter(name = "serviceIndex") Integer serviceIndex) throws Exception { - if (mBluetoothGattServerList.get(index) != null) { - if (mGattServiceList.get(serviceIndex) != null) { - mBluetoothGattServerList.get(index).addService(mGattServiceList.get(serviceIndex)); - } else { - throw new Exception("Invalid serviceIndex input:" + Integer.toString(serviceIndex)); - } - } else { - throw new Exception("Invalid index input:" + Integer.toString(index)); - } - } - - /** - * Get connected devices of the gatt server - * - * @param gattServerIndex the gatt server index - * @throws Exception - */ - @Rpc(description = "Return a list of connected gatt devices.") - public List<BluetoothDevice> gattServerGetConnectedDevices( - @RpcParameter(name = "gattServerIndex") Integer gattServerIndex) throws Exception { - if (mBluetoothGattServerList.get(gattServerIndex) == null) { - throw new Exception("Invalid gattServerIndex: " + Integer.toString(gattServerIndex)); - } - List<BluetoothDevice> connectedDevices = - mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER); - mGattServerDiscoveredDevicesList.put(gattServerIndex, connectedDevices); - return connectedDevices; - } - - /** - * Get connected devices of the gatt server - * - * @param gattServerIndex the gatt server index - * @param bluetoothDeviceIndex the remotely connected bluetooth device - * @param requestId the ID of the request that was received with the callback - * @param status the status of the request to be sent to the remote devices - * @param offset value offset for partial read/write response - * @param value the value of the attribute that was read/written - * @throws Exception - */ - @Rpc(description = "Send a response after a write.") - public void gattServerSendResponse( - @RpcParameter(name = "gattServerIndex") Integer gattServerIndex, - @RpcParameter(name = "bluetoothDeviceIndex") Integer bluetoothDeviceIndex, - @RpcParameter(name = "requestId") Integer requestId, - @RpcParameter(name = "status") Integer status, @RpcParameter(name = "offset") Integer offset, - @RpcParameter(name = "value") String value) throws Exception { - - BluetoothGattServer gattServer = mBluetoothGattServerList.get(gattServerIndex); - if (gattServer == null) - throw new Exception("Invalid gattServerIndex: " + Integer.toString(gattServerIndex)); - List<BluetoothDevice> connectedDevices = mGattServerDiscoveredDevicesList.get(gattServerIndex); - if (connectedDevices == null) - throw new Exception( - "Connected device list empty for gattServerIndex:" + Integer.toString(gattServerIndex)); - BluetoothDevice bluetoothDevice = connectedDevices.get(bluetoothDeviceIndex); - if (bluetoothDevice == null) - throw new Exception( - "Invalid bluetoothDeviceIndex: " + Integer.toString(bluetoothDeviceIndex)); - gattServer.sendResponse(bluetoothDevice, requestId, status, offset, - ConvertUtils.convertStringToByteArray(value)); - } - - /** - * Create a new bluetooth gatt service - * - * @param uuid the UUID that characterises the service - * @param serviceType the service type - * @return The index of the new bluetooth gatt service - */ - @Rpc(description = "Create new bluetooth gatt service") - public int gattServerCreateService(@RpcParameter(name = "uuid") String uuid, - @RpcParameter(name = "serviceType") Integer serviceType) { - GattServiceCount += 1; - int index = GattServiceCount; - mGattServiceList.put(index, new BluetoothGattService(UUID.fromString(uuid), serviceType)); - return index; - } - - /** - * Add a characteristic to a bluetooth gatt service - * - * @param index the bluetooth gatt service index - * @param serviceUuid the service Uuid to get - * @param characteristicIndex the character index to use - * @throws Exception - */ - @Rpc(description = "Add a characteristic to a bluetooth gatt service") - public void gattServiceAddCharacteristic(@RpcParameter(name = "index") Integer index, - @RpcParameter(name = "serviceUuid") String serviceUuid, - @RpcParameter(name = "characteristicIndex") Integer characteristicIndex) throws Exception { - if (mBluetoothGattServerList.get(index) != null - && mBluetoothGattServerList.get(index).getService(UUID.fromString(serviceUuid)) != null - && mCharacteristicList.get(characteristicIndex) != null) { - mBluetoothGattServerList.get(index).getService(UUID.fromString(serviceUuid)) - .addCharacteristic(mCharacteristicList.get(characteristicIndex)); - } else { - if (mBluetoothGattServerList.get(index) == null) { - throw new Exception("Invalid index input:" + index); - } else if (mCharacteristicList.get(characteristicIndex) == null) { - throw new Exception("Invalid characteristicIndex input:" + characteristicIndex); - } else { - throw new Exception("Invalid serviceUuid input:" + serviceUuid); - } - } - } - - /** - * Add a characteristic to a bluetooth gatt service - * - * @param index the bluetooth gatt service to add a characteristic to - * @param characteristicIndex the characteristic to add - * @throws Exception - */ - @Rpc(description = "Add a characteristic to a bluetooth gatt service") - public void gattServerAddCharacteristicToService(@RpcParameter(name = "index") Integer index, - @RpcParameter(name = "characteristicIndex") Integer characteristicIndex - - ) throws Exception { - if (mGattServiceList.get(index) != null) { - if (mCharacteristicList.get(characteristicIndex) != null) { - mGattServiceList.get(index).addCharacteristic(mCharacteristicList.get(characteristicIndex)); - } else { - throw new Exception("Invalid index input:" + index); - } - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Close a bluetooth gatt - * - * @param index the bluetooth gatt index to close - * @throws Exception - */ - @Rpc(description = "Close a bluetooth gatt") - public void gattServerClose(@RpcParameter(name = "index") Integer index) throws Exception { - if (mBluetoothGattServerList.get(index) != null) { - mBluetoothGattServerList.get(index).close(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get a list of Bluetooth Devices connnected to the bluetooth gatt - * - * @param index the bluetooth gatt index - * @return List of BluetoothDevice Objects - * @throws Exception - */ - @Rpc(description = "Get a list of Bluetooth Devices connnected to the bluetooth gatt") - public List<BluetoothDevice> gattGetConnectedDevices(@RpcParameter(name = "index") Integer index) - throws Exception { - if (mBluetoothGattServerList.get(index) != null) { - return mBluetoothGattServerList.get(index).getConnectedDevices(); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get the service from an input UUID - * - * @param index the bluetooth gatt index - * @return BluetoothGattService related to the bluetooth gatt - * @throws Exception - */ - @Rpc(description = "Get the service from an input UUID") - public ArrayList<String> gattGetServiceUuidList(@RpcParameter(name = "index") Integer index) - throws Exception { - if (mBluetoothGattServerList.get(index) != null) { - ArrayList<String> serviceUuidList = new ArrayList<String>(); - for (BluetoothGattService service : mBluetoothGattServerList.get(index).getServices()) { - serviceUuidList.add(service.getUuid().toString()); - } - return serviceUuidList; - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Get the service from an input UUID - * - * @param index the bluetooth gatt index - * @param uuid the String uuid that matches the service - * @return BluetoothGattService related to the bluetooth gatt - * @throws Exception - */ - @Rpc(description = "Get the service from an input UUID") - public BluetoothGattService gattGetService(@RpcParameter(name = "index") Integer index, - @RpcParameter(name = "uuid") String uuid) throws Exception { - if (mBluetoothGattServerList.get(index) != null) { - return mBluetoothGattServerList.get(index).getService(UUID.fromString(uuid)); - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Add a descriptor to a bluetooth gatt characteristic - * - * @param index the bluetooth gatt characteristic to add a descriptor to - * @param descriptorIndex the descritor index to add to the characteristic - * @throws Exception - */ - @Rpc(description = "add descriptor to blutooth gatt characteristic") - public void gattServerCharacteristicAddDescriptor(@RpcParameter(name = "index") Integer index, - @RpcParameter(name = "descriptorIndex") Integer descriptorIndex) throws Exception { - if (mCharacteristicList.get(index) != null) { - if (mDescriptorList.get(descriptorIndex) != null) { - mCharacteristicList.get(index).addDescriptor(mDescriptorList.get(descriptorIndex)); - } else { - throw new Exception("Invalid descriptorIndex input:" + descriptorIndex); - } - } else { - throw new Exception("Invalid index input:" + index); - } - } - - /** - * Create a new Characteristic object - * - * @param characteristicUuid uuid The UUID for this characteristic - * @param property Properties of this characteristic - * @param permission permissions Permissions for this characteristic - * @return - */ - @Rpc(description = "Create a new Characteristic object") - public int gattServerCreateBluetoothGattCharacteristic( - @RpcParameter(name = "characteristicUuid") String characteristicUuid, - @RpcParameter(name = "property") Integer property, - @RpcParameter(name = "permission") Integer permission) { - CharacteristicCount += 1; - int index = CharacteristicCount; - BluetoothGattCharacteristic characteristic = - new BluetoothGattCharacteristic(UUID.fromString(characteristicUuid), property, permission); - mCharacteristicList.put(index, characteristic); - return index; - } - - /** - * Create a new GattCallback object - * - * @return the index of the callback object - */ - @Rpc(description = "Create a new GattCallback object") - public Integer gattServerCreateGattServerCallback() { - GattServerCallbackCount += 1; - int index = GattServerCallbackCount; - mBluetoothGattServerCallbackList.put(index, new myBluetoothGattServerCallback(index)); - return index; - } - - /** - * Create a new Descriptor object - * - * @param descriptorUuid the UUID for this descriptor - * @param permissions Permissions for this descriptor - * @return the index of the Descriptor object - */ - @Rpc(description = "Create a new Descriptor object") - public int gattServerCreateBluetoothGattDescriptor( - @RpcParameter(name = "descriptorUuid") String descriptorUuid, - @RpcParameter(name = "permissions") Integer permissions) { - DescriptorCount += 1; - int index = DescriptorCount; - BluetoothGattDescriptor descriptor = - new BluetoothGattDescriptor(UUID.fromString(descriptorUuid), permissions); - mDescriptorList.put(index, descriptor); - return index; - } - - private class myBluetoothGattServerCallback extends BluetoothGattServerCallback { - private final Bundle mResults; - private final int index; - private final String mEventType; - - public myBluetoothGattServerCallback(int idx) { - mResults = new Bundle(); - mEventType = "GattServer"; - index = idx; - } - - @Override - public void onServiceAdded(int status, BluetoothGattService service) { - Log.d("gatt_server change onServiceAdded " + mEventType + " " + index); - mResults.putString("serviceUuid", service.getUuid().toString()); - mResults.putInt("instanceId", service.getInstanceId()); - mEventFacade.postEvent(mEventType + index + "onServiceAdded", mResults.clone()); - mResults.clear(); - } - - @Override - public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattCharacteristic characteristic) { - Log.d("gatt_server change onCharacteristicReadRequest " + mEventType + " " + index); - mResults.putInt("requestId", requestId); - mResults.putInt("offset", offset); - mResults.putInt("instanceId", characteristic.getInstanceId()); - mResults.putInt("properties", characteristic.getProperties()); - mResults.putString("uuid", characteristic.getUuid().toString()); - mResults.putInt("permissions", characteristic.getPermissions()); - mEventFacade.postEvent(mEventType + index + "onCharacteristicReadRequest", mResults.clone()); - mResults.clear(); - } - - @Override - public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { - Log.d("gatt_server change onCharacteristicWriteRequest " + mEventType + " " + index); - mResults.putInt("requestId", requestId); - mResults.putInt("offset", offset); - mResults.putParcelable("BluetoothDevice", device); - mResults.putBoolean("preparedWrite", preparedWrite); - mResults.putBoolean("responseNeeded", responseNeeded); - mResults.putString("value", ConvertUtils.convertByteArrayToString(value)); - mResults.putInt("instanceId", characteristic.getInstanceId()); - mResults.putInt("properties", characteristic.getProperties()); - mResults.putString("uuid", characteristic.getUuid().toString()); - mResults.putInt("permissions", characteristic.getPermissions()); - mEventFacade.postEvent(mEventType + index + "onCharacteristicWriteRequest", mResults.clone()); - mResults.clear(); - - } - - @Override - public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, - BluetoothGattDescriptor descriptor) { - Log.d("gatt_server change onDescriptorReadRequest " + mEventType + " " + index); - mResults.putInt("requestId", requestId); - mResults.putInt("offset", offset); - mResults.putParcelable("BluetoothDevice", device); - mResults.putInt("instanceId", descriptor.getInstanceId()); - mResults.putInt("permissions", descriptor.getPermissions()); - mResults.putString("uuid", descriptor.getUuid().toString()); - mEventFacade.postEvent(mEventType + index + "onDescriptorReadRequest", mResults.clone()); - mResults.clear(); - } - - @Override - public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, - BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, - int offset, byte[] value) { - Log.d("gatt_server change onDescriptorWriteRequest " + mEventType + " " + index); - mResults.putInt("requestId", requestId); - mResults.putInt("offset", offset); - mResults.putParcelable("BluetoothDevice", device); - mResults.putBoolean("preparedWrite", preparedWrite); - mResults.putBoolean("responseNeeded", responseNeeded); - mResults.putString("value", ConvertUtils.convertByteArrayToString(value)); - mResults.putInt("instanceId", descriptor.getInstanceId()); - mResults.putInt("permissions", descriptor.getPermissions()); - mResults.putString("uuid", descriptor.getUuid().toString()); - mEventFacade.postEvent(mEventType + index + "onDescriptorWriteRequest", mResults.clone()); - mResults.clear(); - } - - @Override - public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) { - Log.d("gatt_server change onExecuteWrite " + mEventType + " " + index); - mResults.putParcelable("BluetoothDevice", device); - mResults.putInt("requestId", requestId); - mResults.putBoolean("execute", execute); - mEventFacade.postEvent(mEventType + index + "onExecuteWrite", mResults.clone()); - mResults.clear(); - } - - @Override - public void onNotificationSent(BluetoothDevice device, int status) { - Log.d("gatt_server change onNotificationSent " + mEventType + " " + index); - mResults.putParcelable("BluetoothDevice", device); - mResults.putInt("status", status); - mEventFacade.postEvent(mEventType + index + "onNotificationSent", mResults.clone()); - mResults.clear(); - } - - @Override - public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { - Log.d("gatt_server change onConnectionStateChange " + mEventType + " " + index); - if (newState == BluetoothProfile.STATE_CONNECTED) { - Log.d("State Connected to mac address " + device.getAddress() + " status " + status); - } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { - Log.d("State Disconnected from mac address " + device.getAddress() + " status " + status); - } - mResults.putParcelable("BluetoothDevice", device); - mResults.putInt("status", status); - mResults.putInt("newState", newState); - mEventFacade.postEvent(mEventType + index + "onConnectionStateChange", mResults.clone()); - mResults.clear(); - } - - @Override - public void onMtuChanged(BluetoothDevice device, int mtu) { - Log.d("gatt_server change onMtuChanged " + mEventType + " " + index); - mResults.putParcelable("BluetoothDevice", device); - mResults.putInt("mtu", mtu); - mEventFacade.postEvent(mEventType + index + "onMtuChanged", mResults.clone()); - mResults.clear(); - } - } - - @Override - public void shutdown() { - if (!mBluetoothGattServerList.isEmpty()) { - if (mBluetoothGattServerList.values() != null) { - for (BluetoothGattServer mBluetoothGattServer : mBluetoothGattServerList.values()) { - mBluetoothGattServer.close(); - } - } - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/AudioManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/AudioManagerFacade.java deleted file mode 100644 index b611678..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/AudioManagerFacade.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import android.app.Service; -import android.content.Context; -import android.media.AudioManager; -import android.media.AudioManager.OnAudioFocusChangeListener; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; - -public class AudioManagerFacade extends RpcReceiver { - - private final Service mService; - private final EventFacade mEventFacade; - private final AudioManager mAudio; - private final OnAudioFocusChangeListener mFocusChangeListener; - private boolean mIsFocused; - - public AudioManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mEventFacade = manager.getReceiver(EventFacade.class); - mAudio = (AudioManager) mService.getSystemService(Context.AUDIO_SERVICE); - mFocusChangeListener = new OnAudioFocusChangeListener() { - public void onAudioFocusChange(int focusChange) { - if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { - mIsFocused = false; - } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { - mIsFocused = true; - } - } - }; - } - - @Rpc(description = "Checks whether any music is active.") - public Boolean audioIsMusicActive() { - return mAudio.isMusicActive(); - } - - @Rpc(description = "Checks whether A2DP audio routing to the Bluetooth headset is on or off.") - public Boolean audioIsBluetoothA2dpOn() { - return mAudio.isBluetoothA2dpOn(); - } - - @Rpc(description = "Request audio focus for sl4a.") - public Boolean audioRequestAudioFocus() { - int status = mAudio.requestAudioFocus(mFocusChangeListener, - AudioManager.STREAM_MUSIC, - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); - if (status == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { - mIsFocused = true; - return true; - } - mIsFocused = false; - return false; - } - - @Rpc(description = "Whether sl4a has the audio focus or not.") - public Boolean audioIsFocused() { - return mIsFocused; - } - - @Override - public void shutdown() { - mAudio.abandonAudioFocus(mFocusChangeListener); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaButtonCallback.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaButtonCallback.java deleted file mode 100644 index fc7c11e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaButtonCallback.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import android.content.Intent; -import android.media.session.MediaSession; -import android.os.Bundle; -import android.view.KeyEvent; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; - -public class MediaButtonCallback extends MediaSession.Callback { - private final EventFacade mEventFacade; - public MediaButtonCallback(EventFacade eventFacade) { - this.mEventFacade = eventFacade; - } - private void handleKeyEvent(KeyEvent event) { - int keyCode = event.getKeyCode(); - Log.d("Received ACTION_DOWN with keycode " + keyCode); - Bundle msg = new Bundle(); - if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY) { - msg.putString("ButtonPressed", "Play"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE) { - msg.putString("ButtonPressed", "Pause"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) { - msg.putString("ButtonPressed", "PlayPause"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP) { - msg.putString("ButtonPressed", "Stop"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_NEXT) { - msg.putString("ButtonPressed", "Next"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS) { - msg.putString("ButtonPressed", "Previous"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) { - msg.putString("ButtonPressed", "Forward"); - } else if (keyCode == KeyEvent.KEYCODE_MEDIA_REWIND) { - msg.putString("ButtonPressed", "Rewind"); - } - Log.d("Sending MediaButton event with ButtonPressed value " - + msg.getString("ButtonPressed")); - this.mEventFacade.postEvent("MediaButton", msg); - } - - @Override - public boolean onMediaButtonEvent(Intent mediaButtonIntent) { - String action = mediaButtonIntent.getAction(); - Log.d("Received intent with action " + action); - if (action.equals(Intent.ACTION_MEDIA_BUTTON)) { - KeyEvent event = (KeyEvent) mediaButtonIntent - .getParcelableExtra(Intent.EXTRA_KEY_EVENT); - int keyAction = event.getAction(); - Log.d("Received KeyEvent with action " + keyAction); - if (keyAction == KeyEvent.ACTION_DOWN) { - handleKeyEvent(event); - } else if (keyAction == KeyEvent.ACTION_UP) { - handleKeyEvent(event); - } - return true; - } - return super.onMediaButtonEvent(mediaButtonIntent); - } -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaPlayerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaPlayerFacade.java deleted file mode 100644 index 3925a38..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaPlayerFacade.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import android.app.Service; -import android.media.MediaPlayer; -import android.net.Uri; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; - -/** - * This facade exposes basic mediaPlayer functionality. <br> - * <br> - * <b>Usage Notes:</b><br> - * mediaPlayerFacade maintains a list of media streams, identified by a user supplied tag. If the - * tag is null or blank, this tag defaults to "default"<br> - * Basic operation is: mediaPlayOpen("file:///sdcard/MP3/sample.mp3","mytag",true)<br> - * This will look for a media file at /sdcard/MP3/sample.mp3. Other urls should work. If the file - * exists and is playable, this will return a true otherwise it will return a false. <br> - * If play=true, then the media file will play immediately, otherwise it will wait for a - * {@link #mediaPlayStart mediaPlayerStart} command. <br> - * When done with the resource, use {@link #mediaPlayClose mediaPlayClose} <br> - * You can get information about the loaded media with {@link #mediaPlayInfo mediaPlayInfo} This - * returns a map with the following elements: - * <ul> - * <li>"tag" - user supplied tag identifying this mediaPlayer. - * <li>"loaded" - true if loaded, false if not. If false, no other elements are returned. - * <li>"duration" - length of the media in milliseconds. - * <li>"position" - current position of playback in milliseconds. Controlled by - * {@link #mediaPlaySeek mediaPlaySeek} - * <li>"isplaying" - shows whether media is playing. Controlled by {@link #mediaPlayPause - * mediaPlayPause} and {@link #mediaPlayStart mediaPlayStart} - * <li>"url" - the url used to open this media. - * <li>"looping" - whether media will loop. Controlled by {@link #mediaPlaySetLooping - * mediaPlaySetLooping} - * </ul> - * <br> - * You can use {@link #mediaPlayList mediaPlayList} to get a list of the loaded tags. <br> - * {@link #mediaIsPlaying mediaIsPlaying} will return true if the media is playing.<br> - * <b>Events:</b><br> - * A playing media will throw a <b>"media"</b> event on completion. NB: In remote mode, a media file - * will continue playing after the script has finished unless an explicit {@link #mediaPlayClose - * mediaPlayClose} event is called. - * - * @author Robbie Matthews (rjmatthews62@gmail.com) - */ - -public class MediaPlayerFacade extends RpcReceiver implements MediaPlayer.OnCompletionListener { - - private final Service mService; - static private final Map<String, MediaPlayer> mPlayers = new Hashtable<String, MediaPlayer>(); - static private final Map<String, String> mUrls = new Hashtable<String, String>(); - - private final EventFacade mEventFacade; - - public MediaPlayerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mEventFacade = manager.getReceiver(EventFacade.class); - } - - private String getDefault(String tag) { - return (tag == null || tag.equals("")) ? "default" : tag; - } - - private MediaPlayer getPlayer(String tag) { - tag = getDefault(tag); - return mPlayers.get(tag); - } - - private String getUrl(String tag) { - tag = getDefault(tag); - return mUrls.get(tag); - } - - private void putMp(String tag, MediaPlayer player, String url) { - tag = getDefault(tag); - mPlayers.put(tag, player); - mUrls.put(tag, url); - } - - private void removeMp(String tag) { - tag = getDefault(tag); - MediaPlayer player = mPlayers.get(tag); - if (player != null) { - player.stop(); - player.release(); - } - mPlayers.remove(tag); - mUrls.remove(tag); - } - - @Rpc(description = "Open a media file", returns = "true if play successful") - public synchronized boolean mediaPlayOpen(@RpcParameter(name = "url", - description = "url of media resource") - String url, @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag, @RpcParameter(name = "play", description = "start playing immediately") - @RpcDefault(value = "true") - Boolean play) { - removeMp(tag); - MediaPlayer player = getPlayer(tag); - player = MediaPlayer.create(mService, Uri.parse(url)); - if (player != null) { - putMp(tag, player, url); - player.setOnCompletionListener(this); - if (play) { - player.start(); - } - } - return player != null; - } - - @Rpc(description = "pause playing media file", returns = "true if successful") - public synchronized boolean mediaPlayPause( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - if (player == null) { - return false; - } - player.pause(); - return true; - } - - @Rpc(description = "Start playing media file.", returns = "true if successful") - public synchronized boolean mediaPlayStart( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - if (player == null) { - return false; - } - player.start(); - return mediaIsPlaying(tag); - } - - @Rpc(description = "Stop playing media file.", returns = "true if successful") - public synchronized boolean mediaPlayStop( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - if (player == null) { - return false; - } - player.stop(); - return !mediaIsPlaying(tag) && player.getCurrentPosition() == 0; - } - - @Rpc(description = "Stop all players.") - public synchronized void mediaPlayStopAll() { - for (MediaPlayer p : mPlayers.values()) { - p.stop(); - } - } - - @Rpc(description = "Seek To Position", returns = "New Position (in ms)") - public synchronized int mediaPlaySeek(@RpcParameter(name = "msec", - description = "Position in millseconds") - Integer msec, @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - if (player == null) { - return 0; - } - player.seekTo(msec); - return player.getCurrentPosition(); - } - - @Rpc(description = "Close media file", returns = "true if successful") - public synchronized boolean mediaPlayClose( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) throws Exception { - if (!mPlayers.containsKey(tag)) { - return false; - } - removeMp(tag); - return true; - } - - @Rpc(description = "Checks if media file is playing.", returns = "true if playing") - public synchronized boolean mediaIsPlaying( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - return (player == null) ? false : player.isPlaying(); - } - - @Rpc(description = "Information on current media", returns = "Media Information") - public synchronized Map<String, Object> mediaPlayGetInfo( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - Map<String, Object> result = new HashMap<String, Object>(); - MediaPlayer player = getPlayer(tag); - result.put("tag", getDefault(tag)); - if (player == null) { - result.put("loaded", false); - } else { - result.put("loaded", true); - result.put("duration", player.getDuration()); - result.put("position", player.getCurrentPosition()); - result.put("isplaying", player.isPlaying()); - result.put("url", getUrl(tag)); - result.put("looping", player.isLooping()); - } - return result; - } - - @Rpc(description = "Lists currently loaded media", returns = "List of Media Tags") - public Set<String> mediaPlayList() { - return mPlayers.keySet(); - } - - @Rpc(description = "Set Looping", returns = "True if successful") - public synchronized boolean mediaPlaySetLooping(@RpcParameter(name = "enabled") - @RpcDefault(value = "true") - Boolean enabled, @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag) { - MediaPlayer player = getPlayer(tag); - if (player == null) { - return false; - } - player.setLooping(enabled); - return true; - } - - @Rpc(description = "Checks if media file is playing.", returns = "true if playing") - public synchronized void mediaSetNext( - @RpcParameter(name = "tag", description = "string identifying resource") - @RpcDefault(value = "default") - String tag, - @RpcParameter(name = "next", description = "tag of the next track to play.") - String next) { - MediaPlayer player = getPlayer(tag); - MediaPlayer nPlayer = getPlayer(next); - if (player == null) { - throw new NullPointerException("Non-existent player tag " + tag); - } - if (nPlayer == null) { - throw new NullPointerException("Non-existent player tag " + next); - } - player.setNextMediaPlayer(nPlayer); - } - - @Override - public synchronized void shutdown() { - for (String key : mPlayers.keySet()) { - MediaPlayer player = mPlayers.get(key); - if (player != null) { - player.stop(); - player.release(); - player = null; - } - } - mPlayers.clear(); - mUrls.clear(); - } - - @Override - public void onCompletion(MediaPlayer player) { - String tag = getTag(player); - if (tag != null) { - Map<String, Object> data = new HashMap<String, Object>(); - data.put("action", "complete"); - data.put("tag", tag); - mEventFacade.postEvent("media", data); - } - } - - private String getTag(MediaPlayer player) { - for (Entry<String, MediaPlayer> m : mPlayers.entrySet()) { - if (m.getValue() == player) { - return m.getKey(); - } - } - return null; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaRecorderFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaRecorderFacade.java deleted file mode 100644 index ee67fe6..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaRecorderFacade.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import android.app.Service; -import android.content.Intent; -import android.media.MediaRecorder; -import android.net.Uri; -import android.provider.MediaStore; -import android.view.SurfaceHolder; -import android.view.SurfaceHolder.Callback; -import android.view.SurfaceView; -import android.view.WindowManager; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.AndroidFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * A facade for recording media. - * - * Guidance notes: Use e.g. '/sdcard/file.ext' for your media destination file. A file extension of - * mpg will use the default settings for format and codec (often h263 which won't work with common - * PC media players). A file extension of mp4 or 3gp will use the appropriate format with the (more - * common) h264 codec. A video player such as QQPlayer (from the android market) plays both codecs - * and uses the composition matrix (embedded in the video file) to correct for image rotation. Many - * PC based media players ignore this matrix. Standard video sizes may be specified. - * - * @author Felix Arends (felix.arends@gmail.com) - * @author Damon Kohler (damonkohler@gmail.com) - * @author John Karwatzki (jokar49@gmail.com) - */ -public class MediaRecorderFacade extends RpcReceiver { - - private final MediaRecorder mMediaRecorder = new MediaRecorder(); - private final Service mService; - - public MediaRecorderFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - } - - @Rpc(description = "Records audio from the microphone and saves it to the given location.") - public void recorderStartMicrophone(@RpcParameter(name = "targetPath") String targetPath) - throws IOException { - startAudioRecording(targetPath, MediaRecorder.AudioSource.MIC); - } - - @Rpc(description = "Records video from the camera and saves it to the given location. " - + "\nDuration specifies the maximum duration of the recording session. " - + "\nIf duration is 0 this method will return and the recording will only be stopped " - + "\nwhen recorderStop is called or when a scripts exits. " - + "\nOtherwise it will block for the time period equal to the duration argument." - + "\nvideoSize: 0=160x120, 1=320x240, 2=352x288, 3=640x480, 4=800x480.") - public void recorderStartVideo(@RpcParameter(name = "targetPath") String targetPath, - @RpcParameter(name = "duration") @RpcDefault("0") Integer duration, - @RpcParameter(name = "videoSize") @RpcDefault("1") Integer videoSize) throws Exception { - int ms = convertSecondsToMilliseconds(duration); - startVideoRecording(new File(targetPath), ms, videoSize); - } - - private void startVideoRecording(File file, int milliseconds, int videoSize) throws Exception { - mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); - - int audioSource = MediaRecorder.AudioSource.MIC; - try { - Field source = Class.forName("android.media.MediaRecorder$AudioSource").getField("CAMCORDER"); - source.getInt(null); - } catch (Exception e) { - Log.e(e); - } - int xSize; - int ySize; - switch (videoSize) { - case 0: - xSize = 160; - ySize = 120; - break; - case 1: - xSize = 320; - ySize = 240; - break; - case 2: - xSize = 352; - ySize = 288; - break; - case 3: - xSize = 640; - ySize = 480; - break; - case 4: - xSize = 800; - ySize = 480; - break; - default: - xSize = 320; - ySize = 240; - break; - } - - mMediaRecorder.setAudioSource(audioSource); - String extension = file.toString().split("\\.")[1]; - if (extension.equals("mp4")) { - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); - mMediaRecorder.setVideoSize(xSize, ySize); - mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); - } else if (extension.equals("3gp")) { - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); - mMediaRecorder.setVideoSize(xSize, ySize); - mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); - } else { - - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); - mMediaRecorder.setVideoSize(xSize, ySize); - mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); - } - - mMediaRecorder.setOutputFile(file.getAbsolutePath()); - if (milliseconds > 0) { - mMediaRecorder.setMaxDuration(milliseconds); - } - FutureActivityTask<Exception> prepTask = prepare(); - mMediaRecorder.start(); - if (milliseconds > 0) { - new CountDownLatch(1).await(milliseconds, TimeUnit.MILLISECONDS); - } - prepTask.finish(); - } - - @Rpc(description = "Records video (and optionally audio) from the camera and saves it to the given location. " - + "\nDuration specifies the maximum duration of the recording session. " - + "\nIf duration is not provided this method will return immediately and the recording will only be stopped " - + "\nwhen recorderStop is called or when a scripts exits. " - + "\nOtherwise it will block for the time period equal to the duration argument.") - public void recorderCaptureVideo(@RpcParameter(name = "targetPath") String targetPath, - @RpcParameter(name = "duration") @RpcOptional Integer duration, - @RpcParameter(name = "recordAudio") @RpcDefault("true") Boolean recordAudio) throws Exception { - int ms = convertSecondsToMilliseconds(duration); - startVideoRecording(new File(targetPath), ms, recordAudio); - } - - private void startVideoRecording(File file, int milliseconds, boolean withAudio) throws Exception { - mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); - if (withAudio) { - int audioSource = MediaRecorder.AudioSource.MIC; - try { - Field source = - Class.forName("android.media.MediaRecorder$AudioSource").getField("CAMCORDER"); - audioSource = source.getInt(null); - } catch (Exception e) { - Log.e(e); - } - mMediaRecorder.setAudioSource(audioSource); - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); - } else { - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); - } - mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); - mMediaRecorder.setOutputFile(file.getAbsolutePath()); - if (milliseconds > 0) { - mMediaRecorder.setMaxDuration(milliseconds); - } - FutureActivityTask<Exception> prepTask = prepare(); - mMediaRecorder.start(); - if (milliseconds > 0) { - new CountDownLatch(1).await(milliseconds, TimeUnit.MILLISECONDS); - } - prepTask.finish(); - } - - private void startAudioRecording(String targetPath, int source) throws IOException { - mMediaRecorder.setAudioSource(source); - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); - mMediaRecorder.setOutputFile(targetPath); - mMediaRecorder.prepare(); - mMediaRecorder.start(); - } - - @Rpc(description = "Stops a previously started recording.") - public void recorderStop() { - mMediaRecorder.stop(); - mMediaRecorder.reset(); - } - - @Rpc(description = "Starts the video capture application to record a video and saves it to the specified path.") - public void startInteractiveVideoRecording(@RpcParameter(name = "path") final String path) { - Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - File file = new File(path); - intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); - AndroidFacade facade = mManager.getReceiver(AndroidFacade.class); - facade.startActivityForResult(intent); - } - - @Override - public void shutdown() { - mMediaRecorder.release(); - } - - // TODO(damonkohler): This shares a lot of code with the CameraFacade. It's probably worth moving - // it there. - private FutureActivityTask<Exception> prepare() throws Exception { - FutureActivityTask<Exception> task = new FutureActivityTask<Exception>() { - @Override - public void onCreate() { - super.onCreate(); - final SurfaceView view = new SurfaceView(getActivity()); - getActivity().setContentView(view); - getActivity().getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED); - view.getHolder().addCallback(new Callback() { - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - try { - mMediaRecorder.setPreviewDisplay(view.getHolder().getSurface()); - mMediaRecorder.prepare(); - setResult(null); - } catch (IOException e) { - setResult(e); - } - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - } - }); - } - }; - - FutureActivityTaskExecutor taskExecutor = - ((BaseApplication) mService.getApplication()).getTaskExecutor(); - taskExecutor.execute(task); - - Exception e = task.getResult(); - if (e != null) { - throw e; - } - return task; - } - - private int convertSecondsToMilliseconds(Integer seconds) { - if (seconds == null) { - return 0; - } - return (int) (seconds * 1000L); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaScannerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaScannerFacade.java deleted file mode 100644 index fd885c7..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaScannerFacade.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.media.MediaScanner; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Expose functionalities of MediaScanner related APIs. - */ -public class MediaScannerFacade extends RpcReceiver { - - private final Service mService; - private final MediaScanner mScanService; - private final EventFacade mEventFacade; - private final MediaScannerReceiver mReceiver; - - public MediaScannerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mScanService = new MediaScanner(mService, "external"); - mEventFacade = manager.getReceiver(EventFacade.class); - mReceiver = new MediaScannerReceiver(); - } - - public class MediaScannerReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if(action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) { - Log.d("Scan finished, posting event."); - mEventFacade.postEvent("MediaScanFinished", new Bundle()); - mService.unregisterReceiver(mReceiver); - } - } - } - - @Rpc(description = "Scan external storage for media files.") - public void mediaScanForFiles() { - mService.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, - Uri.parse("file://" + Environment.getExternalStorageDirectory()))); - mService.registerReceiver(mReceiver, - new IntentFilter(Intent.ACTION_MEDIA_SCANNER_FINISHED)); - } - - @Rpc(description = "Scan for a media file.") - public void mediaScanForOneFile(@RpcParameter(name = "path") String path) { - mService.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(path))); - } - - @Override - public void shutdown() { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java deleted file mode 100644 index 130b392..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/media/MediaSessionFacade.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.media; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; - -import android.app.Service; -import android.content.ComponentName; -import android.content.Context; -import android.media.session.MediaController; -import android.media.session.MediaSession; -import android.media.session.MediaSessionManager; -import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener; -import android.media.session.PlaybackState; -import android.media.session.MediaSession.Callback; -import android.view.KeyEvent; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Expose functionalities of MediaSession related classes - * like MediaSession, MediaSessionManager, MediaController. - * - */ -public class MediaSessionFacade extends RpcReceiver { - - private final Service mService; - private final EventFacade mEventFacade; - private final MediaSession mSession; - private final MediaSessionManager mManager; - private final OnActiveSessionsChangedListener mSessionListener; - private final Callback mCallback; - - private List<MediaController> mActiveControllers = null; - - public MediaSessionFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mEventFacade = manager.getReceiver(EventFacade.class); - Log.d("Creating MediaSession."); - mSession = new MediaSession(mService, "SL4A"); - mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); - mManager = (MediaSessionManager) mService.getSystemService(Context.MEDIA_SESSION_SERVICE); - mCallback = new MediaButtonCallback(mEventFacade); - mSessionListener = new MediaSessionListener(); - mManager.addOnActiveSessionsChangedListener(mSessionListener, - new ComponentName(mService.getPackageName(), this.getClass().getName())); - mSession.setActive(true); - } - - private class MediaSessionListener implements OnActiveSessionsChangedListener { - - @Override - public void onActiveSessionsChanged(List<MediaController> controllers) { - Log.d("Active MediaSessions have changed. Update current controller."); - int size = controllers.size(); - for (int i = 0; i < size; i++) { - MediaController controller = controllers.get(i); - long flags = controller.getFlags(); - // We only care about sessions that handle transport controls, - // which will be true for apps using RCC - if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) { - Log.d("The current active MediaSessions is " + controller.getTag()); - return; - } - } - } - } - - @Rpc(description = "Retrieve a list of active sessions.") - public List<String> mediaGetActiveSessions() { - mActiveControllers = mManager.getActiveSessions(null); - List<String> results = new ArrayList<String>(); - for (MediaController mc : mActiveControllers) { - results.add(mc.getTag()); - } - return results; - } - - @Rpc(description = "Add callback to media session.") - public void mediaSessionAddCallback() { - MainThread.run(mService, new Callable<Object>() { - @Override - public Object call() throws Exception { - Log.d("Adding callback."); - mSession.setCallback(mCallback); - PlaybackState.Builder bob = new PlaybackState.Builder(); - bob.setActions(PlaybackState.ACTION_PLAY | - PlaybackState.ACTION_PAUSE | - PlaybackState.ACTION_STOP); - bob.setState(PlaybackState.STATE_PLAYING, 0, 1); - mSession.setPlaybackState(bob.build()); - return null; - } - }); - } - - @Rpc(description = "Whether current media session is active.") - public Boolean mediaSessionIsActive() { - return mSession.isActive(); - } - - @Rpc(description = "Simulate a media key press.") - public void mediaDispatchMediaKeyEvent(String key) { - int keyCode; - if (key.equals("Play")) { - keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; - } else if (key.equals("Pause")) { - keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE; - } else if (key.equals("Stop")) { - keyCode = KeyEvent.KEYCODE_MEDIA_STOP; - } else if (key.equals("Next")) { - keyCode = KeyEvent.KEYCODE_MEDIA_NEXT; - } else if (key.equals("Previous")) { - keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; - } else if (key.equals("Forward")) { - keyCode = KeyEvent.KEYCODE_MEDIA_FAST_FORWARD; - } else if (key.equals("Rewind")) { - keyCode = KeyEvent.KEYCODE_MEDIA_REWIND; - } else { - Log.d("Unrecognized media key."); - return; - } - KeyEvent keyDown = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); - KeyEvent keyUp = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); - mManager.dispatchMediaKeyEvent(keyDown); - mManager.dispatchMediaKeyEvent(keyUp); - } - - private MediaController getMediaController(int idx) { - return mActiveControllers.get(idx); - } - - @Rpc(description = "Call Play on the currently active media session.") - public void mediaSessionPlay(@RpcParameter(name = "index") @RpcDefault(value = "0") - Integer idx) { - getMediaController(idx).getTransportControls().play(); - } - - @Rpc(description = "Call Pause on the currently active media session.") - public void mediaSessionPause(@RpcParameter(name = "index") @RpcDefault(value = "0") - Integer idx) { - getMediaController(idx).getTransportControls().pause(); - } - - @Rpc(description = "Call Stop on the currently active media session.") - public void mediaSessionStop(@RpcParameter(name = "index") @RpcDefault(value = "0") - Integer idx) { - getMediaController(idx).getTransportControls().stop(); - } - - @Rpc(description = "Call Next on the currently active media session.") - public void mediaSessionNext(@RpcParameter(name = "index") @RpcDefault(value = "0") - Integer idx) { - getMediaController(idx).getTransportControls().skipToNext(); - } - - @Override - public void shutdown() { - mSession.setCallback(null); - mSession.release(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/CarrierConfigFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/CarrierConfigFacade.java deleted file mode 100644 index fc4d061..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/CarrierConfigFacade.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import android.app.Activity; -import android.app.Service; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.telephony.CarrierConfigManager; - -import com.googlecode.android_scripting.facade.AndroidFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.rpc.RpcOptional; - -public class CarrierConfigFacade extends RpcReceiver { - private final Service mService; - private final AndroidFacade mAndroidFacade; - private final CarrierConfigManager mCarrierConfigManager; - - public CarrierConfigFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - mCarrierConfigManager = - (CarrierConfigManager)mService.getSystemService(Context.CARRIER_CONFIG_SERVICE); - } - - @Rpc(description = "Tethering Entitlement Check") - public boolean carrierConfigIsTetheringModeAllowed(String mode, Integer timeout) { - String[] mProvisionApp = mService.getResources().getStringArray( - com.android.internal.R.array.config_mobile_hotspot_provision_app); - /* following check defined in - frameworks/base/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java - isProvisioningNeeded - */ - if ((mProvisionApp == null) || (mProvisionApp.length != 2)){ - Log.d("carrierConfigIsTetheringModeAllowed: no check is present."); - return true; - } - Log.d("carrierConfigIsTetheringModeAllowed mProvisionApp 0 " + mProvisionApp[0]); - Log.d("carrierConfigIsTetheringModeAllowed mProvisionApp 1 " + mProvisionApp[1]); - - /* defined in frameworks/base/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java - public static final int INVALID = -1; - public static final int WIFI_TETHERING = 0; - public static final int USB_TETHERING = 1; - public static final int BLUETOOTH_TETHERING = 2; - */ - // TODO: b/26273844 need to use android.settingslib.TetherUtil to - // replace those private defines. - final int INVALID = -1; - final int WIFI_TETHERING = 0; - final int USB_TETHERING = 1; - final int BLUETOOTH_TETHERING = 2; - - /* defined in packages/apps/Settings/src/com/android/settings/TetherSettings.java - private static final int PROVISION_REQUEST = 0; - */ - final int PROVISION_REQUEST = 0; - - int mTetherChoice = INVALID; - if (mode.equals("wifi")){ - mTetherChoice = WIFI_TETHERING; - } else if (mode.equals("usb")) { - mTetherChoice = USB_TETHERING; - } else if (mode.equals("bluetooth")) { - mTetherChoice = BLUETOOTH_TETHERING; - } - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setClassName(mProvisionApp[0], mProvisionApp[1]); - intent.putExtra("TETHER_TYPE", mTetherChoice); - int result; - try{ - result = mAndroidFacade.startActivityForResultCodeWithTimeout( - intent, PROVISION_REQUEST, timeout); - } catch (Exception e) { - Log.d("phoneTetherCheck exception" + e.toString()); - return false; - } - - if (result == Activity.RESULT_OK) { - return true; - } else { - return false; - } - } - - @Override - public void shutdown() { - - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/ImsManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/ImsManagerFacade.java deleted file mode 100755 index 0a67c34..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/ImsManagerFacade.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import android.app.Service; -import android.content.Context; -import android.content.SharedPreferences; -import android.telephony.SubscriptionManager; - -import com.android.ims.ImsException; -import com.android.ims.ImsManager; -import com.android.ims.ImsConfig; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Exposes ImsManager functionality. - */ -public class ImsManagerFacade extends RpcReceiver { - - private final Service mService; - private final Context mContext; - private ImsManager mImsManager; - - public ImsManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContext = mService.getBaseContext(); - mImsManager = ImsManager.getInstance(mContext, - SubscriptionManager.getDefaultVoicePhoneId()); - } - - @Rpc(description = "Return True if Enhanced 4g Lte mode is enabled by platform.") - public boolean imsIsEnhanced4gLteModeSettingEnabledByPlatform() { - return ImsManager.isVolteEnabledByPlatform(mContext); - } - - @Rpc(description = "Return True if Enhanced 4g Lte mode is enabled by user.") - public boolean imsIsEnhanced4gLteModeSettingEnabledByUser() { - return ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext); - } - - @Rpc(description = "Set Enhanced 4G mode.") - public void imsSetEnhanced4gMode( - @RpcParameter(name = "enable") Boolean enable) { - ImsManager.setEnhanced4gLteModeSetting(mContext, enable); - } - - @Rpc(description = "Check for VoLTE Provisioning.") - public boolean imsIsVolteProvisionedOnDevice() { - return mImsManager.isVolteProvisionedOnDevice(mContext); - } - - @Rpc(description = "Set Modem Provisioning for VoLTE") - public void imsSetVolteProvisioning( - @RpcParameter(name = "enable") Boolean enable) - throws ImsException{ - mImsManager.getConfigInterface().setProvisionedValue( - ImsConfig.ConfigConstants.VLT_SETTING_ENABLED, - enable? 1 : 0); - } - - /************************** - * Begin WFC Calling APIs - **************************/ - - @Rpc(description = "Return True if WiFi Calling is enabled for platform.") - public boolean imsIsWfcEnabledByPlatform() { - return ImsManager.isWfcEnabledByPlatform(mContext); - } - - @Rpc(description = "Set whether or not WFC is enabled during roaming") - public void imsSetWfcRoamingSetting( - @RpcParameter(name = "enable") - Boolean enable) { - ImsManager.setWfcRoamingSetting(mContext, enable); - - } - - @Rpc(description = "Return True if WiFi Calling is enabled during roaming.") - public boolean imsIsWfcRoamingEnabledByUser() { - return ImsManager.isWfcRoamingEnabledByUser(mContext); - } - - @Rpc(description = "Set the Wifi Calling Mode of operation") - public void imsSetWfcMode( - @RpcParameter(name = "mode") - String mode) - throws IllegalArgumentException { - - int mode_val; - - switch (mode.toUpperCase()) { - case TelephonyConstants.WFC_MODE_WIFI_ONLY: - mode_val = - ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY; - break; - case TelephonyConstants.WFC_MODE_CELLULAR_PREFERRED: - mode_val = - ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED; - break; - case TelephonyConstants.WFC_MODE_WIFI_PREFERRED: - mode_val = - ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED; - break; - case TelephonyConstants.WFC_MODE_DISABLED: - if (ImsManager.isWfcEnabledByPlatform(mContext) && - ImsManager.isWfcEnabledByUser(mContext) == true) { - ImsManager.setWfcSetting(mContext, false); - } - return; - default: - throw new IllegalArgumentException("Invalid WfcMode"); - } - - ImsManager.setWfcMode(mContext, mode_val); - if (ImsManager.isWfcEnabledByPlatform(mContext) && - ImsManager.isWfcEnabledByUser(mContext) == false) { - ImsManager.setWfcSetting(mContext, true); - } - - return; - } - - @Rpc(description = "Return current WFC Mode if Enabled.") - public String imsGetWfcMode() { - if(ImsManager.isWfcEnabledByUser(mContext) == false) { - return TelephonyConstants.WFC_MODE_DISABLED; - } - return TelephonyUtils.getWfcModeString( - ImsManager.getWfcMode(mContext)); - } - - @Rpc(description = "Return True if WiFi Calling is enabled by user.") - public boolean imsIsWfcEnabledByUser() { - return ImsManager.isWfcEnabledByUser(mContext); - } - - @Rpc(description = "Set whether or not WFC is enabled") - public void imsSetWfcSetting( - @RpcParameter(name = "enable") Boolean enable) { - ImsManager.setWfcSetting(mContext,enable); - } - - /************************** - * Begin VT APIs - **************************/ - - @Rpc(description = "Return True if Video Calling is enabled by the platform.") - public boolean imsIsVtEnabledByPlatform() { - return ImsManager.isVtEnabledByPlatform(mContext); - } - - @Override - public void shutdown() { - - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java deleted file mode 100644 index 965735a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java +++ /dev/null @@ -1,1416 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import java.util.HashMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import android.telecom.Call; -import android.telecom.Call.Details; -import android.telecom.CallAudioState; -import android.telecom.Conference; -import android.telecom.Connection; -import android.telecom.ConnectionService; -import android.telecom.InCallService; -import android.telecom.Phone; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.telecom.VideoProfile.CameraCapabilities; - -import com.googlecode.android_scripting.Log; - -import com.googlecode.android_scripting.facade.EventFacade; - -public class InCallServiceImpl extends InCallService { - - private static InCallServiceImpl mService = null; - - public static InCallServiceImpl getService() { - return mService; - } - - private static Object mLock = new Object(); - - // Provides a return value for getCallState when no call is active - public static final int STATE_INVALID = -1; - - // Provides a return value for getCallQuality when input is invalid - public static final int QUALITY_INVALID = -1; - - // Provides a return value for getAudioRoute when input is invalid - public static final int INVALID_AUDIO_ROUTE = -1; - - public static final int VIDEO_STATE_AUDIO_ONLY = VideoProfile.STATE_AUDIO_ONLY; - - public static final int VIDEO_STATE_TX_ENABLED = VideoProfile.STATE_TX_ENABLED; - - public static final int VIDEO_STATE_RX_ENABLED = VideoProfile.STATE_RX_ENABLED; - - public static final int VIDEO_STATE_BIDIRECTIONAL = VideoProfile.STATE_BIDIRECTIONAL; - - public static final int VIDEO_STATE_TX_PAUSED = - VideoProfile.STATE_TX_ENABLED | VideoProfile.STATE_PAUSED; - - public static final int VIDEO_STATE_RX_PAUSED = - VideoProfile.STATE_RX_ENABLED | VideoProfile.STATE_PAUSED; - - public static final int VIDEO_STATE_BIDIRECTIONAL_PAUSED = - VideoProfile.STATE_BIDIRECTIONAL | VideoProfile.STATE_PAUSED; - - // Container class to return the call ID along with the event - public class CallEvent<EventType> { - - private final String mCallId; - private final EventType mEvent; - - CallEvent(String callId, EventType event) { - mCallId = callId; - mEvent = event; - } - - public String getCallId() { - return mCallId; - } - - public EventType getEvent() { - return mEvent; - } - } - - // Currently the same as a call event... here for future use - public class VideoCallEvent<EventType> extends CallEvent<EventType> { - VideoCallEvent(String callId, EventType event) { - super(callId, event); - } - } - - private class CallCallback extends Call.Callback { - - // Invalid video state (valid >= 0) - public static final int STATE_INVALID = InCallServiceImpl.STATE_INVALID; - - public static final int EVENT_INVALID = -1; - public static final int EVENT_NONE = 0; - public static final int EVENT_STATE_CHANGED = 1 << 0; - public static final int EVENT_PARENT_CHANGED = 1 << 1; - public static final int EVENT_CHILDREN_CHANGED = 1 << 2; - public static final int EVENT_DETAILS_CHANGED = 1 << 3; - public static final int EVENT_CANNED_TEXT_RESPONSES_LOADED = 1 << 4; - public static final int EVENT_POST_DIAL_WAIT = 1 << 5; - public static final int EVENT_VIDEO_CALL_CHANGED = 1 << 6; - public static final int EVENT_CALL_DESTROYED = 1 << 7; - public static final int EVENT_CONFERENCABLE_CALLS_CHANGED = 1 << 8; - - public static final int EVENT_ALL = EVENT_STATE_CHANGED | - EVENT_PARENT_CHANGED | - EVENT_CHILDREN_CHANGED | - EVENT_DETAILS_CHANGED | - EVENT_CANNED_TEXT_RESPONSES_LOADED | - EVENT_POST_DIAL_WAIT | - EVENT_VIDEO_CALL_CHANGED | - EVENT_DETAILS_CHANGED | - EVENT_CALL_DESTROYED | - EVENT_CONFERENCABLE_CALLS_CHANGED; - - private int mEvents; - private String mCallId; - - public CallCallback(String callId, int events) { - super(); - mEvents = events & EVENT_ALL; - mCallId = callId; - } - - public void startListeningForEvents(int events) { - mEvents |= events & EVENT_ALL; - } - - public void stopListeningForEvents(int events) { - mEvents &= ~(events & EVENT_ALL); - } - - @Override - public void onStateChanged( - Call call, int state) { - Log.d("CallCallback:onStateChanged()"); - if ((mEvents & EVENT_STATE_CHANGED) - == EVENT_STATE_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomCallStateChanged, - new CallEvent<String>(mCallId, getCallStateString(state))); - } - } - - @Override - public void onParentChanged( - Call call, Call parent) { - Log.d("CallCallback:onParentChanged()"); - if ((mEvents & EVENT_PARENT_CHANGED) - == EVENT_PARENT_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomCallParentChanged, - new CallEvent<String>(mCallId, getCallId(parent))); - } - } - - @Override - public void onChildrenChanged( - Call call, List<Call> children) { - Log.d("CallCallback:onChildrenChanged()"); - - if ((mEvents & EVENT_CHILDREN_CHANGED) - == EVENT_CHILDREN_CHANGED) { - List<String> childList = new ArrayList<String>(); - - for (Call child : children) { - childList.add(getCallId(child)); - } - servicePostEvent(TelephonyConstants.EventTelecomCallChildrenChanged, - new CallEvent<List<String>>(mCallId, childList)); - } - } - - @Override - public void onDetailsChanged( - Call call, Details details) { - Log.d("CallCallback:onDetailsChanged()"); - - if ((mEvents & EVENT_DETAILS_CHANGED) - == EVENT_DETAILS_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomCallDetailsChanged, - new CallEvent<Details>(mCallId, details)); - } - } - - @Override - public void onCannedTextResponsesLoaded( - Call call, List<String> cannedTextResponses) { - Log.d("CallCallback:onCannedTextResponsesLoaded()"); - if ((mEvents & EVENT_CANNED_TEXT_RESPONSES_LOADED) - == EVENT_CANNED_TEXT_RESPONSES_LOADED) { - servicePostEvent(TelephonyConstants.EventTelecomCallCannedTextResponsesLoaded, - new CallEvent<List<String>>(mCallId, cannedTextResponses)); - } - } - - @Override - public void onPostDialWait( - Call call, String remainingPostDialSequence) { - Log.d("CallCallback:onPostDialWait()"); - if ((mEvents & EVENT_POST_DIAL_WAIT) - == EVENT_POST_DIAL_WAIT) { - servicePostEvent(TelephonyConstants.EventTelecomCallPostDialWait, - new CallEvent<String>(mCallId, remainingPostDialSequence)); - } - } - - @Override - public void onVideoCallChanged( - Call call, InCallService.VideoCall videoCall) { - - /* - * There is a race condition such that the lifetime of the VideoCall is not aligned with - * the lifetime of the underlying call object. We are using the onVideoCallChanged - * method as a way of determining the lifetime of the VideoCall object rather than - * onCallAdded/onCallRemoved. - */ - Log.d("CallCallback:onVideoCallChanged()"); - - if (call != null) { - String callId = getCallId(call); - CallContainer cc = mCallContainerMap.get(callId); - if (cc == null) { - Log.d(String.format("Call container returned null for callId %s", callId)); - } - else { - synchronized (mLock) { - if (videoCall == null) { - Log.d("Yo dawg, I heard you like null video calls."); - // Try and see if the videoCall has been added/changed after firing the - // callback - // This probably won't work. - videoCall = call.getVideoCall(); - } - if (cc.getVideoCall() != videoCall) { - if (videoCall == null) { - // VideoCall object deleted - cc.updateVideoCall(null, null); - Log.d("Removing video call from call."); - } - else if (cc.getVideoCall() != null) { - // Somehow we have a mismatched VideoCall ID! - Log.d("Mismatched video calls for same call ID."); - } - else { - Log.d("Huzzah, we have a video call!"); - - VideoCallCallback videoCallCallback = - new VideoCallCallback(callId, VideoCallCallback.EVENT_NONE); - - videoCall.registerCallback(videoCallCallback); - - cc.updateVideoCall( - videoCall, - videoCallCallback); - } - } - else { - Log.d("Change to existing video call."); - } - - } - } - } - else { - Log.d("passed null call pointer to call callback"); - } - - if ((mEvents & EVENT_VIDEO_CALL_CHANGED) - == EVENT_VIDEO_CALL_CHANGED) { - // TODO: b/26273778 Need to determine what to return; - // probably not the whole video call - servicePostEvent(TelephonyConstants.EventTelecomCallVideoCallChanged, - new CallEvent<String>(mCallId, videoCall.toString())); - } - } - - @Override - public void onCallDestroyed(Call call) { - Log.d("CallCallback:onCallDestroyed()"); - - if ((mEvents & EVENT_CALL_DESTROYED) - == EVENT_CALL_DESTROYED) { - servicePostEvent(TelephonyConstants.EventTelecomCallDestroyed, - new CallEvent<Call>(mCallId, call)); - } - } - - @Override - public void onConferenceableCallsChanged( - Call call, List<Call> conferenceableCalls) { - Log.d("CallCallback:onConferenceableCallsChanged()"); - - if ((mEvents & EVENT_CONFERENCABLE_CALLS_CHANGED) - == EVENT_CONFERENCABLE_CALLS_CHANGED) { - List<String> confCallList = new ArrayList<String>(); - for (Call cc : conferenceableCalls) { - confCallList.add(getCallId(cc)); - } - servicePostEvent(TelephonyConstants.EventTelecomCallConferenceableCallsChanged, - new CallEvent<List<String>>(mCallId, confCallList)); - } - } - } - - private class VideoCallCallback extends InCallService.VideoCall.Callback { - - public static final int EVENT_INVALID = -1; - public static final int EVENT_NONE = 0; - public static final int EVENT_SESSION_MODIFY_REQUEST_RECEIVED = 1 << 0; - public static final int EVENT_SESSION_MODIFY_RESPONSE_RECEIVED = 1 << 1; - public static final int EVENT_SESSION_EVENT = 1 << 2; - public static final int EVENT_PEER_DIMENSIONS_CHANGED = 1 << 3; - public static final int EVENT_VIDEO_QUALITY_CHANGED = 1 << 4; - public static final int EVENT_DATA_USAGE_CHANGED = 1 << 5; - public static final int EVENT_CAMERA_CAPABILITIES_CHANGED = 1 << 6; - public static final int EVENT_ALL = - EVENT_SESSION_MODIFY_REQUEST_RECEIVED | - EVENT_SESSION_MODIFY_RESPONSE_RECEIVED | - EVENT_SESSION_EVENT | - EVENT_PEER_DIMENSIONS_CHANGED | - EVENT_VIDEO_QUALITY_CHANGED | - EVENT_DATA_USAGE_CHANGED | - EVENT_CAMERA_CAPABILITIES_CHANGED; - - private String mCallId; - private int mEvents; - - public VideoCallCallback(String callId, int listeners) { - - mCallId = callId; - mEvents = listeners & EVENT_ALL; - } - - public void startListeningForEvents(int events) { - Log.d(String.format( - "VideoCallCallback(%s):startListeningForEvents(%x): events:%x", - mCallId, events, mEvents)); - - mEvents |= events & EVENT_ALL; - - } - - public void stopListeningForEvents(int events) { - mEvents &= ~(events & EVENT_ALL); - } - - @Override - public void onSessionModifyRequestReceived(VideoProfile videoProfile) { - Log.d(String.format("VideoCallCallback(%s):onSessionModifyRequestReceived()", mCallId)); - - if ((mEvents & EVENT_SESSION_MODIFY_REQUEST_RECEIVED) - == EVENT_SESSION_MODIFY_REQUEST_RECEIVED) { - servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionModifyRequestReceived, - new VideoCallEvent<VideoProfile>(mCallId, videoProfile)); - } - - } - - @Override - public void onSessionModifyResponseReceived(int status, - VideoProfile requestedProfile, VideoProfile responseProfile) { - Log.d("VideoCallCallback:onSessionModifyResponseReceived()"); - - if ((mEvents & EVENT_SESSION_MODIFY_RESPONSE_RECEIVED) - == EVENT_SESSION_MODIFY_RESPONSE_RECEIVED) { - - HashMap<String, VideoProfile> smrrInfo = new HashMap<String, VideoProfile>(); - - smrrInfo.put("RequestedProfile", requestedProfile); - smrrInfo.put("ResponseProfile", responseProfile); - - servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionModifyResponseReceived, - new VideoCallEvent<HashMap<String, VideoProfile>>(mCallId, smrrInfo)); - } - } - - @Override - public void onCallSessionEvent(int event) { - Log.d("VideoCallCallback:onCallSessionEvent()"); - - String eventString = getVideoCallSessionEventString(event); - - if ((mEvents & EVENT_SESSION_EVENT) - == EVENT_SESSION_EVENT) { - servicePostEvent(TelephonyConstants.EventTelecomVideoCallSessionEvent, - new VideoCallEvent<String>(mCallId, eventString)); - } - } - - @Override - public void onPeerDimensionsChanged(int width, int height) { - Log.d("VideoCallCallback:onPeerDimensionsChanged()"); - - if ((mEvents & EVENT_PEER_DIMENSIONS_CHANGED) - == EVENT_PEER_DIMENSIONS_CHANGED) { - - HashMap<String, Integer> temp = new HashMap<String, Integer>(); - temp.put("Width", width); - temp.put("Height", height); - - servicePostEvent(TelephonyConstants.EventTelecomVideoCallPeerDimensionsChanged, - new VideoCallEvent<HashMap<String, Integer>>(mCallId, temp)); - } - } - - @Override - public void onVideoQualityChanged(int videoQuality) { - Log.d("VideoCallCallback:onVideoQualityChanged()"); - - if ((mEvents & EVENT_VIDEO_QUALITY_CHANGED) - == EVENT_VIDEO_QUALITY_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomVideoCallVideoQualityChanged, - new VideoCallEvent<String>(mCallId, - getVideoCallQualityString(videoQuality))); - } - } - - @Override - public void onCallDataUsageChanged(long dataUsage) { - Log.d("VideoCallCallback:onCallDataUsageChanged()"); - - if ((mEvents & EVENT_DATA_USAGE_CHANGED) - == EVENT_DATA_USAGE_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomVideoCallDataUsageChanged, - new VideoCallEvent<Long>(mCallId, dataUsage)); - } - } - - @Override - public void onCameraCapabilitiesChanged( - CameraCapabilities cameraCapabilities) { - Log.d("VideoCallCallback:onCallDataUsageChanged()"); - - if ((mEvents & EVENT_DATA_USAGE_CHANGED) - == EVENT_DATA_USAGE_CHANGED) { - servicePostEvent(TelephonyConstants.EventTelecomVideoCallCameraCapabilities, - new VideoCallEvent<CameraCapabilities>(mCallId, cameraCapabilities)); - } - - } - } - - /* - * Container Class for Call and CallCallback Objects - */ - private class CallContainer { - - /* - * Call Container Members - */ - - private Call mCall; - private CallCallback mCallCallback; - private VideoCall mVideoCall; - private VideoCallCallback mVideoCallCallback; - - /* - * Call Container Functions - */ - - public CallContainer(Call call, - CallCallback callback, - VideoCall videoCall, - VideoCallCallback videoCallCallback) { - mCall = call; - mCallCallback = callback; - mVideoCall = videoCall; - mVideoCallCallback = videoCallCallback; - } - - public Call getCall() { - return mCall; - } - - public CallCallback getCallback() { - return mCallCallback; - } - - public InCallService.VideoCall getVideoCall() { - return mVideoCall; - } - - public VideoCallCallback getVideoCallCallback() { - return mVideoCallCallback; - } - - public void updateVideoCall(VideoCall videoCall, VideoCallCallback videoCallCallback) { - if (videoCall == null && videoCallCallback != null) { - Log.d("UpdateVideoCall: videoCall and videoCallCallback are null."); - return; - } - mVideoCall = videoCall; - mVideoCallCallback = videoCallCallback; - } - } - - /* - * TODO: b/26272583 Refactor so that these are instance members of the - * incallservice. Then we can perform null checks using the design pattern - * of the "manager" classes. - */ - - private static EventFacade mEventFacade = null; - private static HashMap<String, CallContainer> mCallContainerMap = - new HashMap<String, CallContainer>(); - - @Override - public void onCallAdded(Call call) { - Log.d("onCallAdded: " + call.toString()); - String id = getCallId(call); - Log.d("Adding " + id); - CallCallback callCallback = new CallCallback(id, CallCallback.EVENT_NONE); - - call.registerCallback(callCallback); - - VideoCall videoCall = call.getVideoCall(); - VideoCallCallback videoCallCallback = null; - - if (videoCall != null) { - synchronized (mLock) { - if (getVideoCallById(id) == null) { - videoCallCallback = new VideoCallCallback(id, VideoCallCallback.EVENT_NONE); - videoCall.registerCallback(videoCallCallback); - } - } - } - else { - // No valid video object - Log.d("No Video Call provided to InCallService."); - } - - mCallContainerMap.put(id, - new CallContainer(call, - callCallback, - videoCall, - videoCallCallback)); - - /* - * Once we have a call active, anchor the inCallService instance as a psuedo-singleton. - * Because object lifetime is not guaranteed we shouldn't do this in the - * constructor/destructor. - */ - if (mService == null) { - mService = this; - } - else if (mService != this) { - Log.e("Multiple InCall Services Active in SL4A!"); - } - } - - @Override - public void onCallRemoved(Call call) { - Log.d("onCallRemoved: " + call.toString()); - String id = getCallId(call); - Log.d("Removing " + id); - - mCallContainerMap.remove(id); - - if (mCallContainerMap.size() == 0) { - mService = null; - } - } - - public static void setEventFacade(EventFacade facade) { - Log.d(String.format("setEventFacade(): Settings SL4A event facade to %s", - (facade != null) ? facade.toString() : "null")); - mEventFacade = facade; - } - - private static boolean servicePostEvent(String eventName, Object event) { - - if (mEventFacade == null) { - Log.d("servicePostEvent():SL4A eventFacade Is Null!!"); - return false; - } - - mEventFacade.postEvent(eventName, event); - - return true; - } - - public static String getCallId(Call call) { - if (call != null) { - return call.toString(); - } - else - return ""; - } - - public static String getVideoCallId(InCallServiceImpl.VideoCall videoCall) { - if (videoCall != null) - return videoCall.toString(); - else - return ""; - } - - private static Call getCallById(String callId) { - - CallContainer cc = mCallContainerMap.get(callId); - - if (cc != null) { - return cc.getCall(); - } - - return null; - } - - private static CallCallback getCallCallbackById(String callId) { - - CallContainer cc = mCallContainerMap.get(callId); - - if (cc != null) { - return cc.getCallback(); - } - - return null; - } - - private static InCallService.VideoCall getVideoCallById(String callId) { - - CallContainer cc = mCallContainerMap.get(callId); - - if (cc != null) { - return cc.getVideoCall(); - - } - - return null; - } - - private static VideoCallCallback - getVideoCallListenerById(String callId) { - - CallContainer cc = mCallContainerMap.get(callId); - - if (cc != null) { - return cc.getVideoCallCallback(); - } - - return null; - } - - /* - * Public Call/Phone Functions - */ - - public static void callDisconnect(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("callDisconnect: callId is null"); - return; - } - - c.disconnect(); - } - - public static void holdCall(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("holdCall: callId is null"); - return; - } - c.hold(); - } - - public static void mergeCallsInConference(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("mergeCallsInConference: callId is null"); - return; - } - c.mergeConference(); - } - - public static void splitCallFromConf(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("splitCallFromConf: callId is null"); - return; - } - c.splitFromConference(); - } - - public static void unholdCall(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("unholdCall: callId is null"); - return; - } - c.unhold(); - } - - public static void joinCallsInConf(String callIdOne, String callIdTwo) { - Call callOne = getCallById(callIdOne); - Call callTwo = getCallById(callIdTwo); - - if (callOne == null || callTwo == null) { - Log.d("joinCallsInConf: callOne or CallTwo is null"); - return; - } - - callOne.conference(callTwo); - } - - public static Set<String> getCallIdList() { - return mCallContainerMap.keySet(); - } - - public static void clearCallList() { - mCallContainerMap.clear(); - } - - public static String callGetState(String callId) { - Call c = getCallById(callId); - if (c == null) { - return getCallStateString(STATE_INVALID); - } - - return getCallStateString(c.getState()); - } - - public static Call.Details callGetDetails(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d(String.format("Couldn't find an active call with ID:%s", callId)); - return null; - } - - return c.getDetails(); - } - - public static List<String> callGetCallProperties(String callId) { - Call.Details details = callGetDetails(callId); - - if (details == null) { - return null; - } - - return getCallPropertiesString(details.getCallProperties()); - } - - public static List<String> callGetCallCapabilities(String callId) { - Call.Details details = callGetDetails(callId); - - if (details == null) { - return null; - } - - return getCallCapabilitiesString(details.getCallCapabilities()); - } - - @SuppressWarnings("deprecation") - public static void overrideProximitySensor(Boolean screenOn) { - InCallServiceImpl svc = getService(); - if (svc == null) { - Log.d("overrideProximitySensor: InCallServiceImpl is null."); - return; - } - - Phone phone = svc.getPhone(); - if (phone == null) { - Log.d("overrideProximitySensor: phone is null."); - return; - } - - phone.setProximitySensorOff(screenOn); - } - - public static CallAudioState serviceGetCallAudioState() { - InCallServiceImpl svc = getService(); - - if (svc != null) { - return svc.getCallAudioState(); - } - else { - return null; - } - } - - // Wonky name due to conflict with internal function - public static void serviceSetAudioRoute(String route) { - InCallServiceImpl svc = getService(); - - if (svc == null) { - Log.d("serviceSetAudioRoute: InCallServiceImpl is null."); - return; - } - - int r = getAudioRoute(route); - - Log.d(String.format("Setting Audio Route to %s:%d", route, r)); - - if (r == INVALID_AUDIO_ROUTE) { - Log.d(String.format("Invalid Audio route %s:%d", route, r)); - return; - } - svc.setAudioRoute(r); - } - - public static void callStartListeningForEvent(String callId, String strEvent) { - - CallCallback cl = getCallCallbackById(callId); - - if (cl == null) { - Log.d("callStartListeningForEvent: CallCallback is null."); - return; - } - - int event = getCallCallbackEvent(strEvent); - - if (event == CallCallback.EVENT_INVALID) { - Log.d("callStartListeningForEvent: event is invalid."); - return; - } - - cl.startListeningForEvents(event); - } - - public static void callStopListeningForEvent(String callId, String strEvent) { - CallCallback cl = getCallCallbackById(callId); - - if (cl == null) { - Log.d("callStopListeningForEvent: CallCallback is null."); - return; - } - - int event = getCallCallbackEvent(strEvent); - - if (event == CallCallback.EVENT_INVALID) { - Log.d("callStopListeningForEvent: event is invalid."); - return; - } - - cl.stopListeningForEvents(event); - } - - public static void videoCallStartListeningForEvent(String callId, String strEvent) { - VideoCallCallback cl = getVideoCallListenerById(callId); - - if (cl == null) { - Log.d(String.format("Couldn't find a call with call id:%s", callId)); - return; - } - - int event = getVideoCallCallbackEvent(strEvent); - - if (event == VideoCallCallback.EVENT_INVALID) { - Log.d(String.format("Failed to find a valid event:[%s]", strEvent)); - return; - } - - cl.startListeningForEvents(event); - } - - public static void videoCallStopListeningForEvent(String callId, String strEvent) { - VideoCallCallback cl = getVideoCallListenerById(callId); - - if (cl == null) { - Log.d("videoCallStopListeningForEvent: CallCallback is null."); - return; - } - - int event = getVideoCallCallbackEvent(strEvent); - - if (event == VideoCallCallback.EVENT_INVALID) { - Log.d("getVideoCallCallbackEvent: event is invalid."); - return; - } - - cl.stopListeningForEvents(event); - } - - public static String videoCallGetState(String callId) { - Call c = getCallById(callId); - - int state = CallCallback.STATE_INVALID; - - if (c == null) { - Log.d("videoCallGetState: call is null."); - } - else { - state = c.getDetails().getVideoState(); - } - - return getVideoCallStateString(state); - } - - public static void videoCallSendSessionModifyRequest( - String callId, String videoStateString, String videoQualityString) { - VideoCall vc = getVideoCallById(callId); - - if (vc == null) { - Log.d("Invalid video call for call ID"); - return; - } - - int videoState = getVideoCallState(videoStateString); - int videoQuality = getVideoCallQuality(videoQualityString); - - Log.d(String.format("Sending Modify request for %s:%d, %s:%d", - videoStateString, videoState, videoQualityString, videoQuality)); - - if (videoState == CallCallback.STATE_INVALID || - videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { - Log.d("Invalid session modify request!"); - return; - } - - vc.sendSessionModifyRequest(new VideoProfile(videoState, videoQuality)); - } - - public static void videoCallSendSessionModifyResponse( - String callId, String videoStateString, String videoQualityString) { - VideoCall vc = getVideoCallById(callId); - - if (vc == null) { - Log.d("Invalid video call for call ID"); - return; - } - - int videoState = getVideoCallState(videoStateString); - int videoQuality = getVideoCallQuality(videoQualityString); - - Log.d(String.format("Sending Modify request for %s:%d, %s:%d", - videoStateString, videoState, videoQualityString, videoQuality)); - - if (videoState == CallCallback.STATE_INVALID || - videoQuality == QUALITY_INVALID || videoQuality == VideoProfile.QUALITY_UNKNOWN) { - Log.d("Invalid session modify request!"); - return; - } - - vc.sendSessionModifyResponse(new VideoProfile(videoState, videoQuality)); - } - - public static void callAnswer(String callId, String videoState) { - Call c = getCallById(callId); - - if (c == null) { - Log.d("callAnswer: call is null."); - } - - int state = getVideoCallState(videoState); - - if (state == CallCallback.STATE_INVALID) { - Log.d("callAnswer: video state is invalid."); - state = VideoProfile.STATE_AUDIO_ONLY; - } - - c.answer(state); - } - - public static void callReject(String callId, String message) { - Call c = getCallById(callId); - - if (c == null) { - Log.d("callReject: call is null."); - } - - c.reject((message != null) ? true : false, message); - } - - public static String getCallParent(String callId) { - Call c = getCallById(callId); - - if (c == null) { - Log.d("getCallParent: call is null."); - return null; - } - Call callParent = c.getParent(); - return getCallId(callParent); - } - - public static List<String> getCallChildren(String callId) { - Call c = getCallById(callId); - - if (c == null) { - Log.d("getCallChildren: call is null."); - return null; - } - List<String> childrenList = new ArrayList<String>(); - List<Call> callChildren = c.getChildren(); - for (Call call : callChildren) { - childrenList.add(getCallId(call)); - } - return childrenList; - } - - public static void swapCallsInConference(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("swapCallsInConference: call is null."); - return; - } - c.swapConference(); - } - - public static void callPlayDtmfTone(String callId, char digit) { - Call c = getCallById(callId); - if (c == null) { - Log.d("callPlayDtmfTone: call is null."); - return; - } - c.playDtmfTone(digit); - } - - public static void callStopDtmfTone(String callId) { - Call c = getCallById(callId); - if (c == null) { - Log.d("callStopDtmfTone: call is null."); - return; - } - c.stopDtmfTone(); - } - - public static List<String> callGetCannedTextResponses(String callId) { - Call c = getCallById(callId); - if (c == null) { - return null; - } - - return c.getCannedTextResponses(); - } - - /* - * String Mapping Functions for Facade Parameter Translation - */ - - public static String getVideoCallStateString(int state) { - switch (state) { - case VIDEO_STATE_AUDIO_ONLY: - return TelephonyConstants.VT_STATE_AUDIO_ONLY; - case VIDEO_STATE_TX_ENABLED: - return TelephonyConstants.VT_STATE_TX_ENABLED; - case VIDEO_STATE_RX_ENABLED: - return TelephonyConstants.VT_STATE_RX_ENABLED; - case VIDEO_STATE_BIDIRECTIONAL: - return TelephonyConstants.VT_STATE_BIDIRECTIONAL; - case VIDEO_STATE_TX_PAUSED: - return TelephonyConstants.VT_STATE_TX_PAUSED; - case VIDEO_STATE_RX_PAUSED: - return TelephonyConstants.VT_STATE_RX_PAUSED; - case VIDEO_STATE_BIDIRECTIONAL_PAUSED: - return TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED; - default: - } - Log.d("getVideoCallStateString: state is invalid."); - return TelephonyConstants.VT_STATE_STATE_INVALID; - } - - public static int getVideoCallState(String state) { - switch (state.toUpperCase()) { - case TelephonyConstants.VT_STATE_AUDIO_ONLY: - return VIDEO_STATE_AUDIO_ONLY; - case TelephonyConstants.VT_STATE_TX_ENABLED: - return VIDEO_STATE_TX_ENABLED; - case TelephonyConstants.VT_STATE_RX_ENABLED: - return VIDEO_STATE_RX_ENABLED; - case TelephonyConstants.VT_STATE_BIDIRECTIONAL: - return VIDEO_STATE_BIDIRECTIONAL; - case TelephonyConstants.VT_STATE_TX_PAUSED: - return VIDEO_STATE_TX_PAUSED; - case TelephonyConstants.VT_STATE_RX_PAUSED: - return VIDEO_STATE_RX_PAUSED; - case TelephonyConstants.VT_STATE_BIDIRECTIONAL_PAUSED: - return VIDEO_STATE_BIDIRECTIONAL_PAUSED; - - default: - } - Log.d("getVideoCallState: state is invalid."); - return CallCallback.STATE_INVALID; - } - - private static int getVideoCallQuality(String quality) { - - switch (quality.toUpperCase()) { - case TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN: - return VideoProfile.QUALITY_UNKNOWN; - case TelephonyConstants.VT_VIDEO_QUALITY_HIGH: - return VideoProfile.QUALITY_HIGH; - case TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM: - return VideoProfile.QUALITY_MEDIUM; - case TelephonyConstants.VT_VIDEO_QUALITY_LOW: - return VideoProfile.QUALITY_LOW; - case TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT: - return VideoProfile.QUALITY_DEFAULT; - default: - } - Log.d("getVideoCallQuality: quality is invalid."); - return QUALITY_INVALID; - } - - public static String getVideoCallQualityString(int quality) { - switch (quality) { - case VideoProfile.QUALITY_UNKNOWN: - return TelephonyConstants.VT_VIDEO_QUALITY_UNKNOWN; - case VideoProfile.QUALITY_HIGH: - return TelephonyConstants.VT_VIDEO_QUALITY_HIGH; - case VideoProfile.QUALITY_MEDIUM: - return TelephonyConstants.VT_VIDEO_QUALITY_MEDIUM; - case VideoProfile.QUALITY_LOW: - return TelephonyConstants.VT_VIDEO_QUALITY_LOW; - case VideoProfile.QUALITY_DEFAULT: - return TelephonyConstants.VT_VIDEO_QUALITY_DEFAULT; - default: - } - Log.d("getVideoCallQualityString: quality is invalid."); - return TelephonyConstants.VT_VIDEO_QUALITY_INVALID; - } - - private static int getCallCallbackEvent(String event) { - - switch (event.toUpperCase()) { - case "EVENT_STATE_CHANGED": - return CallCallback.EVENT_STATE_CHANGED; - case "EVENT_PARENT_CHANGED": - return CallCallback.EVENT_PARENT_CHANGED; - case "EVENT_CHILDREN_CHANGED": - return CallCallback.EVENT_CHILDREN_CHANGED; - case "EVENT_DETAILS_CHANGED": - return CallCallback.EVENT_DETAILS_CHANGED; - case "EVENT_CANNED_TEXT_RESPONSES_LOADED": - return CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED; - case "EVENT_POST_DIAL_WAIT": - return CallCallback.EVENT_POST_DIAL_WAIT; - case "EVENT_VIDEO_CALL_CHANGED": - return CallCallback.EVENT_VIDEO_CALL_CHANGED; - case "EVENT_CALL_DESTROYED": - return CallCallback.EVENT_CALL_DESTROYED; - case "EVENT_CONFERENCABLE_CALLS_CHANGED": - return CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED; - } - Log.d("getCallCallbackEvent: event is invalid."); - return CallCallback.EVENT_INVALID; - } - - public static String getCallCallbackEventString(int event) { - - switch (event) { - case CallCallback.EVENT_STATE_CHANGED: - return "EVENT_STATE_CHANGED"; - case CallCallback.EVENT_PARENT_CHANGED: - return "EVENT_PARENT_CHANGED"; - case CallCallback.EVENT_CHILDREN_CHANGED: - return "EVENT_CHILDREN_CHANGED"; - case CallCallback.EVENT_DETAILS_CHANGED: - return "EVENT_DETAILS_CHANGED"; - case CallCallback.EVENT_CANNED_TEXT_RESPONSES_LOADED: - return "EVENT_CANNED_TEXT_RESPONSES_LOADED"; - case CallCallback.EVENT_POST_DIAL_WAIT: - return "EVENT_POST_DIAL_WAIT"; - case CallCallback.EVENT_VIDEO_CALL_CHANGED: - return "EVENT_VIDEO_CALL_CHANGED"; - case CallCallback.EVENT_CALL_DESTROYED: - return "EVENT_CALL_DESTROYED"; - case CallCallback.EVENT_CONFERENCABLE_CALLS_CHANGED: - return "EVENT_CONFERENCABLE_CALLS_CHANGED"; - } - Log.d("getCallCallbackEventString: event is invalid."); - return "EVENT_INVALID"; - } - - private static int getVideoCallCallbackEvent(String event) { - - switch (event) { - case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED: - return VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED; - case TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED: - return VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED; - case TelephonyConstants.EVENT_VIDEO_SESSION_EVENT: - return VideoCallCallback.EVENT_SESSION_EVENT; - case TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED: - return VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED; - case TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED: - return VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED; - case TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED: - return VideoCallCallback.EVENT_DATA_USAGE_CHANGED; - case TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED: - return VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED; - } - Log.d("getVideoCallCallbackEvent: event is invalid."); - return CallCallback.EVENT_INVALID; - } - - public static String getVideoCallCallbackEventString(int event) { - - switch (event) { - case VideoCallCallback.EVENT_SESSION_MODIFY_REQUEST_RECEIVED: - return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED; - case VideoCallCallback.EVENT_SESSION_MODIFY_RESPONSE_RECEIVED: - return TelephonyConstants.EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED; - case VideoCallCallback.EVENT_SESSION_EVENT: - return TelephonyConstants.EVENT_VIDEO_SESSION_EVENT; - case VideoCallCallback.EVENT_PEER_DIMENSIONS_CHANGED: - return TelephonyConstants.EVENT_VIDEO_PEER_DIMENSIONS_CHANGED; - case VideoCallCallback.EVENT_VIDEO_QUALITY_CHANGED: - return TelephonyConstants.EVENT_VIDEO_QUALITY_CHANGED; - case VideoCallCallback.EVENT_DATA_USAGE_CHANGED: - return TelephonyConstants.EVENT_VIDEO_DATA_USAGE_CHANGED; - case VideoCallCallback.EVENT_CAMERA_CAPABILITIES_CHANGED: - return TelephonyConstants.EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED; - } - Log.d("getVideoCallCallbackEventString: event is invalid."); - return TelephonyConstants.EVENT_VIDEO_INVALID; - } - - public static String getCallStateString(int state) { - switch (state) { - case Call.STATE_NEW: - return TelephonyConstants.CALL_STATE_NEW; - case Call.STATE_DIALING: - return TelephonyConstants.CALL_STATE_DIALING; - case Call.STATE_RINGING: - return TelephonyConstants.CALL_STATE_RINGING; - case Call.STATE_HOLDING: - return TelephonyConstants.CALL_STATE_HOLDING; - case Call.STATE_ACTIVE: - return TelephonyConstants.CALL_STATE_ACTIVE; - case Call.STATE_DISCONNECTED: - return TelephonyConstants.CALL_STATE_DISCONNECTED; - case Call.STATE_PRE_DIAL_WAIT: - return TelephonyConstants.CALL_STATE_PRE_DIAL_WAIT; - case Call.STATE_CONNECTING: - return TelephonyConstants.CALL_STATE_CONNECTING; - case Call.STATE_DISCONNECTING: - return TelephonyConstants.CALL_STATE_DISCONNECTING; - case STATE_INVALID: - return TelephonyConstants.CALL_STATE_INVALID; - default: - return TelephonyConstants.CALL_STATE_UNKNOWN; - } - } - - private static int getAudioRoute(String audioRoute) { - switch (audioRoute.toUpperCase()) { - case TelephonyConstants.AUDIO_ROUTE_BLUETOOTH: - return CallAudioState.ROUTE_BLUETOOTH; - case TelephonyConstants.AUDIO_ROUTE_EARPIECE: - return CallAudioState.ROUTE_EARPIECE; - case TelephonyConstants.AUDIO_ROUTE_SPEAKER: - return CallAudioState.ROUTE_SPEAKER; - case TelephonyConstants.AUDIO_ROUTE_WIRED_HEADSET: - return CallAudioState.ROUTE_WIRED_HEADSET; - case TelephonyConstants.AUDIO_ROUTE_WIRED_OR_EARPIECE: - return CallAudioState.ROUTE_WIRED_OR_EARPIECE; - default: - return INVALID_AUDIO_ROUTE; - } - } - - public static String getAudioRouteString(int audioRoute) { - return CallAudioState.audioRouteToString(audioRoute); - } - - public static String getVideoCallSessionEventString(int event) { - - switch (event) { - case Connection.VideoProvider.SESSION_EVENT_RX_PAUSE: - return TelephonyConstants.SESSION_EVENT_RX_PAUSE; - case Connection.VideoProvider.SESSION_EVENT_RX_RESUME: - return TelephonyConstants.SESSION_EVENT_RX_RESUME; - case Connection.VideoProvider.SESSION_EVENT_TX_START: - return TelephonyConstants.SESSION_EVENT_TX_START; - case Connection.VideoProvider.SESSION_EVENT_TX_STOP: - return TelephonyConstants.SESSION_EVENT_TX_STOP; - case Connection.VideoProvider.SESSION_EVENT_CAMERA_FAILURE: - return TelephonyConstants.SESSION_EVENT_CAMERA_FAILURE; - case Connection.VideoProvider.SESSION_EVENT_CAMERA_READY: - return TelephonyConstants.SESSION_EVENT_CAMERA_READY; - default: - return TelephonyConstants.SESSION_EVENT_UNKNOWN; - } - } - - public static String getCallCapabilityString(int capability) { - switch (capability) { - case Call.Details.CAPABILITY_HOLD: - return TelephonyConstants.CALL_CAPABILITY_HOLD; - case Call.Details.CAPABILITY_SUPPORT_HOLD: - return TelephonyConstants.CALL_CAPABILITY_SUPPORT_HOLD; - case Call.Details.CAPABILITY_MERGE_CONFERENCE: - return TelephonyConstants.CALL_CAPABILITY_MERGE_CONFERENCE; - case Call.Details.CAPABILITY_SWAP_CONFERENCE: - return TelephonyConstants.CALL_CAPABILITY_SWAP_CONFERENCE; - case Call.Details.CAPABILITY_UNUSED_1: - return TelephonyConstants.CALL_CAPABILITY_UNUSED_1; - case Call.Details.CAPABILITY_RESPOND_VIA_TEXT: - return TelephonyConstants.CALL_CAPABILITY_RESPOND_VIA_TEXT; - case Call.Details.CAPABILITY_MUTE: - return TelephonyConstants.CALL_CAPABILITY_MUTE; - case Call.Details.CAPABILITY_MANAGE_CONFERENCE: - return TelephonyConstants.CALL_CAPABILITY_MANAGE_CONFERENCE; - case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_RX; - case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_TX; - case Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL; - case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_RX; - case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_TX; - case Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL: - return TelephonyConstants.CALL_CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL; - case Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE: - return TelephonyConstants.CALL_CAPABILITY_SEPARATE_FROM_CONFERENCE; - case Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE: - return TelephonyConstants.CALL_CAPABILITY_DISCONNECT_FROM_CONFERENCE; - case Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO: - return TelephonyConstants.CALL_CAPABILITY_SPEED_UP_MT_AUDIO; - case Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO: - return TelephonyConstants.CALL_CAPABILITY_CAN_UPGRADE_TO_VIDEO; - case Call.Details.CAPABILITY_CAN_PAUSE_VIDEO: - return TelephonyConstants.CALL_CAPABILITY_CAN_PAUSE_VIDEO; - } - return TelephonyConstants.CALL_CAPABILITY_UNKOWN; - } - - public static List<String> getCallCapabilitiesString(int capabilities) { - final int[] capabilityConstants = new int[] { - Call.Details.CAPABILITY_HOLD, - Call.Details.CAPABILITY_SUPPORT_HOLD, - Call.Details.CAPABILITY_MERGE_CONFERENCE, - Call.Details.CAPABILITY_SWAP_CONFERENCE, - Call.Details.CAPABILITY_UNUSED_1, - Call.Details.CAPABILITY_RESPOND_VIA_TEXT, - Call.Details.CAPABILITY_MUTE, - Call.Details.CAPABILITY_MANAGE_CONFERENCE, - Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_RX, - Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_TX, - Call.Details.CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL, - Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_RX, - Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_TX, - Call.Details.CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL, - Call.Details.CAPABILITY_SEPARATE_FROM_CONFERENCE, - Call.Details.CAPABILITY_DISCONNECT_FROM_CONFERENCE, - Call.Details.CAPABILITY_SPEED_UP_MT_AUDIO, - Call.Details.CAPABILITY_CAN_UPGRADE_TO_VIDEO, - Call.Details.CAPABILITY_CAN_PAUSE_VIDEO - }; - - List<String> capabilityList = new ArrayList<String>(); - - for (int capability : capabilityConstants) { - if ((capabilities & capability) == capability) { - capabilityList.add(getCallCapabilityString(capability)); - } - } - return capabilityList; - } - - public static String getCallPropertyString(int property) { - - switch (property) { - case Call.Details.PROPERTY_CONFERENCE: - return TelephonyConstants.CALL_PROPERTY_CONFERENCE; - case Call.Details.PROPERTY_GENERIC_CONFERENCE: - return TelephonyConstants.CALL_PROPERTY_GENERIC_CONFERENCE; - case Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE: - return TelephonyConstants.CALL_PROPERTY_EMERGENCY_CALLBACK_MODE; - case Call.Details.PROPERTY_WIFI: - return TelephonyConstants.CALL_PROPERTY_WIFI; - case Call.Details.PROPERTY_HIGH_DEF_AUDIO: - return TelephonyConstants.CALL_PROPERTY_HIGH_DEF_AUDIO; - default: - return TelephonyConstants.CALL_PROPERTY_UNKNOWN; - } - } - - public static List<String> getCallPropertiesString(int properties) { - final int[] propertyConstants = new int[] { - Call.Details.PROPERTY_CONFERENCE, - Call.Details.PROPERTY_GENERIC_CONFERENCE, - Call.Details.PROPERTY_EMERGENCY_CALLBACK_MODE, - Call.Details.PROPERTY_WIFI, - Call.Details.PROPERTY_HIGH_DEF_AUDIO - }; - - List<String> propertyList = new ArrayList<String>(); - - for (int property : propertyConstants) { - if ((properties & property) == property) { - propertyList.add(getCallPropertyString(property)); - } - } - - return propertyList; - } - - public static String getCallPresentationInfoString(int presentation) { - switch (presentation) { - case TelecomManager.PRESENTATION_ALLOWED: - return TelephonyConstants.CALL_PRESENTATION_ALLOWED; - case TelecomManager.PRESENTATION_RESTRICTED: - return TelephonyConstants.CALL_PRESENTATION_RESTRICTED; - case TelecomManager.PRESENTATION_PAYPHONE: - return TelephonyConstants.CALL_PRESENTATION_PAYPHONE; - default: - return TelephonyConstants.CALL_PRESENTATION_UNKNOWN; - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java deleted file mode 100644 index 1744d2b..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SmsFacade.java +++ /dev/null @@ -1,990 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import com.google.android.mms.ContentType; -import com.google.android.mms.InvalidHeaderValueException; -import com.google.android.mms.pdu.CharacterSets; -import com.google.android.mms.pdu.EncodedStringValue; -import com.google.android.mms.pdu.GenericPdu; -import com.google.android.mms.pdu.PduBody; -import com.google.android.mms.pdu.PduComposer; -import com.google.android.mms.pdu.PduHeaders; -import com.google.android.mms.pdu.PduParser; -import com.google.android.mms.pdu.PduPart; -import com.google.android.mms.pdu.PduPersister; -import com.google.android.mms.pdu.SendConf; -import com.google.android.mms.pdu.SendReq; -import com.google.android.mms.MmsException; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import android.app.Activity; -import android.app.PendingIntent; -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.Uri; -import android.os.Bundle; -import android.provider.Telephony.Sms.Intents; -import android.provider.Telephony.Mms; -import android.telephony.SmsManager; -import android.telephony.SmsMessage; -import android.telephony.SmsCbMessage; -import com.android.internal.telephony.gsm.SmsCbConstants; -import com.android.internal.telephony.cdma.sms.SmsEnvelope; -import android.telephony.SmsCbEtwsInfo; -import android.telephony.SmsCbCmasInfo; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.facade.telephony.TelephonyConstants; - -//FIXME: Change the build order to use constants defined in here -//import com.googlecode.android_scripting.provider.TelephonyTestProvider; - -/** - * Exposes SmsManager functionality. - */ -public class SmsFacade extends RpcReceiver { - - static final boolean DBG = false; - - private final EventFacade mEventFacade; - private final SmsManager mSms; - private final Context mContext; - private final Service mService; - private BroadcastReceiver mSmsSendListener; - private BroadcastReceiver mSmsIncomingListener; - private int mNumExpectedSentEvents; - private int mNumExpectedDeliveredEvents; - private boolean mListeningIncomingSms; - private IntentFilter mEmergencyCBMessage; - private BroadcastReceiver mGsmEmergencyCBMessageListener; - private BroadcastReceiver mCdmaEmergencyCBMessageListener; - private boolean mGsmEmergencyCBListenerRegistered; - private boolean mCdmaEmergencyCBListenerRegistered; - private boolean mSentReceiversRegistered; - private Object lock = new Object(); - - private BroadcastReceiver mMmsSendListener; - private BroadcastReceiver mMmsIncomingListener; - private boolean mListeningIncomingMms; - - TelephonyManager mTelephonyManager; - - private static final String SMS_MESSAGE_STATUS_DELIVERED_ACTION = - "com.googlecode.android_scripting.sms.MESSAGE_STATUS_DELIVERED"; - private static final String SMS_MESSAGE_SENT_ACTION = - "com.googlecode.android_scripting.sms.MESSAGE_SENT"; - - private static final String EMERGENCY_CB_MESSAGE_RECEIVED_ACTION = - "android.provider.Telephony.SMS_EMERGENCY_CB_RECEIVED"; - - private static final String MMS_MESSAGE_SENT_ACTION = - "com.googlecode.android_scripting.mms.MESSAGE_SENT"; - - private final int MAX_MESSAGE_LENGTH = 160; - private final int INTERNATIONAL_NUMBER_LENGTH = 12; - private final int DOMESTIC_NUMBER_LENGTH = 10; - - private static final String DEFAULT_FROM_PHONE_NUMBER = new String("8675309"); - - private final int[] mGsmCbMessageIdList = { - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING, - SmsCbConstants.MESSAGE_ID_ETWS_TSUNAMI_WARNING, - SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING, - SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE, - SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST, - SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE - }; - - private final int[] mCdmaCbMessageIdList = { - SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT, - SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, - SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, - SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, - SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE - }; - - public SmsFacade(FacadeManager manager) { - - super(manager); - mService = manager.getService(); - mContext = mService; - mSms = SmsManager.getDefault(); - mEventFacade = manager.getReceiver(EventFacade.class); - mSmsSendListener = new SmsSendListener(); - mSmsIncomingListener = new SmsIncomingListener(); - mNumExpectedSentEvents = 0; - mNumExpectedDeliveredEvents = 0; - mListeningIncomingSms = false; - mGsmEmergencyCBMessageListener = new SmsEmergencyCBMessageListener(); - mCdmaEmergencyCBMessageListener = new SmsEmergencyCBMessageListener(); - mGsmEmergencyCBListenerRegistered = false; - mCdmaEmergencyCBListenerRegistered = false; - mSentReceiversRegistered = false; - - mMmsIncomingListener = new MmsIncomingListener(); - mMmsSendListener = new MmsSendListener(); - - mListeningIncomingMms = false; - - IntentFilter smsFilter = new IntentFilter(SMS_MESSAGE_SENT_ACTION); - smsFilter.addAction(SMS_MESSAGE_STATUS_DELIVERED_ACTION); - - IntentFilter mmsFilter = new IntentFilter(MMS_MESSAGE_SENT_ACTION); - - synchronized (lock) { - mService.registerReceiver(mSmsSendListener, smsFilter); - mService.registerReceiver(mMmsSendListener, mmsFilter); - mSentReceiversRegistered = true; - } - - mTelephonyManager = - (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE); - } - - // FIXME: Move to a utility class - // FIXME: remove the MODE_WORLD_READABLE once we verify the use case - @SuppressWarnings("deprecation") - private boolean writeBytesToFile(String fileName, byte[] pdu) { - FileOutputStream writer = null; - try { - writer = mContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE); - writer.write(pdu); - return true; - } catch (final IOException e) { - return false; - } finally { - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - } - } - } - } - - // FIXME: Move to a utility class - private boolean writeBytesToCacheFile(String fileName, byte[] pdu) { - File mmsFile = new File(mContext.getCacheDir(), fileName); - Log.d(String.format("filename:%s, directory:%s", fileName, - mContext.getCacheDir().toString())); - FileOutputStream writer = null; - try { - writer = new FileOutputStream(mmsFile); - writer.write(pdu); - return true; - } catch (final IOException e) { - Log.d("writeBytesToCacheFile() failed with " + e.toString()); - return false; - } finally { - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - } - } - } - } - - @Deprecated - @Rpc(description = "Starts tracking incoming SMS.") - public void smsStartTrackingIncomingMessage() { - Log.d("Using Deprecated smsStartTrackingIncomingMessage!"); - smsStartTrackingIncomingSmsMessage(); - } - - @Rpc(description = "Starts tracking incoming SMS.") - public void smsStartTrackingIncomingSmsMessage() { - mService.registerReceiver(mSmsIncomingListener, - new IntentFilter(Intents.SMS_RECEIVED_ACTION)); - mListeningIncomingSms = true; - } - - @Deprecated - @Rpc(description = "Stops tracking incoming SMS.") - public void smsStopTrackingIncomingMessage() { - Log.d("Using Deprecated smsStopTrackingIncomingMessage!"); - smsStopTrackingIncomingSmsMessage(); - } - - @Rpc(description = "Stops tracking incoming SMS.") - public void smsStopTrackingIncomingSmsMessage() { - if (mListeningIncomingSms) { - mListeningIncomingSms = false; - try { - mService.unregisterReceiver(mSmsIncomingListener); - } catch (Exception e) { - Log.e("Tried to unregister nonexistent SMS Listener!"); - } - } - } - - @Rpc(description = "Starts tracking incoming MMS.") - public void smsStartTrackingIncomingMmsMessage() { - IntentFilter mmsReceived = new IntentFilter(Intents.MMS_DOWNLOADED_ACTION); - mmsReceived.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); - mmsReceived.addAction(Intents.DATA_SMS_RECEIVED_ACTION); - mService.registerReceiver(mMmsIncomingListener, mmsReceived); - mListeningIncomingSms = true; - } - - @Rpc(description = "Stops tracking incoming MMS.") - public void smsStopTrackingIncomingMmsMessage() { - if (mListeningIncomingMms) { - mListeningIncomingMms = false; - try { - mService.unregisterReceiver(mMmsIncomingListener); - } catch (Exception e) { - Log.e("Tried to unregister nonexistent MMS Listener!"); - } - } - } - - // Currently requires 'adb shell su root setenforce 0' - @Rpc(description = "Send a multimedia message to a specified number.") - public void smsSendMultimediaMessage( - @RpcParameter(name = "toPhoneNumber") - String toPhoneNumber, - @RpcParameter(name = "subject") - String subject, - @RpcParameter(name = "message") - String message, - @RpcParameter(name = "fromPhoneNumber") - @RpcOptional - String fromPhoneNumber, - @RpcParameter(name = "fileName") - @RpcOptional - String fileName) { - - MmsBuilder mms = new MmsBuilder(); - - mms.setToPhoneNumber(toPhoneNumber); - if (fromPhoneNumber == null) { - mTelephonyManager.getLine1Number(); //TODO: b/21592513 - multi-sim awareness - } - - if (DBG) { - Log.d(String.format( - "Params:toPhoneNumber(%s),subject(%s),message(%s),fromPhoneNumber(%s),filename(%s)", - toPhoneNumber, subject, message, - (fromPhoneNumber != null) ? fromPhoneNumber : "", - (fileName != null) ? fileName : "")); - } - - mms.setFromPhoneNumber((fromPhoneNumber != null) ? fromPhoneNumber : DEFAULT_FROM_PHONE_NUMBER); - mms.setSubject(subject); - mms.setDate(); - mms.addMessageBody(message); - mms.setMessageClass(MmsBuilder.MESSAGE_CLASS_PERSONAL); - mms.setMessagePriority(MmsBuilder.DEFAULT_PRIORITY); - mms.setDeliveryReport(true); - mms.setReadReport(true); - // Default to 1 week; - mms.setExpirySeconds(MmsBuilder.DEFAULT_EXPIRY_TIME); - - Uri contentUri = null; - - String randomFileName = "mms." + String.valueOf(System.currentTimeMillis()) + ".dat"; - - byte[] mmsBytes = mms.build(); - if (mmsBytes.length == 0) { - Log.e("Failed to build PDU!"); - return; - } - - if (writeBytesToCacheFile(randomFileName, mmsBytes) == false) { - Log.e("Failed to write PDU to file"); - return; - } - - contentUri = (new Uri.Builder()) - .authority("com.googlecode.android_scripting.provider.telephonytestprovider") - .path("mms/" + randomFileName) - .scheme(ContentResolver.SCHEME_CONTENT) - .build(); - - if (contentUri != null) { - Log.d(String.format("URI String: %s", contentUri.toString())); - - SmsManager.getDefault().sendMultimediaMessage(mContext, - contentUri, null/* locationUrl */, null/* configOverrides */, - PendingIntent.getBroadcast(mService, 0, - new Intent(MMS_MESSAGE_SENT_ACTION), 0) - ); - } - else { - Log.d("smsSendMultimediaMessage():Content URI String is null"); - } - } - - @Rpc(description = "Send a text message to a specified number.") - public void smsSendTextMessage( - @RpcParameter(name = "phoneNumber") - String phoneNumber, - @RpcParameter(name = "message") - String message, - @RpcParameter(name = "deliveryReportRequired") - Boolean deliveryReportRequired) { - - if (message.length() > MAX_MESSAGE_LENGTH) { - ArrayList<String> messagesParts = mSms.divideMessage(message); - mNumExpectedSentEvents = mNumExpectedDeliveredEvents = messagesParts.size(); - ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>(); - ArrayList<PendingIntent> deliveredIntents = new ArrayList<PendingIntent>(); - for (int i = 0; i < messagesParts.size(); i++) { - sentIntents.add(PendingIntent.getBroadcast(mService, 0, - new Intent(SMS_MESSAGE_SENT_ACTION), 0)); - if (deliveryReportRequired) { - deliveredIntents.add( - PendingIntent.getBroadcast(mService, 0, - new Intent(SMS_MESSAGE_STATUS_DELIVERED_ACTION), 0)); - } - } - mSms.sendMultipartTextMessage( - phoneNumber, null, messagesParts, - sentIntents, deliveryReportRequired ? deliveredIntents : null); - } else { - mNumExpectedSentEvents = mNumExpectedDeliveredEvents = 1; - PendingIntent sentIntent = PendingIntent.getBroadcast(mService, 0, - new Intent(SMS_MESSAGE_SENT_ACTION), 0); - PendingIntent deliveredIntent = PendingIntent.getBroadcast(mService, 0, - new Intent(SMS_MESSAGE_STATUS_DELIVERED_ACTION), 0); - mSms.sendTextMessage( - phoneNumber, null, message, sentIntent, - deliveryReportRequired ? deliveredIntent : null); - } - } - - @Rpc(description = "Retrieves all messages currently stored on ICC.") - public ArrayList<SmsMessage> smsGetAllMessagesFromIcc() { - return SmsManager.getDefault().getAllMessagesFromIcc(); - } - - @Rpc(description = "Starts tracking GSM Emergency CB Messages.") - public void smsStartTrackingGsmEmergencyCBMessage() { - if (!mGsmEmergencyCBListenerRegistered) { - for (int messageId : mGsmCbMessageIdList) { - mSms.enableCellBroadcast( - messageId, - SmsManager.CELL_BROADCAST_RAN_TYPE_GSM); - } - - mEmergencyCBMessage = new IntentFilter(EMERGENCY_CB_MESSAGE_RECEIVED_ACTION); - mService.registerReceiver(mGsmEmergencyCBMessageListener, - mEmergencyCBMessage); - mGsmEmergencyCBListenerRegistered = true; - } - } - - @Rpc(description = "Stop tracking GSM Emergency CB Messages") - public void smsStopTrackingGsmEmergencyCBMessage() { - if (mGsmEmergencyCBListenerRegistered) { - mService.unregisterReceiver(mGsmEmergencyCBMessageListener); - mGsmEmergencyCBListenerRegistered = false; - for (int messageId : mGsmCbMessageIdList) { - mSms.disableCellBroadcast( - messageId, - SmsManager.CELL_BROADCAST_RAN_TYPE_GSM); - } - } - } - - @Rpc(description = "Starts tracking CDMA Emergency CB Messages") - public void smsStartTrackingCdmaEmergencyCBMessage() { - if (!mCdmaEmergencyCBListenerRegistered) { - for (int messageId : mCdmaCbMessageIdList) { - mSms.enableCellBroadcast( - messageId, - SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA); - } - mEmergencyCBMessage = new IntentFilter(EMERGENCY_CB_MESSAGE_RECEIVED_ACTION); - mService.registerReceiver(mCdmaEmergencyCBMessageListener, - mEmergencyCBMessage); - mCdmaEmergencyCBListenerRegistered = true; - } - } - - @Rpc(description = "Stop tracking CDMA Emergency CB Message.") - public void smsStopTrackingCdmaEmergencyCBMessage() { - if (mCdmaEmergencyCBListenerRegistered) { - mService.unregisterReceiver(mCdmaEmergencyCBMessageListener); - mCdmaEmergencyCBListenerRegistered = false; - for (int messageId : mCdmaCbMessageIdList) { - mSms.disableCellBroadcast( - messageId, - SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA); - } - } - } - - private class SmsSendListener extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Bundle event = new Bundle(); - event.putString("Type", "SmsDeliverStatus"); - String action = intent.getAction(); - int resultCode = getResultCode(); - if (SMS_MESSAGE_STATUS_DELIVERED_ACTION.equals(action)) { - if (resultCode == Activity.RESULT_OK) { - if (mNumExpectedDeliveredEvents == 1) { - Log.d("SMS Message delivered successfully"); - mEventFacade.postEvent(TelephonyConstants.EventSmsDeliverSuccess, event); - } - if (mNumExpectedDeliveredEvents > 0) { - mNumExpectedDeliveredEvents--; - } - } else { - Log.e("SMS Message delivery failed"); - // TODO . Need to find the reason for failure from pdu - mEventFacade.postEvent(TelephonyConstants.EventSmsDeliverFailure, event); - } - } else if (SMS_MESSAGE_SENT_ACTION.equals(action)) { - if (resultCode == Activity.RESULT_OK) { - if (mNumExpectedSentEvents == 1) { - event.putString("Type", "SmsSentSuccess"); - Log.d("SMS Message sent successfully"); - mEventFacade.postEvent(TelephonyConstants.EventSmsSentSuccess, event); - } - if (mNumExpectedSentEvents > 0) { - mNumExpectedSentEvents--; - } - } else { - Log.e("SMS Message send failed"); - event.putString("Type", "SmsSentFailure"); - switch (resultCode) { - case SmsManager.RESULT_ERROR_GENERIC_FAILURE: - event.putString("Reason", "GenericFailure"); - break; - case SmsManager.RESULT_ERROR_RADIO_OFF: - event.putString("Reason", "RadioOff"); - break; - case SmsManager.RESULT_ERROR_NULL_PDU: - event.putString("Reason", "NullPdu"); - break; - case SmsManager.RESULT_ERROR_NO_SERVICE: - event.putString("Reason", "NoService"); - break; - case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED: - event.putString("Reason", "LimitExceeded"); - break; - case SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE: - event.putString("Reason", "FdnCheckFailure"); - break; - default: - event.putString("Reason", "Unknown"); - break; - } - mEventFacade.postEvent(TelephonyConstants.EventSmsSentFailure, event); - } - } - } - } - - private class SmsIncomingListener extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intents.SMS_RECEIVED_ACTION.equals(action)) { - Log.d("New SMS Received"); - Bundle extras = intent.getExtras(); - int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - if (extras != null) { - Bundle event = new Bundle(); - event.putString("Type", "NewSmsReceived"); - SmsMessage[] msgs = Intents.getMessagesFromIntent(intent); - StringBuilder smsMsg = new StringBuilder(); - - SmsMessage sms = msgs[0]; - String sender = sms.getOriginatingAddress(); - event.putString("Sender", formatPhoneNumber(sender)); - - for (int i = 0; i < msgs.length; i++) { - sms = msgs[i]; - smsMsg.append(sms.getMessageBody()); - } - event.putString("Text", smsMsg.toString()); - // TODO - // Need to explore how to get subId information. - event.putInt("subscriptionId", subId); - mEventFacade.postEvent(TelephonyConstants.EventSmsReceived, event); - } - } - } - } - - private class MmsSendListener extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Bundle event = new Bundle(); - String action = intent.getAction(); - int resultCode = getResultCode(); - event.putString("ResultCode", Integer.toString(resultCode)); - if (MMS_MESSAGE_SENT_ACTION.equals(action)) { - if (resultCode == Activity.RESULT_OK) { - Log.d("MMS Message sent successfully"); - mEventFacade.postEvent(TelephonyConstants.EventMmsSentSuccess, event); - } else { - Log.e(String.format("MMS Message send failed: %d", resultCode)); - mEventFacade.postEvent(TelephonyConstants.EventMmsSentFailure, event); - } - } else { - Log.e("MMS Send Listener Received Invalid Event" + intent.toString()); - } - } - } - - // b/21569494 - Never receiving ANY of these events: requires debugging - private class MmsIncomingListener extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.d("MmsIncomingListener Received an Intent " + intent.toString()); - String action = intent.getAction(); - if (Intents.MMS_DOWNLOADED_ACTION.equals(action)) { - Log.d("New MMS Downloaded"); - mEventFacade.postEvent(TelephonyConstants.EventMmsDownloaded, new Bundle()); - } - else if (Intents.WAP_PUSH_RECEIVED_ACTION.equals(action)) { - Log.d("New Wap Push Received"); - mEventFacade.postEvent(TelephonyConstants.EventWapPushReceived, new Bundle()); - } - else if (Intents.DATA_SMS_RECEIVED_ACTION.equals(action)) { - Log.d("New Data SMS Received"); - mEventFacade.postEvent(TelephonyConstants.EventDataSmsReceived, new Bundle()); - } - else { - Log.e("MmsIncomingListener Received Unexpected Event" + intent.toString()); - } - } - } - - String formatPhoneNumber(String phoneNumber) { - String senderNumberStr = null; - int len = phoneNumber.length(); - if (len > 0) { - /** - * Currently this incomingNumber modification is specific for US numbers. - */ - if ((INTERNATIONAL_NUMBER_LENGTH == len) && ('+' == phoneNumber.charAt(0))) { - senderNumberStr = phoneNumber.substring(1); - } else if (DOMESTIC_NUMBER_LENGTH == len) { - senderNumberStr = '1' + phoneNumber; - } else { - senderNumberStr = phoneNumber; - } - } - return senderNumberStr; - } - - private class SmsEmergencyCBMessageListener extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if (EMERGENCY_CB_MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) { - Bundle extras = intent.getExtras(); - if (extras != null) { - Bundle event = new Bundle(); - String eventName = null; - SmsCbMessage message = (SmsCbMessage) extras.get("message"); - if (message != null) { - if (message.isEmergencyMessage()) { - event.putString("geographicalScope", getGeographicalScope( - message.getGeographicalScope())); - event.putInt("serialNumber", message.getSerialNumber()); - event.putString("location", message.getLocation().toString()); - event.putInt("serviceCategory", message.getServiceCategory()); - event.putString("language", message.getLanguageCode()); - event.putString("message", message.getMessageBody()); - event.putString("priority", getPriority(message.getMessagePriority())); - if (message.isCmasMessage()) { - // CMAS message - eventName = TelephonyConstants.EventCmasReceived; - event.putString("cmasMessageClass", getCMASMessageClass( - message.getCmasWarningInfo().getMessageClass())); - event.putString("cmasCategory", getCMASCategory( - message.getCmasWarningInfo().getCategory())); - event.putString("cmasResponseType", getCMASResponseType( - message.getCmasWarningInfo().getResponseType())); - event.putString("cmasSeverity", getCMASSeverity( - message.getCmasWarningInfo().getSeverity())); - event.putString("cmasUrgency", getCMASUrgency( - message.getCmasWarningInfo().getUrgency())); - event.putString("cmasCertainty", getCMASCertainty( - message.getCmasWarningInfo().getCertainty())); - } else if (message.isEtwsMessage()) { - // ETWS message - eventName = TelephonyConstants.EventEtwsReceived; - event.putString("etwsWarningType", getETWSWarningType( - message.getEtwsWarningInfo().getWarningType())); - event.putBoolean("etwsIsEmergencyUserAlert", - message.getEtwsWarningInfo().isEmergencyUserAlert()); - event.putBoolean("etwsActivatePopup", - message.getEtwsWarningInfo().isPopupAlert()); - } else { - Log.d("Received message is not CMAS or ETWS"); - } - if (eventName != null) - mEventFacade.postEvent(eventName, event); - } - } - } else { - Log.d("Received Emergency CB without extras"); - } - } - } - } - - private static String getETWSWarningType(int type) { - switch (type) { - case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE: - return "EARTHQUAKE"; - case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI: - return "TSUNAMI"; - case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI: - return "EARTHQUAKE_AND_TSUNAMI"; - case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE: - return "TEST_MESSAGE"; - case SmsCbEtwsInfo.ETWS_WARNING_TYPE_OTHER_EMERGENCY: - return "OTHER_EMERGENCY"; - } - return "UNKNOWN"; - } - - private static String getCMASMessageClass(int messageclass) { - switch (messageclass) { - case SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT: - return "PRESIDENTIAL_LEVEL_ALERT"; - case SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT: - return "EXTREME_THREAT"; - case SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT: - return "SEVERE_THREAT"; - case SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY: - return "CHILD_ABDUCTION_EMERGENCY"; - case SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST: - return "REQUIRED_MONTHLY_TEST"; - case SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE: - return "CMAS_EXERCISE"; - } - return "UNKNOWN"; - } - - private static String getCMASCategory(int category) { - switch (category) { - case SmsCbCmasInfo.CMAS_CATEGORY_GEO: - return "GEOPHYSICAL"; - case SmsCbCmasInfo.CMAS_CATEGORY_MET: - return "METEOROLOGICAL"; - case SmsCbCmasInfo.CMAS_CATEGORY_SAFETY: - return "SAFETY"; - case SmsCbCmasInfo.CMAS_CATEGORY_SECURITY: - return "SECURITY"; - case SmsCbCmasInfo.CMAS_CATEGORY_RESCUE: - return "RESCUE"; - case SmsCbCmasInfo.CMAS_CATEGORY_FIRE: - return "FIRE"; - case SmsCbCmasInfo.CMAS_CATEGORY_HEALTH: - return "HEALTH"; - case SmsCbCmasInfo.CMAS_CATEGORY_ENV: - return "ENVIRONMENTAL"; - case SmsCbCmasInfo.CMAS_CATEGORY_TRANSPORT: - return "TRANSPORTATION"; - case SmsCbCmasInfo.CMAS_CATEGORY_INFRA: - return "INFRASTRUCTURE"; - case SmsCbCmasInfo.CMAS_CATEGORY_CBRNE: - return "CHEMICAL"; - case SmsCbCmasInfo.CMAS_CATEGORY_OTHER: - return "OTHER"; - } - return "UNKNOWN"; - } - - private static String getCMASResponseType(int type) { - switch (type) { - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_SHELTER: - return "SHELTER"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EVACUATE: - return "EVACUATE"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_PREPARE: - return "PREPARE"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EXECUTE: - return "EXECUTE"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR: - return "MONITOR"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_AVOID: - return "AVOID"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_ASSESS: - return "ASSESS"; - case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE: - return "NONE"; - } - return "UNKNOWN"; - } - - private static String getCMASSeverity(int severity) { - switch (severity) { - case SmsCbCmasInfo.CMAS_SEVERITY_EXTREME: - return "EXTREME"; - case SmsCbCmasInfo.CMAS_SEVERITY_SEVERE: - return "SEVERE"; - } - return "UNKNOWN"; - } - - private static String getCMASUrgency(int urgency) { - switch (urgency) { - case SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE: - return "IMMEDIATE"; - case SmsCbCmasInfo.CMAS_URGENCY_EXPECTED: - return "EXPECTED"; - } - return "UNKNOWN"; - } - - private static String getCMASCertainty(int certainty) { - switch (certainty) { - case SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED: - return "IMMEDIATE"; - case SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY: - return "LIKELY"; - } - return "UNKNOWN"; - } - - private static String getGeographicalScope(int scope) { - switch (scope) { - case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE: - return "CELL_WIDE_IMMEDIATE"; - case SmsCbMessage.GEOGRAPHICAL_SCOPE_PLMN_WIDE: - return "PLMN_WIDE "; - case SmsCbMessage.GEOGRAPHICAL_SCOPE_LA_WIDE: - return "LA_WIDE"; - case SmsCbMessage.GEOGRAPHICAL_SCOPE_CELL_WIDE: - return "CELL_WIDE"; - } - return "UNKNOWN"; - } - - private static String getPriority(int priority) { - switch (priority) { - case SmsCbMessage.MESSAGE_PRIORITY_NORMAL: - return "NORMAL"; - case SmsCbMessage.MESSAGE_PRIORITY_INTERACTIVE: - return "INTERACTIVE"; - case SmsCbMessage.MESSAGE_PRIORITY_URGENT: - return "URGENT"; - case SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY: - return "EMERGENCY"; - } - return "UNKNOWN"; - } - - @Override - public void shutdown() { - - smsStopTrackingIncomingSmsMessage(); - smsStopTrackingIncomingMmsMessage(); - smsStopTrackingGsmEmergencyCBMessage(); - smsStopTrackingCdmaEmergencyCBMessage(); - - synchronized (lock) { - if (mSentReceiversRegistered) { - mService.unregisterReceiver(mSmsSendListener); - mService.unregisterReceiver(mMmsSendListener); - mSentReceiversRegistered = false; - } - } - } - - private class MmsBuilder { - - public static final String MESSAGE_CLASS_PERSONAL = - PduHeaders.MESSAGE_CLASS_PERSONAL_STR; - - public static final String MESSAGE_CLASS_ADVERTISEMENT = - PduHeaders.MESSAGE_CLASS_ADVERTISEMENT_STR; - - public static final String MESSAGE_CLASS_INFORMATIONAL = - PduHeaders.MESSAGE_CLASS_INFORMATIONAL_STR; - - public static final String MESSAGE_CLASS_AUTO = - PduHeaders.MESSAGE_CLASS_AUTO_STR; - - public static final int MESSAGE_PRIORITY_LOW = PduHeaders.PRIORITY_LOW; - public static final int MESSAGE_PRIORITY_NORMAL = PduHeaders.PRIORITY_LOW; - public static final int MESSAGE_PRIORITY_HIGH = PduHeaders.PRIORITY_LOW; - - private static final int DEFAULT_EXPIRY_TIME = 7 * 24 * 60 * 60; - private static final int DEFAULT_PRIORITY = PduHeaders.PRIORITY_NORMAL; - - private SendReq mRequest; - private PduBody mBody; - - // FIXME: Eventually this should be exposed as a parameter - private static final String TEMP_CONTENT_FILE_NAME = "text0.txt"; - - // Synchronized Multimedia Internet Language - // Fragment for compatibility - private static final String sSmilText = - "<smil>" + - "<head>" + - "<layout>" + - "<root-layout/>" + - "<region height=\"100%%\" id=\"Text\" left=\"0%%\"" + - " top=\"0%%\" width=\"100%%\"/>" + - "</layout>" + - "</head>" + - "<body>" + - "<par dur=\"8000ms\">" + - "<text src=\"%s\" region=\"Text\"/>" + - "</par>" + - "</body>" + - "</smil>"; - - public MmsBuilder() { - mRequest = new SendReq(); - mBody = new PduBody(); - } - - public void setFromPhoneNumber(String number) { - mRequest.setFrom(new EncodedStringValue(number)); - } - - public void setToPhoneNumber(String number) { - mRequest.setTo(new EncodedStringValue[] { - new EncodedStringValue(number) }); - } - - public void setToPhoneNumbers(List<String> number) { - mRequest.setTo(EncodedStringValue.encodeStrings((String[]) number.toArray())); - } - - public void setSubject(String subject) { - mRequest.setSubject(new EncodedStringValue(subject)); - } - - public void setDate() { - setDate(System.currentTimeMillis() / 1000); - } - - public void setDate(long time) { - mRequest.setDate(time); - } - - public void addMessageBody(String message) { - addMessageBody(message, true); - } - - public void setMessageClass(String messageClass) { - mRequest.setMessageClass(messageClass.getBytes()); - } - - public void setMessagePriority(int priority) { - try { - mRequest.setPriority(priority); - } catch (InvalidHeaderValueException e) { - Log.e("Invalid Header Value "+e.toString()); - } - } - - public void setDeliveryReport(boolean report) { - try { - mRequest.setDeliveryReport((report) ? PduHeaders.VALUE_YES : PduHeaders.VALUE_NO); - } catch (InvalidHeaderValueException e) { - Log.e("Invalid Header Value "+e.toString()); - } - } - - public void setReadReport(boolean report) { - try { - mRequest.setReadReport((report) ? PduHeaders.VALUE_YES : PduHeaders.VALUE_NO); - } catch (InvalidHeaderValueException e) { - Log.e("Invalid Header Value "+e.toString()); - } - } - - public void setExpirySeconds(int seconds) { - mRequest.setExpiry(seconds); - } - - public byte[] build() { - mRequest.setBody(mBody); - - int msgSize = 0; - for (int i = 0; i < mBody.getPartsNum(); i++) { - msgSize += mBody.getPart(i).getDataLength(); - } - mRequest.setMessageSize(msgSize); - - return new PduComposer(mContext, mRequest).make(); - } - - public void addMessageBody(String message, boolean addSmilFragment) { - final PduPart part = new PduPart(); - part.setCharset(CharacterSets.UTF_8); - part.setContentType(ContentType.TEXT_PLAIN.getBytes()); - part.setContentLocation("text0".getBytes()); - int index = TEMP_CONTENT_FILE_NAME.lastIndexOf("."); - String contentId = (index == -1) ? TEMP_CONTENT_FILE_NAME - : TEMP_CONTENT_FILE_NAME.substring(0, index); - part.setContentId(contentId.getBytes()); - part.setContentId("txt".getBytes()); - part.setData(message.getBytes()); - mBody.addPart(part); - if (addSmilFragment) { - addSmilTextFragment(TEMP_CONTENT_FILE_NAME); - } - } - - private void addSmilTextFragment(String contentFilename) { - - final String smil = String.format(sSmilText, contentFilename); - final PduPart smilPart = new PduPart(); - smilPart.setContentId("smil".getBytes()); - smilPart.setContentLocation("smil.xml".getBytes()); - smilPart.setContentType(ContentType.APP_SMIL.getBytes()); - smilPart.setData(smil.getBytes()); - mBody.addPart(0, smilPart); - } - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SubscriptionManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SubscriptionManagerFacade.java deleted file mode 100644 index 0031bc1..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/SubscriptionManagerFacade.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import android.app.Service; -import android.content.Context; -import android.telephony.SubscriptionManager; -import android.telephony.SubscriptionInfo; - -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.util.List; - -/** - * Exposes SubscriptionManager functionality. - */ -public class SubscriptionManagerFacade extends RpcReceiver { - - private final Service mService; - private final Context mContext; - private final SubscriptionManager mSubscriptionManager; - - public SubscriptionManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mContext = mService.getBaseContext(); - mSubscriptionManager = SubscriptionManager.from(mContext); - } - - @Rpc(description = "Return the default subscription ID") - public Integer subscriptionGetDefaultSubId() { - return SubscriptionManager.getDefaultSubscriptionId(); - } - - @Rpc(description = "Return the default data subscription ID") - public Integer subscriptionGetDefaultDataSubId() { - return SubscriptionManager.getDefaultDataSubscriptionId(); - } - - @Rpc(description = "Set the default data subscription ID") - public void subscriptionSetDefaultDataSubId( - @RpcParameter(name = "subId") - Integer subId) { - mSubscriptionManager.setDefaultDataSubId(subId); - } - - @Rpc(description = "Return the default voice subscription ID") - public Integer subscriptionGetDefaultVoiceSubId() { - return SubscriptionManager.getDefaultVoiceSubscriptionId(); - } - - @Rpc(description = "Set the default voice subscription ID") - public void subscriptionSetDefaultVoiceSubId( - @RpcParameter(name = "subId") - Integer subId) { - mSubscriptionManager.setDefaultVoiceSubId(subId); - } - - @Rpc(description = "Return the default sms subscription ID") - public Integer subscriptionGetDefaultSmsSubId() { - return SubscriptionManager.getDefaultSmsSubscriptionId(); - } - - @Rpc(description = "Set the default sms subscription ID") - public void subscriptionSetDefaultSmsSubId( - @RpcParameter(name = "subId") - Integer subId) { - mSubscriptionManager.setDefaultSmsSubId(subId); - } - - @Rpc(description = "Return a List of all Subscription Info Records") - public List<SubscriptionInfo> subscriptionGetAllSubInfoList() { - return mSubscriptionManager.getAllSubscriptionInfoList(); - } - - @Rpc(description = "Return a List of all Active Subscription Info Records") - public List<SubscriptionInfo> subscriptionGetActiveSubInfoList() { - return mSubscriptionManager.getActiveSubscriptionInfoList(); - } - - @Rpc(description = "Return the Subscription Info for a Particular Subscription ID") - public SubscriptionInfo subscriptionGetSubInfoForSubscriber( - @RpcParameter(name = "subId") - Integer subId) { - return mSubscriptionManager.getActiveSubscriptionInfo(subId); - } - - @Rpc(description = "Set Data Roaming Enabled or Disabled for a particular Subscription ID") - public Integer subscriptionSetDataRoaming(Integer roaming, Integer subId) { - if (roaming != SubscriptionManager.DATA_ROAMING_DISABLE) { - return mSubscriptionManager.setDataRoaming( - SubscriptionManager.DATA_ROAMING_ENABLE, subId); - } else { - return mSubscriptionManager.setDataRoaming( - SubscriptionManager.DATA_ROAMING_DISABLE, subId); - } - } - - @Override - public void shutdown() { - - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java deleted file mode 100644 index 070e649..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import android.app.Service; -import android.telecom.Call; -import android.telecom.CallAudioState; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.VideoProfile; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Exposes TelecomManager functionality. - */ -public class TelecomCallFacade extends RpcReceiver { - - private final Service mService; - - private List<PhoneAccountHandle> mEnabledAccountHandles = null; - - public TelecomCallFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - - InCallServiceImpl.setEventFacade( - manager.getReceiver(EventFacade.class)); - } - - @Override - public void shutdown() { - InCallServiceImpl.setEventFacade(null); - } - - /** - * Returns an identifier of the call. When a phone number is available, the number will be - * returned. Otherwise, the standard object toString result of the Call object. e.g. A - * conference call does not have a single number associated with it, thus the toString Id will - * be returned. - * - * @param call - * @return String - */ - - @Rpc(description = "Disconnect call by callId.") - public void telecomCallDisconnect( - @RpcParameter(name = "callId") - String callId) { - InCallServiceImpl.callDisconnect(callId); - } - - @Rpc(description = "Hold call by callId") - public void telecomCallHold( - @RpcParameter(name = "callId") - String callId) { - InCallServiceImpl.holdCall(callId); - } - - @Rpc(description = "Merge call to conference by callId") - public void telecomCallMergeToConf( - @RpcParameter(name = "callId") - String callId) { - InCallServiceImpl.mergeCallsInConference(callId); - } - - @Rpc(description = "Split call from conference by callId.") - public void telecomCallSplitFromConf( - @RpcParameter(name = "callId") - String callId) { - InCallServiceImpl.splitCallFromConf(callId); - } - - @Rpc(description = "Unhold call by callId") - public void telecomCallUnhold( - @RpcParameter(name = "callId") - String callId) { - InCallServiceImpl.unholdCall(callId); - } - - @Rpc(description = "Joins two calls into a conference call. " - + "Calls are identified by their " - + "IDs listed by telecomPhoneGetCallIds") - public void telecomCallJoinCallsInConf( - @RpcParameter(name = "callIdOne") - String callIdOne, - @RpcParameter(name = "callIdTwo") - String callIdTwo) { - InCallServiceImpl.joinCallsInConf(callIdOne, callIdTwo); - } - - @Rpc(description = "Obtains the current call audio state of the phone.") - public CallAudioState telecomCallGetAudioState() { - return InCallServiceImpl.serviceGetCallAudioState(); - } - - @Rpc(description = "Lists the IDs (phone numbers or hex hashes) " - + "of the current calls.") - public Set<String> telecomCallGetCallIds() { - return InCallServiceImpl.getCallIdList(); - } - @Rpc(description = "Get callId's children") - public List<String> telecomCallGetCallChildren( - @RpcParameter(name = "callId") String callId) { - return InCallServiceImpl.getCallChildren(callId); - } - @Rpc(description = "Get callId's parent") - public String telecomCallGetCallParent( - @RpcParameter(name = "callId") String callId) { - return InCallServiceImpl.getCallParent(callId); - } - @Rpc(description = "Swaps the calls within this conference") - public void telecomCallSwapCallsInConference( - @RpcParameter(name = "callId") String callId) { - InCallServiceImpl.swapCallsInConference(callId); - } - @Rpc(description = "Play a dual-tone multi-frequency signaling (DTMF) tone") - public void telecomCallPlayDtmfTone( - @RpcParameter(name = "callId") String callId, - @RpcParameter(name = "digit") String digitString) { - for(int i = 0; i < digitString.length(); i++) { - char c = digitString.charAt(i); - InCallServiceImpl.callPlayDtmfTone(callId, c); - } - } - @Rpc(description = "Stop any dual-tone multi-frequency signaling (DTMF) tone") - public void telecomCallStopDtmfTone( - @RpcParameter(name = "callId") String callId) { - InCallServiceImpl.callStopDtmfTone(callId); - } - @Rpc(description = "Obtains a list of text message, user to reject call.") - public List<String> telecomCallGetCannedTextResponses( - @RpcParameter(name = "callId") String callId) { - return InCallServiceImpl.callGetCannedTextResponses(callId); - } - @Rpc(description = "Reset the Call List.") - public void telecomCallClearCallList() { - InCallServiceImpl.clearCallList(); - } - - @Rpc(description = "Get the state of a call according to call id.") - public String telecomCallGetCallState( - @RpcParameter(name = "callId") - String callId) { - - return InCallServiceImpl.callGetState(callId); - } - - @Rpc(description = "Sets the audio route (SPEAKER, BLUETOOTH, etc...).") - public void telecomCallSetAudioRoute( - @RpcParameter(name = "route") - String route) { - - InCallServiceImpl.serviceSetAudioRoute(route); - } - - @Rpc(description = "Turns the proximity sensor off. " - + "If screenOnImmediately is true, " - + "the screen will be turned on immediately") - public void telecomCallOverrideProximitySensor( - @RpcParameter(name = "screenOn") - Boolean screenOn) { - InCallServiceImpl.overrideProximitySensor(screenOn); - } - - @Rpc(description = "Answer a call of a specified id, with video state") - public void telecomCallAnswer( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "videoState") - String videoState) { - InCallServiceImpl.callAnswer(callId, videoState); - } - - @Rpc(description = "Answer a call of a specified id, with video state") - public void telecomCallReject( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "message") - String message) { - InCallServiceImpl.callReject(callId, message); - } - - @Rpc(description = "Start Listening for a VideoCall Event") - public void telecomCallStartListeningForEvent( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "event") - String event) { - InCallServiceImpl.callStartListeningForEvent(callId, event); - } - - @Rpc(description = "Stop Listening for a Call Event") - public void telecomCallStopListeningForEvent( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "event") - String event) { - InCallServiceImpl.callStopListeningForEvent(callId, event); - } - - @Rpc(description = "Get the detailed information about a call") - public Call.Details telecomCallGetDetails( - @RpcParameter(name = "callId") - String callId) { - return InCallServiceImpl.callGetDetails(callId); - } - - @Rpc(description = "Return the capabilities for a call") - public List<String> telecomCallGetCapabilities( - @RpcParameter(name = "callId") - String callId) { - return InCallServiceImpl.callGetCallCapabilities(callId); - } - - @Rpc(description = "Return the properties for a call") - public List<String> telecomCallGetProperties( - @RpcParameter(name = "callId") - String callId) { - return InCallServiceImpl.callGetCallProperties(callId); - } - - @Rpc(description = "Start Listening for a VideoCall Event") - public void telecomCallVideoStartListeningForEvent( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "event") - String event) { - InCallServiceImpl.videoCallStartListeningForEvent(callId, event); - } - - @Rpc(description = "Stop Listening for a VideoCall Event") - public void telecomCallVideoStopListeningForEvent( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "event") - String event) { - InCallServiceImpl.videoCallStopListeningForEvent(callId, event); - } - - @Rpc(description = "Get the Video Call State") - public String telecomCallVideoGetState( - @RpcParameter(name = "call") - String callId) { - return InCallServiceImpl.videoCallGetState(callId); - } - - @Rpc(description = "Send a request to modify the video call session parameters") - public void telecomCallVideoSendSessionModifyRequest( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "videoState") - String videoState, - @RpcParameter(name = "videoQuality") - String videoQuality) { - InCallServiceImpl.videoCallSendSessionModifyRequest(callId, videoState, videoQuality); - } - - @Rpc(description = "Send a response to a modify the video call session request") - public void telecomCallVideoSendSessionModifyResponse( - @RpcParameter(name = "call") - String callId, - @RpcParameter(name = "videoState") - String videoState, - @RpcParameter(name = "videoQuality") - String videoQuality) { - InCallServiceImpl.videoCallSendSessionModifyResponse(callId, videoState, videoQuality); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomManagerFacade.java deleted file mode 100644 index caa60ab..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomManagerFacade.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Field; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import android.app.Service; -import android.content.ContentResolver; -import android.content.Intent; -import android.database.Cursor; -import android.telecom.AudioState; -import android.telecom.Call; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.TelecomManager; -import android.telecom.VideoProfile; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.net.Uri; -import android.provider.ContactsContract; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.AndroidFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Exposes TelecomManager functionality. - */ -public class TelecomManagerFacade extends RpcReceiver { - - private final Service mService; - private final AndroidFacade mAndroidFacade; - - private final TelecomManager mTelecomManager; - private final TelephonyManager mTelephonyManager; - - private List<PhoneAccountHandle> mEnabledAccountHandles = null; - - public TelecomManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mTelecomManager = new TelecomManager(mService); - mTelephonyManager = new TelephonyManager(mService); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - } - - @Override - public void shutdown() { - } - - @Rpc(description = "If there's a ringing call, accept on behalf of the user.") - public void telecomAcceptRingingCall( - @RpcOptional - String videoState) { - - if (videoState == null) { - mTelecomManager.acceptRingingCall(); - } - else { - int state = InCallServiceImpl.getVideoCallState(videoState); - - if (state == InCallServiceImpl.STATE_INVALID) { - Log.e("telecomAcceptRingingCall: video state is invalid!"); - return; - } - - mTelecomManager.acceptRingingCall(state); - } - } - - @Rpc(description = "Removes the missed-call notification if one is present.") - public void telecomCancelMissedCallsNotification() { - mTelecomManager.cancelMissedCallsNotification(); - } - - @Rpc(description = "Remove all Accounts that belong to the calling package from the system.") - public void telecomClearAccounts() { - mTelecomManager.clearAccounts(); - } - - @Rpc(description = "End an ongoing call.") - public Boolean telecomEndCall() { - return mTelecomManager.endCall(); - } - - @Rpc(description = "Get a list of all PhoneAccounts.") - public List<PhoneAccount> telecomGetAllPhoneAccounts() { - return mTelecomManager.getAllPhoneAccounts(); - } - - @Rpc(description = "Get the current call state.") - public String telecomGetCallState() { - int state = mTelecomManager.getCallState(); - return TelephonyUtils.getTelephonyCallStateString(state); - } - - @Rpc(description = "Get the current tty mode.") - public String telecomGetCurrentTtyMode() { - int mode = mTelecomManager.getCurrentTtyMode(); - return TelephonyUtils.getTtyModeString(mode); - } - - @Rpc(description = "Bring incallUI to foreground.") - public void telecomShowInCallScreen( - @RpcParameter(name = "showDialpad") - @RpcOptional - @RpcDefault("false") - Boolean showDialpad) { - mTelecomManager.showInCallScreen(showDialpad); - } - - @Rpc(description = "Get the list of PhoneAccountHandles with calling capability.") - public List<PhoneAccountHandle> telecomGetEnabledPhoneAccounts() { - mEnabledAccountHandles = mTelecomManager.getCallCapablePhoneAccounts(); - return mEnabledAccountHandles; - } - - @Rpc(description = "Set the user-chosen default PhoneAccount for making outgoing phone calls.") - public void telecomSetUserSelectedOutgoingPhoneAccount( - @RpcParameter(name = "phoneAccountHandleId") - String phoneAccountHandleId) throws Exception { - - List<PhoneAccountHandle> accountHandles = mTelecomManager - .getAllPhoneAccountHandles(); - for (PhoneAccountHandle handle : accountHandles) { - if (handle.getId().equals(phoneAccountHandleId)) { - mTelecomManager.setUserSelectedOutgoingPhoneAccount(handle); - Log.d(String.format("Set default Outgoing Phone Account(%s)", - phoneAccountHandleId)); - return; - } - } - Log.d(String.format( - "Failed to find a matching phoneAccountHandleId(%s).", - phoneAccountHandleId)); - throw new Exception(String.format( - "Failed to find a matching phoneAccountHandleId(%s).", - phoneAccountHandleId)); - } - - @Rpc(description = "Get the user-chosen default PhoneAccount for making outgoing phone calls.") - public PhoneAccountHandle telecomGetUserSelectedOutgoingPhoneAccount() { - return mTelecomManager.getUserSelectedOutgoingPhoneAccount(); - } - - @Rpc(description = "Set the PhoneAccount corresponding to user selected subscription id " + - " for making outgoing phone calls.") - public void telecomSetUserSelectedOutgoingPhoneAccountBySubId( - @RpcParameter(name = "subId") - Integer subId) throws Exception { - Iterator<PhoneAccountHandle> phoneAccounts = - mTelecomManager.getCallCapablePhoneAccounts().listIterator(); - - while (phoneAccounts.hasNext()) { - PhoneAccountHandle phoneAccountHandle = phoneAccounts.next(); - PhoneAccount phoneAccount = - mTelecomManager.getPhoneAccount(phoneAccountHandle); - if (subId == mTelephonyManager.getSubIdForPhoneAccount(phoneAccount)) { - mTelecomManager.setUserSelectedOutgoingPhoneAccount(phoneAccountHandle); - Log.d(String.format( - "Set default Outgoing Phone Account for subscription(%s)", subId)); - return; - } - } - Log.d(String.format( - "Failed to find a matching Phone Account for subscription (%s).", - subId)); - throw new Exception(String.format( - "Failed to find a matching Phone Account for subscription (%s).", - subId)); - } - - @Rpc(description = "Returns whether there is an ongoing phone call.") - public Boolean telecomIsInCall() { - return mTelecomManager.isInCall(); - } - - @Rpc(description = "Returns whether there is a ringing incoming call.") - public Boolean telecomIsRinging() { - return mTelecomManager.isRinging(); - } - - @Rpc(description = "Silences the rigner if there's a ringing call.") - public void telecomSilenceRinger() { - mTelecomManager.silenceRinger(); - } - - @Rpc(description = "Swap two calls") - public void telecomSwapCalls() { - // TODO: b/26273475 Add logic to swap the foreground and back ground calls - } - - @Rpc(description = "Toggles call waiting feature on or off for default voice subscription id.") - public void toggleCallWaiting( - @RpcParameter(name = "enabled") - @RpcOptional - Boolean enabled) { - toggleCallWaitingForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId(), enabled); - } - - @Rpc(description = "Toggles call waiting feature on or off for specified subscription id.") - public void toggleCallWaitingForSubscription( - @RpcParameter(name = "subId") - @RpcOptional - Integer subId, - @RpcParameter(name = "enabled") - @RpcOptional - Boolean enabled) { - // TODO: b/26273478 Enable or Disable the call waiting feature - } - - @Rpc(description = "Sends an MMI string to Telecom for processing") - public void telecomHandleMmi( - @RpcParameter(name = "dialString") - String dialString) { - mTelecomManager.handleMmi(dialString); - } - - // TODO: b/20917712 add support to pass arbitrary "Extras" object - // for videoCall parameter - @Deprecated - @Rpc(description = "Calls a phone by resolving a generic URI.") - public void telecomCall( - @RpcParameter(name = "uriString") - final String uriString, - @RpcParameter(name = "videoCall") - @RpcOptional - @RpcDefault("false") - Boolean videoCall) throws Exception { - - Log.w("Function telecomCall is deprecated; please use a URI-specific call"); - - Uri uri = Uri.parse(uriString); - if (uri.getScheme().equals("content")) { - telecomCallContentUri(uriString, videoCall); - } - else { - telecomCallNumber(uriString, videoCall); - } - } - - // TODO: b/20917712 add support to pass arbitrary "Extras" object - // for videoCall parameter - @Rpc(description = "Calls a phone by resolving a Content-type URI.") - public void telecomCallContentUri( - @RpcParameter(name = "uriString") - final String uriString, - @RpcParameter(name = "videoCall") - @RpcOptional - @RpcDefault("false") - Boolean videoCall) - throws Exception { - Uri uri = Uri.parse(uriString); - if (!uri.getScheme().equals("content")) { - Log.e("Invalid URI!!"); - return; - } - - String phoneNumberColumn = ContactsContract.PhoneLookup.NUMBER; - String selectWhere = null; - if ((FacadeManager.class.cast(mManager)).getSdkLevel() >= 5) { - Class<?> contactsContract_Data_class = - Class.forName("android.provider.ContactsContract$Data"); - Field RAW_CONTACT_ID_field = - contactsContract_Data_class.getField("RAW_CONTACT_ID"); - selectWhere = RAW_CONTACT_ID_field.get(null).toString() + "=" - + uri.getLastPathSegment(); - Field CONTENT_URI_field = - contactsContract_Data_class.getField("CONTENT_URI"); - uri = Uri.parse(CONTENT_URI_field.get(null).toString()); - Class<?> ContactsContract_CommonDataKinds_Phone_class = - Class.forName("android.provider.ContactsContract$CommonDataKinds$Phone"); - Field NUMBER_field = - ContactsContract_CommonDataKinds_Phone_class.getField("NUMBER"); - phoneNumberColumn = NUMBER_field.get(null).toString(); - } - ContentResolver resolver = mService.getContentResolver(); - Cursor c = resolver.query(uri, new String[] { - phoneNumberColumn - }, - selectWhere, null, null); - String number = ""; - if (c.moveToFirst()) { - number = c.getString(c.getColumnIndexOrThrow(phoneNumberColumn)); - } - c.close(); - telecomCallNumber(number, videoCall); - } - - // TODO: b/20917712 add support to pass arbitrary "Extras" object - // for videoCall parameter - @Rpc(description = "Calls a phone number.") - public void telecomCallNumber( - @RpcParameter(name = "number") - final String number, - @RpcParameter(name = "videoCall") - @RpcOptional - @RpcDefault("false") - Boolean videoCall) - throws Exception { - telecomCallTelUri("tel:" + URLEncoder.encode(number, "ASCII"), videoCall); - } - - // TODO: b/20917712 add support to pass arbitrary "Extras" object - // for videoCall parameter - @Rpc(description = "Calls a phone by Tel-URI.") - public void telecomCallTelUri( - @RpcParameter(name = "uriString") - final String uriString, - @RpcParameter(name = "videoCall") - @RpcOptional - @RpcDefault("false") - Boolean videoCall) throws Exception { - if (!uriString.startsWith("tel:")) { - Log.w("Invalid tel URI" + uriString); - return; - } - - Intent intent = new Intent(Intent.ACTION_CALL); - intent.setDataAndType(Uri.parse(uriString).normalizeScheme(), null); - - if (videoCall) { - Log.d("Placing a bi-directional video call"); - intent.putExtra(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, - VideoProfile.STATE_BIDIRECTIONAL); - } - - mAndroidFacade.startActivityIntent(intent, false); - } - - @Rpc(description = "Calls an Emergency number.") - public void telecomCallEmergencyNumber( - @RpcParameter(name = "number") - final String number) - throws Exception { - String uriString = "tel:" + URLEncoder.encode(number, "ASCII"); - mAndroidFacade.startActivity(Intent.ACTION_CALL_PRIVILEGED, uriString, - null, null, null, null, null); - } - - @Rpc(description = "Dials a contact/phone number by URI.") - public void telecomDial( - @RpcParameter(name = "uri") - final String uri) - throws Exception { - mAndroidFacade.startActivity(Intent.ACTION_DIAL, uri, null, null, null, - null, null); - } - - @Rpc(description = "Dials a phone number.") - public void telecomDialNumber(@RpcParameter(name = "phone number") - final String number) - throws Exception, UnsupportedEncodingException { - telecomDial("tel:" + URLEncoder.encode(number, "ASCII")); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java deleted file mode 100644 index 4c1b466..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyConstants.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -public class TelephonyConstants { - /** - * Constant for WiFi Calling WFC mode - * **/ - public static final String WFC_MODE_WIFI_ONLY = "WIFI_ONLY"; - public static final String WFC_MODE_CELLULAR_PREFERRED = "CELLULAR_PREFERRED"; - public static final String WFC_MODE_WIFI_PREFERRED = "WIFI_PREFERRED"; - public static final String WFC_MODE_DISABLED = "DISABLED"; - public static final String WFC_MODE_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Video Telephony VT state - * **/ - public static final String VT_STATE_AUDIO_ONLY = "AUDIO_ONLY"; - public static final String VT_STATE_TX_ENABLED = "TX_ENABLED"; - public static final String VT_STATE_RX_ENABLED = "RX_ENABLED"; - public static final String VT_STATE_BIDIRECTIONAL = "BIDIRECTIONAL"; - public static final String VT_STATE_TX_PAUSED = "TX_PAUSED"; - public static final String VT_STATE_RX_PAUSED = "RX_PAUSED"; - public static final String VT_STATE_BIDIRECTIONAL_PAUSED = "BIDIRECTIONAL_PAUSED"; - public static final String VT_STATE_STATE_INVALID = "INVALID"; - - /** - * Constant for Video Telephony Video quality - * **/ - public static final String VT_VIDEO_QUALITY_DEFAULT = "DEFAULT"; - public static final String VT_VIDEO_QUALITY_UNKNOWN = "UNKNOWN"; - public static final String VT_VIDEO_QUALITY_HIGH = "HIGH"; - public static final String VT_VIDEO_QUALITY_MEDIUM = "MEDIUM"; - public static final String VT_VIDEO_QUALITY_LOW = "LOW"; - public static final String VT_VIDEO_QUALITY_INVALID = "INVALID"; - - /** - * Constant for Call State (for call object) - * **/ - public static final String CALL_STATE_ACTIVE = "ACTIVE"; - public static final String CALL_STATE_NEW = "NEW"; - public static final String CALL_STATE_DIALING = "DIALING"; - public static final String CALL_STATE_RINGING = "RINGING"; - public static final String CALL_STATE_HOLDING = "HOLDING"; - public static final String CALL_STATE_DISCONNECTED = "DISCONNECTED"; - public static final String CALL_STATE_PRE_DIAL_WAIT = "PRE_DIAL_WAIT"; - public static final String CALL_STATE_CONNECTING = "CONNECTING"; - public static final String CALL_STATE_DISCONNECTING = "DISCONNECTING"; - public static final String CALL_STATE_UNKNOWN = "UNKNOWN"; - public static final String CALL_STATE_INVALID = "INVALID"; - - /** - * Constant for PRECISE Call State (for call object) - * **/ - public static final String PRECISE_CALL_STATE_ACTIVE = "ACTIVE"; - public static final String PRECISE_CALL_STATE_ALERTING = "ALERTING"; - public static final String PRECISE_CALL_STATE_DIALING = "DIALING"; - public static final String PRECISE_CALL_STATE_INCOMING = "INCOMING"; - public static final String PRECISE_CALL_STATE_HOLDING = "HOLDING"; - public static final String PRECISE_CALL_STATE_DISCONNECTED = "DISCONNECTED"; - public static final String PRECISE_CALL_STATE_WAITING = "WAITING"; - public static final String PRECISE_CALL_STATE_DISCONNECTING = "DISCONNECTING"; - public static final String PRECISE_CALL_STATE_IDLE = "IDLE"; - public static final String PRECISE_CALL_STATE_UNKNOWN = "UNKNOWN"; - public static final String PRECISE_CALL_STATE_INVALID = "INVALID"; - - /** - * Constant for DC POWER STATE - * **/ - public static final String DC_POWER_STATE_LOW = "LOW"; - public static final String DC_POWER_STATE_HIGH = "HIGH"; - public static final String DC_POWER_STATE_MEDIUM = "MEDIUM"; - public static final String DC_POWER_STATE_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Audio Route - * **/ - public static final String AUDIO_ROUTE_EARPIECE = "EARPIECE"; - public static final String AUDIO_ROUTE_BLUETOOTH = "BLUETOOTH"; - public static final String AUDIO_ROUTE_SPEAKER = "SPEAKER"; - public static final String AUDIO_ROUTE_WIRED_HEADSET = "WIRED_HEADSET"; - public static final String AUDIO_ROUTE_WIRED_OR_EARPIECE = "WIRED_OR_EARPIECE"; - - /** - * Constant for Call Capability - * **/ - public static final String CALL_CAPABILITY_HOLD = "HOLD"; - public static final String CALL_CAPABILITY_SUPPORT_HOLD = "SUPPORT_HOLD"; - public static final String CALL_CAPABILITY_MERGE_CONFERENCE = "MERGE_CONFERENCE"; - public static final String CALL_CAPABILITY_SWAP_CONFERENCE = "SWAP_CONFERENCE"; - public static final String CALL_CAPABILITY_UNUSED_1 = "UNUSED_1"; - public static final String CALL_CAPABILITY_RESPOND_VIA_TEXT = "RESPOND_VIA_TEXT"; - public static final String CALL_CAPABILITY_MUTE = "MUTE"; - public static final String CALL_CAPABILITY_MANAGE_CONFERENCE = "MANAGE_CONFERENCE"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_LOCAL_RX = "SUPPORTS_VT_LOCAL_RX"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_LOCAL_TX = "SUPPORTS_VT_LOCAL_TX"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL = "SUPPORTS_VT_LOCAL_BIDIRECTIONAL"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_REMOTE_RX = "SUPPORTS_VT_REMOTE_RX"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_REMOTE_TX = "SUPPORTS_VT_REMOTE_TX"; - public static final String CALL_CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL = "SUPPORTS_VT_REMOTE_BIDIRECTIONAL"; - public static final String CALL_CAPABILITY_SEPARATE_FROM_CONFERENCE = "SEPARATE_FROM_CONFERENCE"; - public static final String CALL_CAPABILITY_DISCONNECT_FROM_CONFERENCE = "DISCONNECT_FROM_CONFERENCE"; - public static final String CALL_CAPABILITY_SPEED_UP_MT_AUDIO = "SPEED_UP_MT_AUDIO"; - public static final String CALL_CAPABILITY_CAN_UPGRADE_TO_VIDEO = "CAN_UPGRADE_TO_VIDEO"; - public static final String CALL_CAPABILITY_CAN_PAUSE_VIDEO = "CAN_PAUSE_VIDEO"; - public static final String CALL_CAPABILITY_UNKOWN = "UNKOWN"; - - /** - * Constant for Call Property - * **/ - public static final String CALL_PROPERTY_HIGH_DEF_AUDIO = "HIGH_DEF_AUDIO"; - public static final String CALL_PROPERTY_CONFERENCE = "CONFERENCE"; - public static final String CALL_PROPERTY_GENERIC_CONFERENCE = "GENERIC_CONFERENCE"; - public static final String CALL_PROPERTY_WIFI = "WIFI"; - public static final String CALL_PROPERTY_EMERGENCY_CALLBACK_MODE = "EMERGENCY_CALLBACK_MODE"; - public static final String CALL_PROPERTY_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Call Presentation - * **/ - public static final String CALL_PRESENTATION_ALLOWED = "ALLOWED"; - public static final String CALL_PRESENTATION_RESTRICTED = "RESTRICTED"; - public static final String CALL_PRESENTATION_PAYPHONE = "PAYPHONE"; - public static final String CALL_PRESENTATION_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Network RAT - * **/ - public static final String RAT_IWLAN = "IWLAN"; - public static final String RAT_LTE = "LTE"; - public static final String RAT_4G = "4G"; - public static final String RAT_3G = "3G"; - public static final String RAT_2G = "2G"; - public static final String RAT_WCDMA = "WCDMA"; - public static final String RAT_UMTS = "UMTS"; - public static final String RAT_1XRTT = "1XRTT"; - public static final String RAT_EDGE = "EDGE"; - public static final String RAT_GPRS = "GPRS"; - public static final String RAT_HSDPA = "HSDPA"; - public static final String RAT_HSUPA = "HSUPA"; - public static final String RAT_CDMA = "CDMA"; - public static final String RAT_EVDO = "EVDO"; - public static final String RAT_EVDO_0 = "EVDO_0"; - public static final String RAT_EVDO_A = "EVDO_A"; - public static final String RAT_EVDO_B = "EVDO_B"; - public static final String RAT_IDEN = "IDEN"; - public static final String RAT_EHRPD = "EHRPD"; - public static final String RAT_HSPA = "HSPA"; - public static final String RAT_HSPAP = "HSPAP"; - public static final String RAT_GSM = "GSM"; - public static final String RAT_TD_SCDMA = "TD_SCDMA"; - public static final String RAT_GLOBAL = "GLOBAL"; - public static final String RAT_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Phone Type - * **/ - public static final String PHONE_TYPE_GSM = "GSM"; - public static final String PHONE_TYPE_NONE = "NONE"; - public static final String PHONE_TYPE_CDMA = "CDMA"; - public static final String PHONE_TYPE_SIP = "SIP"; - - /** - * Constant for SIM State - * **/ - public static final String SIM_STATE_READY = "READY"; - public static final String SIM_STATE_UNKNOWN = "UNKNOWN"; - public static final String SIM_STATE_ABSENT = "ABSENT"; - public static final String SIM_STATE_PUK_REQUIRED = "PUK_REQUIRED"; - public static final String SIM_STATE_PIN_REQUIRED = "PIN_REQUIRED"; - public static final String SIM_STATE_NETWORK_LOCKED = "NETWORK_LOCKED"; - public static final String SIM_STATE_NOT_READY = "NOT_READY"; - public static final String SIM_STATE_PERM_DISABLED = "PERM_DISABLED"; - public static final String SIM_STATE_CARD_IO_ERROR = "CARD_IO_ERROR"; - - /** - * Constant for Data Connection State - * **/ - public static final String DATA_STATE_CONNECTED = "CONNECTED"; - public static final String DATA_STATE_DISCONNECTED = "DISCONNECTED"; - public static final String DATA_STATE_CONNECTING = "CONNECTING"; - public static final String DATA_STATE_SUSPENDED = "SUSPENDED"; - public static final String DATA_STATE_UNKNOWN = "UNKNOWN"; - - /** - * Constant for Telephony Manager Call State - * **/ - public static final String TELEPHONY_STATE_RINGING = "RINGING"; - public static final String TELEPHONY_STATE_IDLE = "IDLE"; - public static final String TELEPHONY_STATE_OFFHOOK = "OFFHOOK"; - public static final String TELEPHONY_STATE_UNKNOWN = "UNKNOWN"; - - /** - * Constant for TTY Mode - * **/ - public static final String TTY_MODE_FULL = "FULL"; - public static final String TTY_MODE_HCO = "HCO"; - public static final String TTY_MODE_OFF = "OFF"; - public static final String TTY_MODE_VCO ="VCO"; - - /** - * Constant for Service State - * **/ - public static final String SERVICE_STATE_EMERGENCY_ONLY = "EMERGENCY_ONLY"; - public static final String SERVICE_STATE_IN_SERVICE = "IN_SERVICE"; - public static final String SERVICE_STATE_OUT_OF_SERVICE = "OUT_OF_SERVICE"; - public static final String SERVICE_STATE_POWER_OFF = "POWER_OFF"; - public static final String SERVICE_STATE_UNKNOWN = "UNKNOWN"; - - /** - * Constant for VoLTE Hand-over Service State - * **/ - public static final String VOLTE_SERVICE_STATE_HANDOVER_STARTED = "STARTED"; - public static final String VOLTE_SERVICE_STATE_HANDOVER_COMPLETED = "COMPLETED"; - public static final String VOLTE_SERVICE_STATE_HANDOVER_FAILED = "FAILED"; - public static final String VOLTE_SERVICE_STATE_HANDOVER_CANCELED = "CANCELED"; - public static final String VOLTE_SERVICE_STATE_HANDOVER_UNKNOWN = "UNKNOWN"; - - /** - * Constant for precise call state state listen level - * **/ - public static final String PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND = "FOREGROUND"; - public static final String PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING = "RINGING"; - public static final String PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND = "BACKGROUND"; - - /** - * Constant for Video Call Session Event Name - * **/ - public static final String SESSION_EVENT_RX_PAUSE = "SESSION_EVENT_RX_PAUSE"; - public static final String SESSION_EVENT_RX_RESUME = "SESSION_EVENT_RX_RESUME"; - public static final String SESSION_EVENT_TX_START = "SESSION_EVENT_TX_START"; - public static final String SESSION_EVENT_TX_STOP = "SESSION_EVENT_TX_STOP"; - public static final String SESSION_EVENT_CAMERA_FAILURE = "SESSION_EVENT_CAMERA_FAILURE"; - public static final String SESSION_EVENT_CAMERA_READY = "SESSION_EVENT_CAMERA_READY"; - public static final String SESSION_EVENT_UNKNOWN = "SESSION_EVENT_UNKNOWN"; - - /** - * Constants used to Register or de-register for Video Call Callbacks - * **/ - public static final String EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED = "EVENT_VIDEO_SESSION_MODIFY_REQUEST_RECEIVED"; - public static final String EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED = "EVENT_VIDEO_SESSION_MODIFY_RESPONSE_RECEIVED"; - public static final String EVENT_VIDEO_SESSION_EVENT = "EVENT_VIDEO_SESSION_EVENT"; - public static final String EVENT_VIDEO_PEER_DIMENSIONS_CHANGED = "EVENT_VIDEO_PEER_DIMENSIONS_CHANGED"; - public static final String EVENT_VIDEO_QUALITY_CHANGED = "EVENT_VIDEO_QUALITY_CHANGED"; - public static final String EVENT_VIDEO_DATA_USAGE_CHANGED = "EVENT_VIDEO_DATA_USAGE_CHANGED"; - public static final String EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED = "EVENT_VIDEO_CAMERA_CAPABILITIES_CHANGED"; - public static final String EVENT_VIDEO_INVALID = "EVENT_VIDEO_INVALID"; - - /** - * Constant for Network Preference - * **/ - public static final String NETWORK_MODE_WCDMA_PREF = "NETWORK_MODE_WCDMA_PREF"; - public static final String NETWORK_MODE_GSM_ONLY = "NETWORK_MODE_GSM_ONLY"; - public static final String NETWORK_MODE_WCDMA_ONLY = "NETWORK_MODE_WCDMA_ONLY"; - public static final String NETWORK_MODE_GSM_UMTS = "NETWORK_MODE_GSM_UMTS"; - public static final String NETWORK_MODE_CDMA = "NETWORK_MODE_CDMA"; - public static final String NETWORK_MODE_CDMA_NO_EVDO = "NETWORK_MODE_CDMA_NO_EVDO"; - public static final String NETWORK_MODE_EVDO_NO_CDMA = "NETWORK_MODE_EVDO_NO_CDMA"; - public static final String NETWORK_MODE_GLOBAL = "NETWORK_MODE_GLOBAL"; - public static final String NETWORK_MODE_LTE_CDMA_EVDO = "NETWORK_MODE_LTE_CDMA_EVDO"; - public static final String NETWORK_MODE_LTE_GSM_WCDMA = "NETWORK_MODE_LTE_GSM_WCDMA"; - public static final String NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA"; - public static final String NETWORK_MODE_LTE_ONLY = "NETWORK_MODE_LTE_ONLY"; - public static final String NETWORK_MODE_LTE_WCDMA = "NETWORK_MODE_LTE_WCDMA"; - public static final String NETWORK_MODE_TDSCDMA_ONLY = "NETWORK_MODE_TDSCDMA_ONLY"; - public static final String NETWORK_MODE_TDSCDMA_WCDMA = "NETWORK_MODE_TDSCDMA_WCDMA"; - public static final String NETWORK_MODE_LTE_TDSCDMA = "NETWORK_MODE_LTE_TDSCDMA"; - public static final String NETWORK_MODE_TDSCDMA_GSM = "NETWORK_MODE_TDSCDMA_GSM"; - public static final String NETWORK_MODE_LTE_TDSCDMA_GSM = "NETWORK_MODE_LTE_TDSCDMA_GSM"; - public static final String NETWORK_MODE_TDSCDMA_GSM_WCDMA = "NETWORK_MODE_TDSCDMA_GSM_WCDMA"; - public static final String NETWORK_MODE_LTE_TDSCDMA_WCDMA = "NETWORK_MODE_LTE_TDSCDMA_WCDMA"; - public static final String NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA = "NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA"; - public static final String NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA"; - public static final String NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = "NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA"; - public static final String NETWORK_MODE_INVALID = "INVALID"; - - /** - * Constant for Messaging Event Name - * **/ - public static final String EventSmsDeliverSuccess = "SmsDeliverSuccess"; - public static final String EventSmsDeliverFailure = "SmsDeliverFailure"; - public static final String EventSmsSentSuccess = "SmsSentSuccess"; - public static final String EventSmsSentFailure = "SmsSentFailure"; - public static final String EventSmsReceived = "SmsReceived"; - public static final String EventMmsSentSuccess = "MmsSentSuccess"; - public static final String EventMmsSentFailure = "MmsSentFailure"; - public static final String EventMmsDownloaded = "MmsDownloaded"; - public static final String EventWapPushReceived = "WapPushReceived"; - public static final String EventDataSmsReceived = "DataSmsReceived"; - public static final String EventCmasReceived = "CmasReceived"; - public static final String EventEtwsReceived = "EtwsReceived"; - - /** - * Constant for Telecom Call Event Name - * **/ - public static final String EventTelecomCallStateChanged = "TelecomCallStateChanged"; - public static final String EventTelecomCallParentChanged = "TelecomCallParentChanged"; - public static final String EventTelecomCallChildrenChanged = "TelecomCallChildrenChanged"; - public static final String EventTelecomCallDetailsChanged = "TelecomCallDetailsChanged"; - public static final String EventTelecomCallCannedTextResponsesLoaded = "TelecomCallCannedTextResponsesLoaded"; - public static final String EventTelecomCallPostDialWait = "TelecomCallPostDialWait"; - public static final String EventTelecomCallVideoCallChanged = "TelecomCallVideoCallChanged"; - public static final String EventTelecomCallDestroyed = "TelecomCallDestroyed"; - public static final String EventTelecomCallConferenceableCallsChanged = "TelecomCallConferenceableCallsChanged"; - - /** - * Constant for Video Call Event Name - * **/ - public static final String EventTelecomVideoCallSessionModifyRequestReceived = "TelecomVideoCallSessionModifyRequestReceived"; - public static final String EventTelecomVideoCallSessionModifyResponseReceived = "TelecomVideoCallSessionModifyResponseReceived"; - public static final String EventTelecomVideoCallSessionEvent = "TelecomVideoCallSessionEvent"; - public static final String EventTelecomVideoCallPeerDimensionsChanged = "TelecomVideoCallPeerDimensionsChanged"; - public static final String EventTelecomVideoCallVideoQualityChanged = "TelecomVideoCallVideoQualityChanged"; - public static final String EventTelecomVideoCallDataUsageChanged = "TelecomVideoCallDataUsageChanged"; - public static final String EventTelecomVideoCallCameraCapabilities = "TelecomVideoCallCameraCapabilities"; - - /** - * Constant for Other Event Name - * **/ - public static final String EventCellInfoChanged = "CellInfoChanged"; - public static final String EventCallStateChanged = "CallStateChanged"; - public static final String EventPreciseStateChanged = "PreciseStateChanged"; - public static final String EventDataConnectionRealTimeInfoChanged = "DataConnectionRealTimeInfoChanged"; - public static final String EventDataConnectionStateChanged = "DataConnectionStateChanged"; - public static final String EventServiceStateChanged = "ServiceStateChanged"; - public static final String EventSignalStrengthChanged = "SignalStrengthChanged"; - public static final String EventVolteServiceStateChanged = "VolteServiceStateChanged"; - public static final String EventMessageWaitingIndicatorChanged = "MessageWaitingIndicatorChanged"; - public static final String EventConnectivityChanged = "ConnectivityChanged"; - - /** - * Constant for Packet Keep Alive Call Back - * **/ - public static final String EventPacketKeepaliveCallback = "PacketKeepaliveCallback"; - - /*Sub-Event Names*/ - public static final String PacketKeepaliveCallbackStarted = "Started"; - public static final String PacketKeepaliveCallbackStopped = "Stopped"; - public static final String PacketKeepaliveCallbackError = "Error"; - public static final String PacketKeepaliveCallbackInvalid = "Invalid"; - - /** - * Constant for Network Call Back - * **/ - public static final String EventNetworkCallback = "NetworkCallback"; - - /*Sub-Event Names*/ - public static final String NetworkCallbackPreCheck = "PreCheck"; - public static final String NetworkCallbackAvailable = "Available"; - public static final String NetworkCallbackLosing = "Losing"; - public static final String NetworkCallbackLost = "Lost"; - public static final String NetworkCallbackUnavailable = "Unavailable"; - public static final String NetworkCallbackCapabilitiesChanged = "CapabilitiesChanged"; - public static final String NetworkCallbackSuspended = "Suspended"; - public static final String NetworkCallbackResumed = "Resumed"; - public static final String NetworkCallbackLinkPropertiesChanged = "LinkPropertiesChanged"; - public static final String NetworkCallbackInvalid = "Invalid"; - - /** - * Constant for Signal Strength fields - * **/ - public static class SignalStrengthContainer { - public static final String SIGNAL_STRENGTH_GSM = "gsmSignalStrength"; - public static final String SIGNAL_STRENGTH_GSM_DBM = "gsmDbm"; - public static final String SIGNAL_STRENGTH_GSM_LEVEL = "gsmLevel"; - public static final String SIGNAL_STRENGTH_GSM_ASU_LEVEL = "gsmAsuLevel"; - public static final String SIGNAL_STRENGTH_GSM_BIT_ERROR_RATE = "gsmBitErrorRate"; - public static final String SIGNAL_STRENGTH_CDMA_DBM = "cdmaDbm"; - public static final String SIGNAL_STRENGTH_CDMA_LEVEL = "cdmaLevel"; - public static final String SIGNAL_STRENGTH_CDMA_ASU_LEVEL = "cdmaAsuLevel"; - public static final String SIGNAL_STRENGTH_CDMA_ECIO = "cdmaEcio"; - public static final String SIGNAL_STRENGTH_EVDO_DBM = "evdoDbm"; - public static final String SIGNAL_STRENGTH_EVDO_ECIO = "evdoEcio"; - public static final String SIGNAL_STRENGTH_LTE = "lteSignalStrength"; - public static final String SIGNAL_STRENGTH_LTE_DBM = "lteDbm"; - public static final String SIGNAL_STRENGTH_LTE_LEVEL = "lteLevel"; - public static final String SIGNAL_STRENGTH_LTE_ASU_LEVEL = "lteAsuLevel"; - public static final String SIGNAL_STRENGTH_DBM = "dbm"; - public static final String SIGNAL_STRENGTH_LEVEL = "level"; - public static final String SIGNAL_STRENGTH_ASU_LEVEL = "asuLevel"; - } - - public static class CallStateContainer { - public static final String INCOMING_NUMBER = "incomingNumber"; - public static final String SUBSCRIPTION_ID = "subscriptionId"; - public static final String CALL_STATE = "callState"; - } - - public static class PreciseCallStateContainer { - public static final String TYPE = "type"; - public static final String CAUSE = "cause"; - public static final String SUBSCRIPTION_ID = "subscriptionId"; - public static final String PRECISE_CALL_STATE = "preciseCallState"; - } - - public static class DataConnectionRealTimeInfoContainer { - public static final String TYPE = "type"; - public static final String TIME = "time"; - public static final String SUBSCRIPTION_ID = "subscriptionId"; - public static final String DATA_CONNECTION_POWER_STATE = "dataConnectionPowerState"; - } - - public static class DataConnectionStateContainer { - public static final String TYPE = "type"; - public static final String DATA_NETWORK_TYPE = "dataNetworkType"; - public static final String STATE_CODE = "stateCode"; - public static final String SUBSCRIPTION_ID = "subscriptionId"; - public static final String DATA_CONNECTION_STATE = "dataConnectionState"; - } - - public static class ServiceStateContainer { - public static final String VOICE_REG_STATE = "voiceRegState"; - public static final String VOICE_NETWORK_TYPE = "voiceNetworkType"; - public static final String DATA_REG_STATE = "dataRegState"; - public static final String DATA_NETWORK_TYPE = "dataNetworkType"; - public static final String OPERATOR_NAME = "operatorName"; - public static final String OPERATOR_ID = "operatorId"; - public static final String IS_MANUAL_NW_SELECTION = "isManualNwSelection"; - public static final String ROAMING = "roaming"; - public static final String IS_EMERGENCY_ONLY = "isEmergencyOnly"; - public static final String NETWORK_ID = "networkId"; - public static final String SYSTEM_ID = "systemId"; - public static final String SUBSCRIPTION_ID = "subscriptionId"; - public static final String SERVICE_STATE = "serviceState"; - } - - public static class MessageWaitingIndicatorContainer { - public static final String IS_MESSAGE_WAITING = "isMessageWaiting"; - } - - public static class VoLteServiceStateContainer { - public static final String SRVCC_STATE = "srvccState"; - } - - public static class PacketKeepaliveContainer { - public static final String ID = "id"; - public static final String PACKET_KEEPALIVE_EVENT = "packetKeepaliveEvent"; - } - - public static class NetworkCallbackContainer { - public static final String ID = "id"; - public static final String NETWORK_CALLBACK_EVENT = "networkCallbackEvent"; - public static final String MAX_MS_TO_LIVE = "maxMsToLive"; - public static final String RSSI = "rssi"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java deleted file mode 100644 index 2c2e621..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyEvents.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import org.json.JSONException; -import org.json.JSONObject; -import android.telephony.DataConnectionRealTimeInfo; -import android.telephony.PreciseCallState; -import android.telephony.ServiceState; -import com.googlecode.android_scripting.jsonrpc.JsonSerializable; -import com.googlecode.android_scripting.facade.telephony.TelephonyConstants; -import com.googlecode.android_scripting.facade.telephony.TelephonyUtils; - -public class TelephonyEvents { - - public static class CallStateEvent implements JsonSerializable { - private String mCallState; - private String mIncomingNumber; - private int mSubscriptionId; - - CallStateEvent(int state, String incomingNumber, int subscriptionId) { - mCallState = null; - mIncomingNumber = TelephonyUtils.formatIncomingNumber( - incomingNumber); - mCallState = TelephonyUtils.getTelephonyCallStateString( - state); - mSubscriptionId = subscriptionId; - } - - public String getIncomingNumber() { - return mIncomingNumber; - } - - public int getSubscriptionId() { - return mSubscriptionId; - } - - public JSONObject toJSON() throws JSONException { - JSONObject callState = new JSONObject(); - - callState.put( - TelephonyConstants.CallStateContainer.SUBSCRIPTION_ID, - mSubscriptionId); - callState.put( - TelephonyConstants.CallStateContainer.INCOMING_NUMBER, - mIncomingNumber); - callState.put(TelephonyConstants.CallStateContainer.CALL_STATE, - mCallState); - - return callState; - } - } - - public static class PreciseCallStateEvent implements JsonSerializable { - private PreciseCallState mPreciseCallState; - private String mPreciseCallStateString; - private String mType; - private int mCause; - private int mSubscriptionId; - - PreciseCallStateEvent(int newState, String type, - PreciseCallState preciseCallState, int subscriptionId) { - mPreciseCallStateString = TelephonyUtils.getPreciseCallStateString( - newState); - mPreciseCallState = preciseCallState; - mType = type; - mSubscriptionId = subscriptionId; - mCause = preciseCallState.getPreciseDisconnectCause(); - } - - public String getType() { - return mType; - } - - public int getSubscriptionId() { - return mSubscriptionId; - } - - public PreciseCallState getPreciseCallState() { - return mPreciseCallState; - } - - public int getCause() { - return mCause; - } - - public JSONObject toJSON() throws JSONException { - JSONObject preciseCallState = new JSONObject(); - - preciseCallState.put( - TelephonyConstants.PreciseCallStateContainer.SUBSCRIPTION_ID, - mSubscriptionId); - preciseCallState.put( - TelephonyConstants.PreciseCallStateContainer.TYPE, mType); - preciseCallState.put( - TelephonyConstants.PreciseCallStateContainer.PRECISE_CALL_STATE, - mPreciseCallStateString); - preciseCallState.put( - TelephonyConstants.PreciseCallStateContainer.CAUSE, mCause); - - return preciseCallState; - } - } - - public static class DataConnectionRealTimeInfoEvent implements JsonSerializable { - private DataConnectionRealTimeInfo mDataConnectionRealTimeInfo; - private String mDataConnectionPowerState; - private int mSubscriptionId; - private long mTime; - - DataConnectionRealTimeInfoEvent( - DataConnectionRealTimeInfo dataConnectionRealTimeInfo, - int subscriptionId) { - mTime = dataConnectionRealTimeInfo.getTime(); - mSubscriptionId = subscriptionId; - mDataConnectionPowerState = TelephonyUtils.getDcPowerStateString( - dataConnectionRealTimeInfo.getDcPowerState()); - mDataConnectionRealTimeInfo = dataConnectionRealTimeInfo; - } - - public int getSubscriptionId() { - return mSubscriptionId; - } - - public long getTime() { - return mTime; - } - - public JSONObject toJSON() throws JSONException { - JSONObject dataConnectionRealTimeInfo = new JSONObject(); - - dataConnectionRealTimeInfo.put( - TelephonyConstants.DataConnectionRealTimeInfoContainer.SUBSCRIPTION_ID, - mSubscriptionId); - dataConnectionRealTimeInfo.put( - TelephonyConstants.DataConnectionRealTimeInfoContainer.TIME, - mTime); - dataConnectionRealTimeInfo.put( - TelephonyConstants.DataConnectionRealTimeInfoContainer.DATA_CONNECTION_POWER_STATE, - mDataConnectionPowerState); - - return dataConnectionRealTimeInfo; - } - } - - public static class DataConnectionStateEvent implements JsonSerializable { - private String mDataConnectionState; - private int mSubscriptionId; - private int mState; - private String mDataNetworkType; - - DataConnectionStateEvent(int state, String dataNetworkType, - int subscriptionId) { - mSubscriptionId = subscriptionId; - mDataConnectionState = TelephonyUtils.getDataConnectionStateString( - state); - mDataNetworkType = dataNetworkType; - mState = state; - } - - public int getSubscriptionId() { - return mSubscriptionId; - } - - public int getState() { - return mState; - } - - public String getDataNetworkType() { - return mDataNetworkType; - } - - public JSONObject toJSON() throws JSONException { - JSONObject dataConnectionState = new JSONObject(); - - dataConnectionState.put( - TelephonyConstants.DataConnectionStateContainer.SUBSCRIPTION_ID, - mSubscriptionId); - dataConnectionState.put( - TelephonyConstants.DataConnectionStateContainer.DATA_CONNECTION_STATE, - mDataConnectionState); - dataConnectionState.put( - TelephonyConstants.DataConnectionStateContainer.DATA_NETWORK_TYPE, - mDataNetworkType); - dataConnectionState.put( - TelephonyConstants.DataConnectionStateContainer.STATE_CODE, - mState); - - return dataConnectionState; - } - } - - public static class ServiceStateEvent implements JsonSerializable { - private String mServiceStateString; - private int mSubscriptionId; - private ServiceState mServiceState; - - ServiceStateEvent(ServiceState serviceState, int subscriptionId) { - mServiceState = serviceState; - mSubscriptionId = subscriptionId; - mServiceStateString = TelephonyUtils.getNetworkStateString( - serviceState.getState()); - if (mServiceStateString.equals( - TelephonyConstants.SERVICE_STATE_OUT_OF_SERVICE) && - serviceState.isEmergencyOnly()) { - mServiceStateString = TelephonyConstants.SERVICE_STATE_EMERGENCY_ONLY; - } - } - - public int getSubscriptionId() { - return mSubscriptionId; - } - - public ServiceState getServiceState() { - return mServiceState; - } - - public JSONObject toJSON() throws JSONException { - JSONObject serviceState = new JSONObject(); - - serviceState.put( - TelephonyConstants.ServiceStateContainer.SUBSCRIPTION_ID, - mSubscriptionId); - serviceState.put( - TelephonyConstants.ServiceStateContainer.VOICE_REG_STATE, - TelephonyUtils.getNetworkStateString( - mServiceState.getVoiceRegState())); - serviceState.put( - TelephonyConstants.ServiceStateContainer.VOICE_NETWORK_TYPE, - TelephonyUtils.getNetworkTypeString( - mServiceState.getVoiceNetworkType())); - serviceState.put( - TelephonyConstants.ServiceStateContainer.DATA_REG_STATE, - TelephonyUtils.getNetworkStateString( - mServiceState.getDataRegState())); - serviceState.put( - TelephonyConstants.ServiceStateContainer.DATA_NETWORK_TYPE, - TelephonyUtils.getNetworkTypeString( - mServiceState.getDataNetworkType())); - serviceState.put( - TelephonyConstants.ServiceStateContainer.OPERATOR_NAME, - mServiceState.getOperatorAlphaLong()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.OPERATOR_ID, - mServiceState.getOperatorNumeric()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.IS_MANUAL_NW_SELECTION, - mServiceState.getIsManualSelection()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.ROAMING, - mServiceState.getRoaming()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.IS_EMERGENCY_ONLY, - mServiceState.isEmergencyOnly()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.NETWORK_ID, - mServiceState.getNetworkId()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.SYSTEM_ID, - mServiceState.getSystemId()); - serviceState.put( - TelephonyConstants.ServiceStateContainer.SERVICE_STATE, - mServiceStateString); - - return serviceState; - } - } - - public static class MessageWaitingIndicatorEvent implements JsonSerializable { - private boolean mMessageWaitingIndicator; - - MessageWaitingIndicatorEvent(boolean messageWaitingIndicator) { - mMessageWaitingIndicator = messageWaitingIndicator; - } - - public boolean getMessageWaitingIndicator() { - return mMessageWaitingIndicator; - } - - public JSONObject toJSON() throws JSONException { - JSONObject messageWaitingIndicator = new JSONObject(); - - messageWaitingIndicator.put( - TelephonyConstants.MessageWaitingIndicatorContainer.IS_MESSAGE_WAITING, - mMessageWaitingIndicator); - - return messageWaitingIndicator; - } - } - - public static class PacketKeepaliveEvent implements JsonSerializable { - private String mId; - private String mPacketKeepaliveEvent; - - public PacketKeepaliveEvent(String id, String event) { - mId = id; - mPacketKeepaliveEvent = event; - } - - public JSONObject toJSON() throws JSONException { - JSONObject packetKeepalive = new JSONObject(); - - packetKeepalive.put( - TelephonyConstants.PacketKeepaliveContainer.ID, - mId); - packetKeepalive.put( - TelephonyConstants.PacketKeepaliveContainer.PACKET_KEEPALIVE_EVENT, - mPacketKeepaliveEvent); - - return packetKeepalive; - } - } - - public static class NetworkCallbackEvent implements JsonSerializable { - public static final Integer INVALID_VALUE = null; - private String mId; - private String mNetworkCallbackEvent; - private Integer mRssi; - private Integer mMaxMsToLive; - - public NetworkCallbackEvent(String id, String event, Integer rssi, Integer maxMsToLive) { - mId = id; - mNetworkCallbackEvent = event; - mRssi = rssi; - mMaxMsToLive = maxMsToLive; - } - - public JSONObject toJSON() throws JSONException { - JSONObject networkCallback = new JSONObject(); - - networkCallback.put( - TelephonyConstants.NetworkCallbackContainer.ID, - mId); - networkCallback.put( - TelephonyConstants.NetworkCallbackContainer.NETWORK_CALLBACK_EVENT, - mNetworkCallbackEvent); - networkCallback.put( - TelephonyConstants.NetworkCallbackContainer.MAX_MS_TO_LIVE, - mMaxMsToLive); - networkCallback.put( - TelephonyConstants.NetworkCallbackContainer.RSSI, - mRssi); - - return networkCallback; - } - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java deleted file mode 100644 index 333274a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyManagerFacade.java +++ /dev/null @@ -1,1183 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import android.app.Activity; -import android.app.Service; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.RemoteException; -import android.provider.ContactsContract; -import android.telephony.CellInfo; -import android.telephony.CellLocation; -import android.telephony.ModemActivityInfo; -import android.telephony.NeighboringCellInfo; -import android.telephony.PhoneStateListener; -import android.telephony.SignalStrength; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.provider.Telephony; -import android.telephony.SubscriptionInfo; -import android.telecom.VideoProfile; -import android.telecom.TelecomManager; -import android.util.Base64; - -import com.android.internal.telephony.PhoneConstants; -import com.android.internal.telephony.RILConstants; -import com.android.internal.telephony.TelephonyProperties; -import com.google.common.io.BaseEncoding; - -import android.content.ContentValues; -import android.os.SystemProperties; - -import com.googlecode.android_scripting.facade.AndroidFacade; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .CallStateChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .CellInfoChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .DataConnectionRealTimeInfoChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .DataConnectionStateChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .ServiceStateChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .SignalStrengthChangeListener; -import com.googlecode.android_scripting.facade.telephony.TelephonyStateListeners - .VoiceMailStateChangeListener; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.rpc.RpcOptional; - -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Field; -import java.net.URLEncoder; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.HashMap; - -/** - * Exposes TelephonyManager functionality. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Felix Arends (felix.arends@gmail.com) - */ -public class TelephonyManagerFacade extends RpcReceiver { - - private final Service mService; - private final AndroidFacade mAndroidFacade; - private final EventFacade mEventFacade; - private final TelephonyManager mTelephonyManager; - private final SubscriptionManager mSubscriptionManager; - private List<SubscriptionInfo> mSubInfos; - private HashMap<Integer, StateChangeListener> StateChangeListeners = - new HashMap<Integer, StateChangeListener>(); - - private static final String[] sProjection = new String[] { - Telephony.Carriers._ID, // 0 - Telephony.Carriers.NAME, // 1 - Telephony.Carriers.APN, // 2 - Telephony.Carriers.PROXY, // 3 - Telephony.Carriers.PORT, // 4 - Telephony.Carriers.USER, // 5 - Telephony.Carriers.SERVER, // 6 - Telephony.Carriers.PASSWORD, // 7 - Telephony.Carriers.MMSC, // 8 - Telephony.Carriers.MCC, // 9 - Telephony.Carriers.MNC, // 10 - Telephony.Carriers.NUMERIC, // 11 - Telephony.Carriers.MMSPROXY,// 12 - Telephony.Carriers.MMSPORT, // 13 - Telephony.Carriers.AUTH_TYPE, // 14 - Telephony.Carriers.TYPE, // 15 - Telephony.Carriers.PROTOCOL, // 16 - Telephony.Carriers.CARRIER_ENABLED, // 17 - Telephony.Carriers.BEARER_BITMASK, // 18 - Telephony.Carriers.ROAMING_PROTOCOL, // 19 - Telephony.Carriers.MVNO_TYPE, // 20 - Telephony.Carriers.MVNO_MATCH_DATA // 21 - }; - - public TelephonyManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mTelephonyManager = - (TelephonyManager) mService.getSystemService(Context.TELEPHONY_SERVICE); - mAndroidFacade = manager.getReceiver(AndroidFacade.class); - mEventFacade = manager.getReceiver(EventFacade.class); - mSubscriptionManager = SubscriptionManager.from(mService); - mSubInfos = mSubscriptionManager.getAllSubscriptionInfoList(); - MainThread.run(manager.getService(), new Callable<Object>() { - @Override - public Object call() throws Exception { - // Creating listeners for all subscription IDs - for (int i = 0; i < mSubInfos.size(); i++) { - int subId = mSubInfos.get(i).getSubscriptionId(); - StateChangeListener tempStateListener = - new StateChangeListener(); - tempStateListener.mServiceStateChangeListener = - new ServiceStateChangeListener(mEventFacade, subId); - tempStateListener.mSignalStrengthChangeListener = - new SignalStrengthChangeListener(mEventFacade, subId); - tempStateListener.mDataConnectionStateChangeListener = - new DataConnectionStateChangeListener(mEventFacade, - mTelephonyManager, subId); - tempStateListener.mCallStateChangeListener = - new CallStateChangeListener(mEventFacade, subId); - tempStateListener.mCellInfoChangeListener = - new CellInfoChangeListener(mEventFacade, subId); - tempStateListener.mDataConnectionRTInfoChangeListener = - new DataConnectionRealTimeInfoChangeListener(mEventFacade, - subId); - tempStateListener.mVoiceMailStateChangeListener = - new VoiceMailStateChangeListener(mEventFacade, subId); - - StateChangeListeners.put(subId, tempStateListener); - } - return null; - } - }); - } - - @Rpc(description = "Set network preference.") - public boolean telephonySetPreferredNetworkTypes( - @RpcParameter(name = "nwPreference") String nwPreference) { - return telephonySetPreferredNetworkTypesForSubscription(nwPreference, - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Set network preference for subscription.") - public boolean telephonySetPreferredNetworkTypesForSubscription( - @RpcParameter(name = "nwPreference") String nwPreference, - @RpcParameter(name = "subId") Integer subId) { - int networkPreferenceInt = TelephonyUtils.getNetworkModeIntfromString( - nwPreference); - if (RILConstants.RIL_ERRNO_INVALID_RESPONSE != networkPreferenceInt) { - return mTelephonyManager.setPreferredNetworkType( - subId, networkPreferenceInt); - } else { - return false; - } - } - - @Rpc(description = "Get network preference.") - public String telephonyGetPreferredNetworkTypes() { - return telephonyGetPreferredNetworkTypesForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Get network preference for subscription.") - public String telephonyGetPreferredNetworkTypesForSubscription( - @RpcParameter(name = "subId") Integer subId) { - int networkPreferenceInt = mTelephonyManager.getPreferredNetworkType(subId); - return TelephonyUtils.getNetworkModeStringfromInt(networkPreferenceInt); - } - - @Rpc(description = "Get current voice network type") - public String telephonyGetCurrentVoiceNetworkType() { - return telephonyGetCurrentVoiceNetworkTypeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Get current voice network type for subscription") - public String telephonyGetCurrentVoiceNetworkTypeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getVoiceNetworkType(subId)); - } - - @Rpc(description = "Get current data network type") - public String telephonyGetCurrentDataNetworkType() { - return telephonyGetCurrentDataNetworkTypeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Get current data network type for subscription") - public String telephonyGetCurrentDataNetworkTypeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getDataNetworkType(subId)); - } - - @Rpc(description = "Get if phone have voice capability") - public boolean telephonyIsVoiceCapable() { - return mTelephonyManager.isVoiceCapable(); - } - - @Rpc(description = "Get preferred network setting for " + - "default subscription ID .Return value is integer.") - public int telephonyGetPreferredNetworkTypeInteger() { - return telephonyGetPreferredNetworkTypeIntegerForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Get preferred network setting for " + - "specified subscription ID .Return value is integer.") - public int telephonyGetPreferredNetworkTypeIntegerForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getPreferredNetworkType(subId); - } - - @Rpc(description = "Starts tracking call state change" + - "for default subscription ID.") - public Boolean telephonyStartTrackingCallState() { - return telephonyStartTrackingCallStateForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Starts tracking call state change" + - "for specified subscription ID.") - public Boolean telephonyStartTrackingCallStateForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mCallStateChangeListener, - CallStateChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking cell info change" + - "for default subscription ID.") - public Boolean telephonyStartTrackingCellInfoChange() { - return telephonyStartTrackingCellInfoChangeForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Starts tracking cell info change" + - "for specified subscription ID.") - public Boolean telephonyStartTrackingCellInfoChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mCellInfoChangeListener, - PhoneStateListener.LISTEN_CELL_INFO); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Turn on/off precise listening on fore/background or" + - " ringing calls for default voice subscription ID.") - public Boolean telephonyAdjustPreciseCallStateListenLevel(String type, - Boolean listen) { - return telephonyAdjustPreciseCallStateListenLevelForSubscription(type, listen, - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Turn on/off precise listening on fore/background or" + - " ringing calls for specified subscription ID.") - public Boolean telephonyAdjustPreciseCallStateListenLevelForSubscription(String type, - Boolean listen, - @RpcParameter(name = "subId") Integer subId) { - try { - if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND)) { - StateChangeListeners.get(subId).mCallStateChangeListener.listenForeground = listen; - } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING)) { - StateChangeListeners.get(subId).mCallStateChangeListener.listenRinging = listen; - } else if (type.equals(TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND)) { - StateChangeListeners.get(subId).mCallStateChangeListener.listenBackground = listen; - } - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking cell info change " + - "for default voice subscription ID.") - public Boolean telephonyStopTrackingCellInfoChange() { - return telephonyStopTrackingCellInfoChangeForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Stops tracking cell info change " + - "for specified subscription ID.") - public Boolean telephonyStopTrackingCellInfoChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mCellInfoChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - @Rpc(description = "Stops tracking call state change " + - "for default voice subscription ID.") - public Boolean telephonyStopTrackingCallStateChange() { - return telephonyStopTrackingCallStateChangeForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Stops tracking call state change " + - "for specified subscription ID.") - public Boolean telephonyStopTrackingCallStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mCallStateChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking data connection real time info change" + - "for default subscription ID.") - public Boolean telephonyStartTrackingDataConnectionRTInfoChange() { - return telephonyStartTrackingDataConnectionRTInfoChangeForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Starts tracking data connection real time info change" + - "for specified subscription ID.") - public Boolean telephonyStartTrackingDataConnectionRTInfoChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mDataConnectionRTInfoChangeListener, - DataConnectionRealTimeInfoChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking data connection real time info change" + - "for default subscription ID.") - public Boolean telephonyStopTrackingDataConnectionRTInfoChange() { - return telephonyStopTrackingDataConnectionRTInfoChangeForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Stops tracking data connection real time info change" + - "for specified subscription ID.") - public Boolean telephonyStopTrackingDataConnectionRTInfoChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mDataConnectionRTInfoChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking data connection state change" + - "for default subscription ID..") - public Boolean telephonyStartTrackingDataConnectionStateChange() { - return telephonyStartTrackingDataConnectionStateChangeForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Starts tracking data connection state change" + - "for specified subscription ID.") - public Boolean telephonyStartTrackingDataConnectionStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mDataConnectionStateChangeListener, - DataConnectionStateChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking data connection state change " + - "for default subscription ID..") - public Boolean telephonyStopTrackingDataConnectionStateChange() { - return telephonyStopTrackingDataConnectionStateChangeForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Stops tracking data connection state change " + - "for specified subscription ID..") - public Boolean telephonyStopTrackingDataConnectionStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mDataConnectionStateChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking service state change " + - "for default subscription ID.") - public Boolean telephonyStartTrackingServiceStateChange() { - return telephonyStartTrackingServiceStateChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Starts tracking service state change " + - "for specified subscription ID.") - public Boolean telephonyStartTrackingServiceStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mServiceStateChangeListener, - ServiceStateChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking service state change " + - "for default subscription ID.") - public Boolean telephonyStopTrackingServiceStateChange() { - return telephonyStopTrackingServiceStateChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Stops tracking service state change " + - "for specified subscription ID.") - public Boolean telephonyStopTrackingServiceStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mServiceStateChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking signal strength change " + - "for default subscription ID.") - public Boolean telephonyStartTrackingSignalStrengthChange() { - return telephonyStartTrackingSignalStrengthChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Starts tracking signal strength change " + - "for specified subscription ID.") - public Boolean telephonyStartTrackingSignalStrengthChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mSignalStrengthChangeListener, - SignalStrengthChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking signal strength change " + - "for default subscription ID.") - public Boolean telephonyStopTrackingSignalStrengthChange() { - return telephonyStopTrackingSignalStrengthChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Stops tracking signal strength change " + - "for specified subscription ID.") - public Boolean telephonyStopTrackingSignalStrengthChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mSignalStrengthChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Starts tracking voice mail state change " + - "for default subscription ID.") - public Boolean telephonyStartTrackingVoiceMailStateChange() { - return telephonyStartTrackingVoiceMailStateChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Starts tracking voice mail state change " + - "for specified subscription ID.") - public Boolean telephonyStartTrackingVoiceMailStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mVoiceMailStateChangeListener, - VoiceMailStateChangeListener.sListeningStates); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Stops tracking voice mail state change " + - "for default subscription ID.") - public Boolean telephonyStopTrackingVoiceMailStateChange() { - return telephonyStopTrackingVoiceMailStateChangeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Stops tracking voice mail state change " + - "for specified subscription ID.") - public Boolean telephonyStopTrackingVoiceMailStateChangeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - try { - mTelephonyManager.listen( - StateChangeListeners.get(subId).mVoiceMailStateChangeListener, - PhoneStateListener.LISTEN_NONE); - return true; - } catch (Exception e) { - Log.e("Invalid subscription ID"); - return false; - } - } - - @Rpc(description = "Answers an incoming ringing call.") - public void telephonyAnswerCall() throws RemoteException { - mTelephonyManager.silenceRinger(); - mTelephonyManager.answerRingingCall(); - } - - @Rpc(description = "Returns the current cell location.") - public CellLocation telephonyGetCellLocation() { - return mTelephonyManager.getCellLocation(); - } - - @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator." + - "for default subscription ID") - public String telephonyGetNetworkOperator() { - return telephonyGetNetworkOperatorForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the numeric name (MCC+MNC) of registered operator" + - "for specified subscription ID.") - public String telephonyGetNetworkOperatorForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getNetworkOperator(subId); - } - - @Rpc(description = "Returns the alphabetic name of current registered operator" + - "for specified subscription ID.") - public String telephonyGetNetworkOperatorName() { - return telephonyGetNetworkOperatorNameForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the alphabetic name of registered operator " + - "for specified subscription ID.") - public String telephonyGetNetworkOperatorNameForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getNetworkOperatorName(subId); - } - - @Rpc(description = "Returns the current RAT in use on the device.+" + - "for default subscription ID") - public String telephonyGetNetworkType() { - - Log.d("sl4a:getNetworkType() is deprecated!" + - "Please use getVoiceNetworkType()" + - " or getDataNetworkTpe()"); - - return telephonyGetNetworkTypeForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the current RAT in use on the device" + - " for a given Subscription.") - public String telephonyGetNetworkTypeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - - Log.d("sl4a:getNetworkTypeForSubscriber() is deprecated!" + - "Please use getVoiceNetworkType()" + - " or getDataNetworkTpe()"); - - return TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getNetworkType(subId)); - } - - @Rpc(description = "Returns the current voice RAT for" + - " the default voice subscription.") - public String telephonyGetVoiceNetworkType() { - return telephonyGetVoiceNetworkTypeForSubscription( - SubscriptionManager.getDefaultVoiceSubscriptionId()); - } - - @Rpc(description = "Returns the current voice RAT for" + - " the specified voice subscription.") - public String telephonyGetVoiceNetworkTypeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getVoiceNetworkType(subId)); - } - - @Rpc(description = "Returns the current data RAT for" + - " the defaut data subscription") - public String telephonyGetDataNetworkType() { - return telephonyGetDataNetworkTypeForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Returns the current data RAT for" + - " the specified data subscription") - public String telephonyGetDataNetworkTypeForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getDataNetworkType(subId)); - } - - @Rpc(description = "Returns the device phone type.") - public String telephonyGetPhoneType() { - return TelephonyUtils.getPhoneTypeString( - mTelephonyManager.getPhoneType()); - } - - @Rpc(description = "Returns the MCC for default subscription ID") - public String telephonyGetSimCountryIso() { - return telephonyGetSimCountryIsoForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Get the latest power consumption stats from the modem") - public ModemActivityInfo telephonyGetModemActivityInfo() { - ModemActivityInfo info = mTelephonyManager.getModemActivityInfo(); - return info; - } - - @Rpc(description = "Returns the MCC for specified subscription ID") - public String telephonyGetSimCountryIsoForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getSimCountryIso(subId); - } - - @Rpc(description = "Returns the MCC+MNC for default subscription ID") - public String telephonyGetSimOperator() { - return telephonyGetSimOperatorForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the MCC+MNC for specified subscription ID") - public String telephonyGetSimOperatorForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getSimOperator(subId); - } - - @Rpc(description = "Returns the Service Provider Name (SPN)" + - "for default subscription ID") - public String telephonyGetSimOperatorName() { - return telephonyGetSimOperatorNameForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the Service Provider Name (SPN)" + - " for specified subscription ID.") - public String telephonyGetSimOperatorNameForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getSimOperatorName(subId); - } - - @Rpc(description = "Returns the serial number of the SIM for " + - "default subscription ID, or Null if unavailable") - public String telephonyGetSimSerialNumber() { - return telephonyGetSimSerialNumberForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the serial number of the SIM for " + - "specified subscription ID, or Null if unavailable") - public String telephonyGetSimSerialNumberForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getSimSerialNumber(subId); - } - - @Rpc(description = "Returns the state of the SIM card for default slot ID.") - public String telephonyGetSimState() { - return telephonyGetSimStateForSlotId( - mTelephonyManager.getDefaultSim()); - } - - @Rpc(description = "Returns the state of the SIM card for specified slot ID.") - public String telephonyGetSimStateForSlotId( - @RpcParameter(name = "slotId") Integer slotId) { - return TelephonyUtils.getSimStateString( - mTelephonyManager.getSimState(slotId)); - } - - @Rpc(description = "Get Authentication Challenge Response from a " + - "given SIM Application") - public String telephonyGetIccSimChallengeResponse( - @RpcParameter(name = "appType") Integer appType, - @RpcParameter(name = "hexChallenge") String hexChallenge) { - return telephonyGetIccSimChallengeResponseForSubscription( - SubscriptionManager.getDefaultSubscriptionId(), appType, hexChallenge); - } - - @Rpc(description = "Get Authentication Challenge Response from a " + - "given SIM Application for a specified Subscription") - public String telephonyGetIccSimChallengeResponseForSubscription( - @RpcParameter(name = "subId") Integer subId, - @RpcParameter(name = "appType") Integer appType, - @RpcParameter(name = "hexChallenge") String hexChallenge) { - - try { - String b64Data = BaseEncoding.base64().encode(BaseEncoding.base16().decode(hexChallenge)); - String b64Result = mTelephonyManager.getIccSimChallengeResponse(subId, appType, b64Data); - return (b64Result != null) - ? BaseEncoding.base16().encode(BaseEncoding.base64().decode(b64Result)) : null; - } catch( Exception e) { - Log.e("Exception in phoneGetIccSimChallengeResponseForSubscription" + e.toString()); - return null; - } - } - - @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " + - "for default subscription ID, or null if unavailable") - public String telephonyGetSubscriberId() { - return telephonyGetSubscriberIdForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the unique subscriber ID (such as IMSI) " + - "for specified subscription ID, or null if unavailable") - public String telephonyGetSubscriberIdForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getSubscriberId(subId); - } - - @Rpc(description = "Retrieves the alphabetic id associated with the" + - " voice mail number for default subscription ID.") - public String telephonyGetVoiceMailAlphaTag() { - return telephonyGetVoiceMailAlphaTagForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - - @Rpc(description = "Retrieves the alphabetic id associated with the " + - "voice mail number for specified subscription ID.") - public String telephonyGetVoiceMailAlphaTagForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getVoiceMailAlphaTag(subId); - } - - @Rpc(description = "Returns the voice mail number " + - "for default subscription ID; null if unavailable.") - public String telephonyGetVoiceMailNumber() { - return telephonyGetVoiceMailNumberForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the voice mail number " + - "for specified subscription ID; null if unavailable.") - public String telephonyGetVoiceMailNumberForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getVoiceMailNumber(subId); - } - - @Rpc(description = "Get voice message count for specified subscription ID.") - public Integer telephonyGetVoiceMailCountForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getVoiceMessageCount(subId); - } - - @Rpc(description = "Get voice message count for default subscription ID.") - public Integer telephonyGetVoiceMailCount() { - return mTelephonyManager.getVoiceMessageCount(); - } - - @Rpc(description = "Returns true if the device is in roaming state" + - "for default subscription ID") - public Boolean telephonyCheckNetworkRoaming() { - return telephonyCheckNetworkRoamingForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns true if the device is in roaming state " + - "for specified subscription ID") - public Boolean telephonyCheckNetworkRoamingForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.isNetworkRoaming(subId); - } - - @Rpc(description = "Returns the unique device ID such as MEID or IMEI " + - "for deault sim slot ID, null if unavailable") - public String telephonyGetDeviceId() { - return telephonyGetDeviceIdForSlotId(mTelephonyManager.getDefaultSim()); - } - - @Rpc(description = "Returns the unique device ID such as MEID or IMEI for" + - " specified slot ID, null if unavailable") - public String telephonyGetDeviceIdForSlotId( - @RpcParameter(name = "slotId") - Integer slotId){ - return mTelephonyManager.getDeviceId(slotId); - } - - @Rpc(description = "Returns the modem sw version, such as IMEI-SV;" + - " null if unavailable") - public String telephonyGetDeviceSoftwareVersion() { - return mTelephonyManager.getDeviceSoftwareVersion(); - } - - @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " + - "for default subscription ID; null if unavailable") - public String telephonyGetLine1Number() { - return mTelephonyManager.getLine1Number(); - } - - @Rpc(description = "Returns phone # string \"line 1\", such as MSISDN " + - "for specified subscription ID; null if unavailable") - public String telephonyGetLine1NumberForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getLine1Number(subId); - } - - @Rpc(description = "Returns the Alpha Tag for the default subscription " + - "ID; null if unavailable") - public String telephonyGetLine1AlphaTag() { - return mTelephonyManager.getLine1AlphaTag(); - } - - @Rpc(description = "Returns the Alpha Tag for the specified subscription " + - "ID; null if unavailable") - public String telephonyGetLine1AlphaTagForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getLine1AlphaTag(subId); - } - - @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" + - "for the default subscription") - public Boolean telephonySetLine1Number( - @RpcParameter(name = "number") String number, - @RpcOptional - @RpcParameter(name = "alphaTag") String alphaTag) { - return mTelephonyManager.setLine1NumberForDisplay(alphaTag, number); - } - - @Rpc(description = "Set the Line1-number (phone number) and Alpha Tag" + - "for the specified subscription") - public Boolean telephonySetLine1NumberForSubscription( - @RpcParameter(name = "subId") Integer subId, - @RpcParameter(name = "number") String number, - @RpcOptional - @RpcParameter(name = "alphaTag") String alphaTag) { - return mTelephonyManager.setLine1NumberForDisplay(subId, alphaTag, number); - } - - @Rpc(description = "Returns the neighboring cell information of the device.") - public List<NeighboringCellInfo> telephonyGetNeighboringCellInfo() { - return mTelephonyManager.getNeighboringCellInfo(); - } - - @Rpc(description = "Sets the minimum reporting interval for CellInfo" + - "0-as quickly as possible, 0x7FFFFFF-off") - public void telephonySetCellInfoListRate( - @RpcParameter(name = "rate") Integer rate - ) { - mTelephonyManager.setCellInfoListRate(rate); - } - - @Rpc(description = "Returns all observed cell information from all radios"+ - "on the device including the primary and neighboring cells") - public List<CellInfo> telephonyGetAllCellInfo() { - return mTelephonyManager.getAllCellInfo(); - } - - @Rpc(description = "Returns True if cellular data is enabled for" + - "default data subscription ID.") - public Boolean telephonyIsDataEnabled() { - return telephonyIsDataEnabledForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId()); - } - - @Rpc(description = "Returns True if data connection is enabled.") - public Boolean telephonyIsDataEnabledForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return mTelephonyManager.getDataEnabled(subId); - } - - @Rpc(description = "Toggles data connection on /off for" + - " default data subscription ID.") - public void telephonyToggleDataConnection( - @RpcParameter(name = "enabled") - @RpcOptional Boolean enabled) { - telephonyToggleDataConnectionForSubscription( - SubscriptionManager.getDefaultDataSubscriptionId(), enabled); - } - - @Rpc(description = "Toggles data connection on/off for" + - " specified subscription ID") - public void telephonyToggleDataConnectionForSubscription( - @RpcParameter(name = "subId") Integer subId, - @RpcParameter(name = "enabled") - @RpcOptional Boolean enabled) { - if (enabled == null) { - enabled = !telephonyIsDataEnabledForSubscription(subId); - } - mTelephonyManager.setDataEnabled(subId, enabled); - } - - @Rpc(description = "Sets an APN and make that as preferred APN.") - public void telephonySetAPN(@RpcParameter(name = "name") final String name, - @RpcParameter(name = "apn") final String apn, - @RpcParameter(name = "type") @RpcOptional @RpcDefault("") - final String type, - @RpcParameter(name = "subId") @RpcOptional Integer subId) { - //TODO: b/26273471 Need to find out how to set APN for specific subId - Uri uri; - Cursor cursor; - - String mcc = ""; - String mnc = ""; - - String numeric = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC); - // MCC is first 3 chars and then in 2 - 3 chars of MNC - if (numeric != null && numeric.length() > 4) { - // Country code - mcc = numeric.substring(0, 3); - // Network code - mnc = numeric.substring(3); - } - - uri = mService.getContentResolver().insert( - Telephony.Carriers.CONTENT_URI, new ContentValues()); - if (uri == null) { - Log.w("Failed to insert new provider into " + Telephony.Carriers.CONTENT_URI); - return; - } - - cursor = mService.getContentResolver().query(uri, sProjection, null, null, null); - cursor.moveToFirst(); - - ContentValues values = new ContentValues(); - - values.put(Telephony.Carriers.NAME, name); - values.put(Telephony.Carriers.APN, apn); - values.put(Telephony.Carriers.PROXY, ""); - values.put(Telephony.Carriers.PORT, ""); - values.put(Telephony.Carriers.MMSPROXY, ""); - values.put(Telephony.Carriers.MMSPORT, ""); - values.put(Telephony.Carriers.USER, ""); - values.put(Telephony.Carriers.SERVER, ""); - values.put(Telephony.Carriers.PASSWORD, ""); - values.put(Telephony.Carriers.MMSC, ""); - values.put(Telephony.Carriers.TYPE, type); - values.put(Telephony.Carriers.MCC, mcc); - values.put(Telephony.Carriers.MNC, mnc); - values.put(Telephony.Carriers.NUMERIC, mcc + mnc); - - int ret = mService.getContentResolver().update(uri, values, null, null); - Log.d("after update " + ret); - cursor.close(); - - // Make this APN as the preferred - String where = "name=\"" + name + "\""; - - Cursor c = mService.getContentResolver().query( - Telephony.Carriers.CONTENT_URI, - new String[] { - "_id", "name", "apn", "type" - }, where, null, - Telephony.Carriers.DEFAULT_SORT_ORDER); - if (c != null) { - c.moveToFirst(); - String key = c.getString(0); - final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn"; - ContentResolver resolver = mService.getContentResolver(); - ContentValues prefAPN = new ContentValues(); - prefAPN.put("apn_id", key); - resolver.update(Uri.parse(PREFERRED_APN_URI), prefAPN, null, null); - } - c.close(); - } - - @Rpc(description = "Returns the number of APNs defined") - public int telephonyGetNumberOfAPNs( - @RpcParameter(name = "subId") - @RpcOptional Integer subId) { - //TODO: b/26273471 Need to find out how to get Number of APNs for specific subId - int result = 0; - String where = "numeric=\"" + android.os.SystemProperties.get( - TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "") + "\""; - - Cursor cursor = mService.getContentResolver().query( - Telephony.Carriers.CONTENT_URI, - new String[] {"_id", "name", "apn", "type"}, where, null, - Telephony.Carriers.DEFAULT_SORT_ORDER); - - if (cursor != null) { - result = cursor.getCount(); - } - cursor.close(); - return result; - } - - @Rpc(description = "Returns the currently selected APN name") - public String telephonyGetSelectedAPN( - @RpcParameter(name = "subId") - @RpcOptional Integer subId) { - //TODO: b/26273471 Need to find out how to get selected APN for specific subId - String key = null; - int ID_INDEX = 0; - final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn"; - - Cursor cursor = mService.getContentResolver().query(Uri.parse(PREFERRED_APN_URI), - new String[] {"name"}, null, null, Telephony.Carriers.DEFAULT_SORT_ORDER); - - if (cursor.getCount() > 0) { - cursor.moveToFirst(); - key = cursor.getString(ID_INDEX); - } - cursor.close(); - return key; - } - - @Rpc(description = "Returns the current data connection state") - public String telephonyGetDataConnectionState() { - return TelephonyUtils.getDataConnectionStateString( - mTelephonyManager.getDataState()); - } - - @Rpc(description = "Enables or Disables Video Calling()") - public void telephonyEnableVideoCalling(boolean enable) { - mTelephonyManager.enableVideoCalling(enable); - } - - @Rpc(description = "Returns a boolean of whether or not " + - "video calling setting is enabled by the user") - public Boolean telephonyIsVideoCallingEnabled() { - return mTelephonyManager.isVideoCallingEnabled(); - } - - @Rpc(description = "Returns a boolean of whether video calling is available for use") - public Boolean telephonyIsVideoCallingAvailable() { - return mTelephonyManager.isVideoTelephonyAvailable(); - } - - @Rpc(description = "Returns a boolean of whether or not the device is ims registered") - public Boolean telephonyIsImsRegistered() { - return mTelephonyManager.isImsRegistered(); - } - - @Rpc(description = "Returns a boolean of whether or not volte calling is available for use") - public Boolean telephonyIsVolteAvailable() { - return mTelephonyManager.isVolteAvailable(); - } - - @Rpc(description = "Returns a boolean of whether or not wifi calling is available for use") - public Boolean telephonyIsWifiCallingAvailable() { - return mTelephonyManager.isWifiCallingAvailable(); - } - - @Rpc(description = "Returns the service state for default subscription ID") - public String telephonyGetServiceState() { - //TODO: b/26273807 need to have framework API to get service state. - return telephonyGetServiceStateForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the service state for specified subscription ID") - public String telephonyGetServiceStateForSubscription( - @RpcParameter(name = "subId") Integer subId) { - //TODO: b/26273807 need to have framework API to get service state. - return null; - } - - @Rpc(description = "Returns the call state for default subscription ID") - public String telephonyGetCallState() { - return telephonyGetCallStateForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns the call state for specified subscription ID") - public String telephonyGetCallStateForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return TelephonyUtils.getTelephonyCallStateString( - mTelephonyManager.getCallState(subId)); - } - - @Rpc(description = "Returns current signal strength for default subscription ID.") - public SignalStrength telephonyGetSignalStrength() { - return telephonyGetSignalStrengthForSubscription( - SubscriptionManager.getDefaultSubscriptionId()); - } - - @Rpc(description = "Returns current signal strength for specified subscription ID.") - public SignalStrength telephonyGetSignalStrengthForSubscription( - @RpcParameter(name = "subId") Integer subId) { - return StateChangeListeners.get(subId).mSignalStrengthChangeListener.mSignalStrengths; - } - - @Rpc(description = "Returns the sim count.") - public int telephonyGetSimCount() { - return mTelephonyManager.getSimCount(); - } - - private static class StateChangeListener { - private ServiceStateChangeListener mServiceStateChangeListener; - private SignalStrengthChangeListener mSignalStrengthChangeListener; - private CallStateChangeListener mCallStateChangeListener; - private CellInfoChangeListener mCellInfoChangeListener; - private DataConnectionStateChangeListener - mDataConnectionStateChangeListener; - private DataConnectionRealTimeInfoChangeListener - mDataConnectionRTInfoChangeListener; - private VoiceMailStateChangeListener - mVoiceMailStateChangeListener; - } - - @Override - public void shutdown() { - for (int i = 0; i < mSubInfos.size(); i++) { - int subId = mSubInfos.get(i).getSubscriptionId(); - telephonyStopTrackingCallStateChangeForSubscription(subId); - telephonyStopTrackingDataConnectionRTInfoChangeForSubscription(subId); - telephonyStopTrackingServiceStateChangeForSubscription(subId); - telephonyStopTrackingSignalStrengthChangeForSubscription(subId); - telephonyStopTrackingDataConnectionStateChangeForSubscription(subId); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java deleted file mode 100644 index cb9db74..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyStateListeners.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.telephony.TelephonyEvents; -import android.os.Bundle; -import android.telephony.CellInfo; -import android.telephony.DataConnectionRealTimeInfo; -import android.telephony.PhoneStateListener; -import android.telephony.PreciseCallState; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.SubscriptionManager; -import android.telephony.TelephonyManager; -import android.telephony.VoLteServiceState; - -import java.util.List; - -/** - * Store all subclasses of PhoneStateListener here. - */ -public class TelephonyStateListeners { - - public static class CallStateChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - public static final int sListeningStates = PhoneStateListener.LISTEN_CALL_STATE | - PhoneStateListener.LISTEN_PRECISE_CALL_STATE; - - public boolean listenForeground = true; - public boolean listenRinging = false; - public boolean listenBackground = false; - public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - - public CallStateChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - subscriptionId = SubscriptionManager.getDefaultVoiceSubscriptionId(); - } - - public CallStateChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - subscriptionId = subId; - } - - @Override - public void onCallStateChanged(int state, String incomingNumber) { - mEventFacade.postEvent(TelephonyConstants.EventCallStateChanged, - new TelephonyEvents.CallStateEvent( - state, incomingNumber, subscriptionId)); - } - - @Override - public void onPreciseCallStateChanged(PreciseCallState callState) { - int foregroundState = callState.getForegroundCallState(); - int ringingState = callState.getRingingCallState(); - int backgroundState = callState.getBackgroundCallState(); - if (listenForeground && - foregroundState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) { - processCallState(foregroundState, - TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND, - callState); - } - if (listenRinging && - ringingState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) { - processCallState(ringingState, - TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING, - callState); - } - if (listenBackground && - backgroundState != PreciseCallState.PRECISE_CALL_STATE_NOT_VALID) { - processCallState(backgroundState, - TelephonyConstants.PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND, - callState); - } - } - - private void processCallState( - int newState, String which, PreciseCallState callState) { - mEventFacade.postEvent(TelephonyConstants.EventPreciseStateChanged, - new TelephonyEvents.PreciseCallStateEvent( - newState, which, callState, subscriptionId)); - } - } - - public static class DataConnectionRealTimeInfoChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - public static final int sListeningStates = - PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO; - public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - - public DataConnectionRealTimeInfoChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); - } - - public DataConnectionRealTimeInfoChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - subscriptionId = subId; - } - - @Override - public void onDataConnectionRealTimeInfoChanged( - DataConnectionRealTimeInfo dcRtInfo) { - mEventFacade.postEvent( - TelephonyConstants.EventDataConnectionRealTimeInfoChanged, - new TelephonyEvents.DataConnectionRealTimeInfoEvent( - dcRtInfo, subscriptionId)); - } - } - - public static class DataConnectionStateChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - private final TelephonyManager mTelephonyManager; - public static final int sListeningStates = - PhoneStateListener.LISTEN_DATA_CONNECTION_STATE; - public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - - public DataConnectionStateChangeListener(EventFacade ef, TelephonyManager tm) { - super(); - mEventFacade = ef; - mTelephonyManager = tm; - subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); - } - - public DataConnectionStateChangeListener(EventFacade ef, TelephonyManager tm, int subId) { - super(subId); - mEventFacade = ef; - mTelephonyManager = tm; - subscriptionId = subId; - } - - @Override - public void onDataConnectionStateChanged(int state) { - mEventFacade.postEvent( - TelephonyConstants.EventDataConnectionStateChanged, - new TelephonyEvents.DataConnectionStateEvent(state, - TelephonyUtils.getNetworkTypeString( - mTelephonyManager.getDataNetworkType()), - subscriptionId)); - } - } - - public static class ServiceStateChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - public static final int sListeningStates = PhoneStateListener.LISTEN_SERVICE_STATE; - public int subscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; - - public ServiceStateChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - subscriptionId = SubscriptionManager.getDefaultDataSubscriptionId(); - } - - public ServiceStateChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - subscriptionId = subId; - } - - @Override - public void onServiceStateChanged(ServiceState serviceState) { - mEventFacade.postEvent(TelephonyConstants.EventServiceStateChanged, - new TelephonyEvents.ServiceStateEvent( - serviceState, subscriptionId)); - } - - } - - public static class CellInfoChangeListener - extends PhoneStateListener { - - private final EventFacade mEventFacade; - - public CellInfoChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - } - - public CellInfoChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - } - - @Override - public void onCellInfoChanged(List<CellInfo> cellInfo) { - mEventFacade.postEvent( - TelephonyConstants.EventCellInfoChanged, cellInfo); - } - } - - public static class VolteServiceStateChangeListener - extends PhoneStateListener { - - private final EventFacade mEventFacade; - - public VolteServiceStateChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - } - - public VolteServiceStateChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - } - - @Override - public void onVoLteServiceStateChanged(VoLteServiceState volteInfo) { - mEventFacade.postEvent( - TelephonyConstants.EventVolteServiceStateChanged, - volteInfo); - } - } - - public static class VoiceMailStateChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - - public static final int sListeningStates = - PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR; - - public VoiceMailStateChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - } - - public VoiceMailStateChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - } - - @Override - public void onMessageWaitingIndicatorChanged(boolean messageWaitingIndicator) { - mEventFacade.postEvent( - TelephonyConstants.EventMessageWaitingIndicatorChanged, - new TelephonyEvents.MessageWaitingIndicatorEvent( - messageWaitingIndicator)); - } - } - - - public static class SignalStrengthChangeListener extends PhoneStateListener { - - private final EventFacade mEventFacade; - public SignalStrength mSignalStrengths; - public static final int sListeningStates = PhoneStateListener.LISTEN_SIGNAL_STRENGTHS; - public SignalStrengthChangeListener(EventFacade ef) { - super(); - mEventFacade = ef; - } - - public SignalStrengthChangeListener(EventFacade ef, int subId) { - super(subId); - mEventFacade = ef; - } - - @Override - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - mSignalStrengths = signalStrength; - mEventFacade.postEvent( - TelephonyConstants.EventSignalStrengthChanged, signalStrength); - } - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java deleted file mode 100644 index 09e161f..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/telephony/TelephonyUtils.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.telephony; -import com.android.ims.ImsConfig; -import com.android.internal.telephony.RILConstants; -import com.googlecode.android_scripting.Log; -import android.telecom.TelecomManager; -import android.telephony.DataConnectionRealTimeInfo; -import android.telephony.PreciseCallState; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.telephony.VoLteServiceState; - -/** - * Telephony utility functions - */ -public class TelephonyUtils { - - public static String getWfcModeString(int mode) { - switch(mode) { - case ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED: - return TelephonyConstants.WFC_MODE_WIFI_PREFERRED; - case ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED: - return TelephonyConstants.WFC_MODE_CELLULAR_PREFERRED; - case ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY: - return TelephonyConstants.WFC_MODE_WIFI_ONLY; - } - Log.d("getWfcModeStringfromInt error. int: " + mode); - return TelephonyConstants.WFC_MODE_UNKNOWN; - } - - public static String getTtyModeString(int mode) { - switch (mode) { - case TelecomManager.TTY_MODE_FULL: - return TelephonyConstants.TTY_MODE_FULL; - case TelecomManager.TTY_MODE_HCO: - return TelephonyConstants.TTY_MODE_HCO; - case TelecomManager.TTY_MODE_OFF: - return TelephonyConstants.TTY_MODE_OFF; - case TelecomManager.TTY_MODE_VCO: - return TelephonyConstants.TTY_MODE_VCO; - } - Log.d("getTtyModeString error. int: " + mode); - return null; - } - - public static String getPhoneTypeString(int type) { - switch (type) { - case TelephonyManager.PHONE_TYPE_GSM: - return TelephonyConstants.PHONE_TYPE_GSM; - case TelephonyManager.PHONE_TYPE_NONE: - return TelephonyConstants.PHONE_TYPE_NONE; - case TelephonyManager.PHONE_TYPE_CDMA: - return TelephonyConstants.PHONE_TYPE_CDMA; - case TelephonyManager.PHONE_TYPE_SIP: - return TelephonyConstants.PHONE_TYPE_SIP; - } - Log.d("getPhoneTypeString error. int: " + type); - return null; - } - - public static String getSimStateString(int state) { - switch (state) { - case TelephonyManager.SIM_STATE_UNKNOWN: - return TelephonyConstants.SIM_STATE_UNKNOWN; - case TelephonyManager.SIM_STATE_ABSENT: - return TelephonyConstants.SIM_STATE_ABSENT; - case TelephonyManager.SIM_STATE_PIN_REQUIRED: - return TelephonyConstants.SIM_STATE_PIN_REQUIRED; - case TelephonyManager.SIM_STATE_PUK_REQUIRED: - return TelephonyConstants.SIM_STATE_PUK_REQUIRED; - case TelephonyManager.SIM_STATE_NETWORK_LOCKED: - return TelephonyConstants.SIM_STATE_NETWORK_LOCKED; - case TelephonyManager.SIM_STATE_READY: - return TelephonyConstants.SIM_STATE_READY; - case TelephonyManager.SIM_STATE_NOT_READY: - return TelephonyConstants.SIM_STATE_NOT_READY; - case TelephonyManager.SIM_STATE_PERM_DISABLED: - return TelephonyConstants.SIM_STATE_PERM_DISABLED; - case TelephonyManager.SIM_STATE_CARD_IO_ERROR: - return TelephonyConstants.SIM_STATE_CARD_IO_ERROR; - } - Log.d("getSimStateString error. int: " + state); - return TelephonyConstants.SIM_STATE_UNKNOWN; - } - - public static String formatIncomingNumber(String incomingNumber) { - String mIncomingNumber = null; - int len = 0; - if (incomingNumber != null) { - len = incomingNumber.length(); - } - if (len > 0) { - /** - * Currently this incomingNumber modification is specific for - * US numbers. - */ - if ((12 == len) && ('+' == incomingNumber.charAt(0))) { - mIncomingNumber = incomingNumber.substring(1); - } else if (10 == len) { - mIncomingNumber = '1' + incomingNumber; - } else { - mIncomingNumber = incomingNumber; - } - } - return mIncomingNumber; - } - - public static String getTelephonyCallStateString(int callState) { - switch (callState) { - case TelephonyManager.CALL_STATE_IDLE: - return TelephonyConstants.TELEPHONY_STATE_IDLE; - case TelephonyManager.CALL_STATE_OFFHOOK: - return TelephonyConstants.TELEPHONY_STATE_OFFHOOK; - case TelephonyManager.CALL_STATE_RINGING: - return TelephonyConstants.TELEPHONY_STATE_RINGING; - } - Log.d("getTelephonyCallStateString error. int: " + callState); - return TelephonyConstants.TELEPHONY_STATE_UNKNOWN; - } - - public static String getPreciseCallStateString(int state) { - switch (state) { - case PreciseCallState.PRECISE_CALL_STATE_ACTIVE: - return TelephonyConstants.PRECISE_CALL_STATE_ACTIVE; - case PreciseCallState.PRECISE_CALL_STATE_HOLDING: - return TelephonyConstants.PRECISE_CALL_STATE_HOLDING; - case PreciseCallState.PRECISE_CALL_STATE_DIALING: - return TelephonyConstants.PRECISE_CALL_STATE_DIALING; - case PreciseCallState.PRECISE_CALL_STATE_ALERTING: - return TelephonyConstants.PRECISE_CALL_STATE_ALERTING; - case PreciseCallState.PRECISE_CALL_STATE_INCOMING: - return TelephonyConstants.PRECISE_CALL_STATE_INCOMING; - case PreciseCallState.PRECISE_CALL_STATE_WAITING: - return TelephonyConstants.PRECISE_CALL_STATE_WAITING; - case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED: - return TelephonyConstants.PRECISE_CALL_STATE_DISCONNECTED; - case PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING: - return TelephonyConstants.PRECISE_CALL_STATE_DISCONNECTING; - case PreciseCallState.PRECISE_CALL_STATE_IDLE: - return TelephonyConstants.PRECISE_CALL_STATE_IDLE; - case PreciseCallState.PRECISE_CALL_STATE_NOT_VALID: - return TelephonyConstants.PRECISE_CALL_STATE_INVALID; - } - Log.d("getPreciseCallStateString error. int: " + state); - return TelephonyConstants.PRECISE_CALL_STATE_UNKNOWN; - } - - public static String getDcPowerStateString(int state) { - if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_LOW) { - return TelephonyConstants.DC_POWER_STATE_LOW; - } else if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH) { - return TelephonyConstants.DC_POWER_STATE_HIGH; - } else if (state == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) { - return TelephonyConstants.DC_POWER_STATE_MEDIUM; - } else { - return TelephonyConstants.DC_POWER_STATE_UNKNOWN; - } - } - - public static String getDataConnectionStateString(int state) { - switch (state) { - case TelephonyManager.DATA_DISCONNECTED: - return TelephonyConstants.DATA_STATE_DISCONNECTED; - case TelephonyManager.DATA_CONNECTING: - return TelephonyConstants.DATA_STATE_CONNECTING; - case TelephonyManager.DATA_CONNECTED: - return TelephonyConstants.DATA_STATE_CONNECTED; - case TelephonyManager.DATA_SUSPENDED: - return TelephonyConstants.DATA_STATE_SUSPENDED; - case TelephonyManager.DATA_UNKNOWN: - return TelephonyConstants.DATA_STATE_UNKNOWN; - } - Log.d("getDataConnectionStateString error. int: " + state); - return TelephonyConstants.DATA_STATE_UNKNOWN; - } - - public static int getNetworkModeIntfromString(String networkMode) { - switch (networkMode) { - case TelephonyConstants.NETWORK_MODE_WCDMA_PREF: - return RILConstants.NETWORK_MODE_WCDMA_PREF; - case TelephonyConstants.NETWORK_MODE_GSM_ONLY: - return RILConstants.NETWORK_MODE_GSM_ONLY; - case TelephonyConstants.NETWORK_MODE_WCDMA_ONLY: - return RILConstants.NETWORK_MODE_WCDMA_ONLY; - case TelephonyConstants.NETWORK_MODE_GSM_UMTS: - return RILConstants.NETWORK_MODE_GSM_UMTS; - case TelephonyConstants.NETWORK_MODE_CDMA: - return RILConstants.NETWORK_MODE_CDMA; - case TelephonyConstants.NETWORK_MODE_CDMA_NO_EVDO: - return RILConstants.NETWORK_MODE_CDMA_NO_EVDO; - case TelephonyConstants.NETWORK_MODE_EVDO_NO_CDMA: - return RILConstants.NETWORK_MODE_EVDO_NO_CDMA; - case TelephonyConstants.NETWORK_MODE_GLOBAL: - return RILConstants.NETWORK_MODE_GLOBAL; - case TelephonyConstants.NETWORK_MODE_LTE_CDMA_EVDO: - return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO; - case TelephonyConstants.NETWORK_MODE_LTE_GSM_WCDMA: - return RILConstants.NETWORK_MODE_LTE_GSM_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: - return RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_ONLY: - return RILConstants.NETWORK_MODE_LTE_ONLY; - case TelephonyConstants.NETWORK_MODE_LTE_WCDMA: - return RILConstants.NETWORK_MODE_LTE_WCDMA; - case TelephonyConstants.NETWORK_MODE_TDSCDMA_ONLY: - return RILConstants.NETWORK_MODE_TDSCDMA_ONLY; - case TelephonyConstants.NETWORK_MODE_TDSCDMA_WCDMA: - return RILConstants.NETWORK_MODE_TDSCDMA_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA: - return RILConstants.NETWORK_MODE_LTE_TDSCDMA; - case TelephonyConstants.NETWORK_MODE_TDSCDMA_GSM: - return RILConstants.NETWORK_MODE_TDSCDMA_GSM; - case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: - return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; - case TelephonyConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: - return RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: - return RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: - return RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; - case TelephonyConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - return RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - case TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - return RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - } - Log.d("getNetworkModeIntfromString error. String: " + networkMode); - return RILConstants.RIL_ERRNO_INVALID_RESPONSE; - } - - public static String getNetworkModeStringfromInt(int networkMode) { - switch (networkMode) { - case RILConstants.NETWORK_MODE_WCDMA_PREF: - return TelephonyConstants.NETWORK_MODE_WCDMA_PREF; - case RILConstants.NETWORK_MODE_GSM_ONLY: - return TelephonyConstants.NETWORK_MODE_GSM_ONLY; - case RILConstants.NETWORK_MODE_WCDMA_ONLY: - return TelephonyConstants.NETWORK_MODE_WCDMA_ONLY; - case RILConstants.NETWORK_MODE_GSM_UMTS: - return TelephonyConstants.NETWORK_MODE_GSM_UMTS; - case RILConstants.NETWORK_MODE_CDMA: - return TelephonyConstants.NETWORK_MODE_CDMA; - case RILConstants.NETWORK_MODE_CDMA_NO_EVDO: - return TelephonyConstants.NETWORK_MODE_CDMA_NO_EVDO; - case RILConstants.NETWORK_MODE_EVDO_NO_CDMA: - return TelephonyConstants.NETWORK_MODE_EVDO_NO_CDMA; - case RILConstants.NETWORK_MODE_GLOBAL: - return TelephonyConstants.NETWORK_MODE_GLOBAL; - case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO: - return TelephonyConstants.NETWORK_MODE_LTE_CDMA_EVDO; - case RILConstants.NETWORK_MODE_LTE_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_GSM_WCDMA; - case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA; - case RILConstants.NETWORK_MODE_LTE_ONLY: - return TelephonyConstants.NETWORK_MODE_LTE_ONLY; - case RILConstants.NETWORK_MODE_LTE_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_WCDMA; - case RILConstants.NETWORK_MODE_TDSCDMA_ONLY: - return TelephonyConstants.NETWORK_MODE_TDSCDMA_ONLY; - case RILConstants.NETWORK_MODE_TDSCDMA_WCDMA: - return TelephonyConstants.NETWORK_MODE_TDSCDMA_WCDMA; - case RILConstants.NETWORK_MODE_LTE_TDSCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA; - case RILConstants.NETWORK_MODE_TDSCDMA_GSM: - return TelephonyConstants.NETWORK_MODE_TDSCDMA_GSM; - case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM: - return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_GSM; - case RILConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_TDSCDMA_GSM_WCDMA; - case RILConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_WCDMA; - case RILConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA; - case RILConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - case RILConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA: - return TelephonyConstants.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA; - } - Log.d("getNetworkModeStringfromInt error. Int: " + networkMode); - return TelephonyConstants.NETWORK_MODE_INVALID; - } - - public static String getNetworkTypeString(int type) { - switch(type) { - case TelephonyManager.NETWORK_TYPE_GPRS: - return TelephonyConstants.RAT_GPRS; - case TelephonyManager.NETWORK_TYPE_EDGE: - return TelephonyConstants.RAT_EDGE; - case TelephonyManager.NETWORK_TYPE_UMTS: - return TelephonyConstants.RAT_UMTS; - case TelephonyManager.NETWORK_TYPE_HSDPA: - return TelephonyConstants.RAT_HSDPA; - case TelephonyManager.NETWORK_TYPE_HSUPA: - return TelephonyConstants.RAT_HSUPA; - case TelephonyManager.NETWORK_TYPE_HSPA: - return TelephonyConstants.RAT_HSPA; - case TelephonyManager.NETWORK_TYPE_CDMA: - return TelephonyConstants.RAT_CDMA; - case TelephonyManager.NETWORK_TYPE_1xRTT: - return TelephonyConstants.RAT_1XRTT; - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return TelephonyConstants.RAT_EVDO_0; - case TelephonyManager.NETWORK_TYPE_EVDO_A: - return TelephonyConstants.RAT_EVDO_A; - case TelephonyManager.NETWORK_TYPE_EVDO_B: - return TelephonyConstants.RAT_EVDO_B; - case TelephonyManager.NETWORK_TYPE_EHRPD: - return TelephonyConstants.RAT_EHRPD; - case TelephonyManager.NETWORK_TYPE_LTE: - return TelephonyConstants.RAT_LTE; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return TelephonyConstants.RAT_HSPAP; - case TelephonyManager.NETWORK_TYPE_GSM: - return TelephonyConstants.RAT_GSM; - case TelephonyManager. NETWORK_TYPE_TD_SCDMA: - return TelephonyConstants.RAT_TD_SCDMA; - case TelephonyManager.NETWORK_TYPE_IWLAN: - return TelephonyConstants.RAT_IWLAN; - case TelephonyManager.NETWORK_TYPE_IDEN: - return TelephonyConstants.RAT_IDEN; - } - return TelephonyConstants.RAT_UNKNOWN; - } - - public static String getNetworkStateString(int state) { - switch(state) { - case ServiceState.STATE_EMERGENCY_ONLY: - return TelephonyConstants.SERVICE_STATE_EMERGENCY_ONLY; - case ServiceState.STATE_IN_SERVICE: - return TelephonyConstants.SERVICE_STATE_IN_SERVICE; - case ServiceState.STATE_OUT_OF_SERVICE: - return TelephonyConstants.SERVICE_STATE_OUT_OF_SERVICE; - case ServiceState.STATE_POWER_OFF: - return TelephonyConstants.SERVICE_STATE_POWER_OFF; - default: - return TelephonyConstants.SERVICE_STATE_UNKNOWN; - } - } - - public static String getSrvccStateString(int srvccState) { - switch (srvccState) { - case VoLteServiceState.HANDOVER_STARTED: - return TelephonyConstants.VOLTE_SERVICE_STATE_HANDOVER_STARTED; - case VoLteServiceState.HANDOVER_COMPLETED: - return TelephonyConstants.VOLTE_SERVICE_STATE_HANDOVER_COMPLETED; - case VoLteServiceState.HANDOVER_FAILED: - return TelephonyConstants.VOLTE_SERVICE_STATE_HANDOVER_FAILED; - case VoLteServiceState.HANDOVER_CANCELED: - return TelephonyConstants.VOLTE_SERVICE_STATE_HANDOVER_CANCELED; - default: - Log.e(String.format("getSrvccStateString():" - + "unknown state %d", srvccState)); - return TelephonyConstants.VOLTE_SERVICE_STATE_HANDOVER_UNKNOWN; - } - }; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/AlertDialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/AlertDialogTask.java deleted file mode 100644 index 2a1e48e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/AlertDialogTask.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.content.DialogInterface; -import android.text.method.PasswordTransformationMethod; -import android.widget.EditText; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.json.JSONArray; -import org.json.JSONException; - -/** - * Wrapper class for alert dialog running in separate thread. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -class AlertDialogTask extends DialogTask { - - private final String mTitle; - private final String mMessage; - - private final List<String> mItems; - private final Set<Integer> mSelectedItems; - private final Map<String, Object> mResultMap; - private InputType mInputType; - private int mEditInputType = 0; - - private String mPositiveButtonText; - private String mNegativeButtonText; - private String mNeutralButtonText; - - private EditText mEditText; - private String mDefaultText; - - private enum InputType { - DEFAULT, MENU, SINGLE_CHOICE, MULTI_CHOICE, PLAIN_TEXT, PASSWORD; - } - - public AlertDialogTask(String title, String message) { - mTitle = title; - mMessage = message; - mInputType = InputType.DEFAULT; - mItems = new ArrayList<String>(); - mSelectedItems = new TreeSet<Integer>(); - mResultMap = new HashMap<String, Object>(); - } - - public void setPositiveButtonText(String text) { - mPositiveButtonText = text; - } - - public void setNegativeButtonText(String text) { - mNegativeButtonText = text; - } - - public void setNeutralButtonText(String text) { - mNeutralButtonText = text; - } - - /** - * Set list items. - * - * @param items - */ - public void setItems(JSONArray items) { - mItems.clear(); - for (int i = 0; i < items.length(); i++) { - try { - mItems.add(items.getString(i)); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - mInputType = InputType.MENU; - } - - /** - * Set single choice items. - * - * @param items - * a list of items as {@link String}s to display - * @param selected - * the index of the item that is selected by default - */ - public void setSingleChoiceItems(JSONArray items, int selected) { - setItems(items); - mSelectedItems.clear(); - mSelectedItems.add(selected); - mInputType = InputType.SINGLE_CHOICE; - } - - /** - * Set multi choice items. - * - * @param items - * a list of items as {@link String}s to display - * @param selected - * a list of indices for items that should be selected by default - * @throws JSONException - */ - public void setMultiChoiceItems(JSONArray items, JSONArray selected) throws JSONException { - setItems(items); - mSelectedItems.clear(); - if (selected != null) { - for (int i = 0; i < selected.length(); i++) { - mSelectedItems.add(selected.getInt(i)); - } - } - mInputType = InputType.MULTI_CHOICE; - } - - /** - * Returns the list of selected items. - */ - public Set<Integer> getSelectedItems() { - return mSelectedItems; - } - - public void setTextInput(String defaultText) { - mDefaultText = defaultText; - mInputType = InputType.PLAIN_TEXT; - setEditInputType("text"); - } - - public void setEditInputType(String editInputType) { - String[] list = editInputType.split("\\|"); - Map<String, Integer> types = ViewInflater.getInputTypes(); - mEditInputType = 0; - for (String flag : list) { - Integer v = types.get(flag.trim()); - if (v != null) { - mEditInputType |= v; - } - } - if (mEditInputType == 0) { - mEditInputType = android.text.InputType.TYPE_CLASS_TEXT; - } - } - - public void setPasswordInput() { - mInputType = InputType.PASSWORD; - } - - @Override - public void onCreate() { - super.onCreate(); - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - if (mTitle != null) { - builder.setTitle(mTitle); - } - // Can't display both a message and items. We'll elect to show the items instead. - if (mMessage != null && mItems.isEmpty()) { - builder.setMessage(mMessage); - } - switch (mInputType) { - // Add single choice menu items to dialog. - case SINGLE_CHOICE: - builder.setSingleChoiceItems(getItemsAsCharSequenceArray(), mSelectedItems.iterator().next(), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int item) { - mSelectedItems.clear(); - mSelectedItems.add(item); - } - }); - break; - // Add multiple choice items to the dialog. - case MULTI_CHOICE: - boolean[] selectedItems = new boolean[mItems.size()]; - for (int i : mSelectedItems) { - selectedItems[i] = true; - } - builder.setMultiChoiceItems(getItemsAsCharSequenceArray(), selectedItems, - new DialogInterface.OnMultiChoiceClickListener() { - @Override - public void onClick(DialogInterface dialog, int item, boolean isChecked) { - if (isChecked) { - mSelectedItems.add(item); - } else { - mSelectedItems.remove(item); - } - } - }); - break; - // Add standard, menu-like, items to dialog. - case MENU: - builder.setItems(getItemsAsCharSequenceArray(), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - Map<String, Integer> result = new HashMap<String, Integer>(); - result.put("item", item); - dismissDialog(); - setResult(result); - } - }); - break; - case PLAIN_TEXT: - mEditText = new EditText(getActivity()); - if (mDefaultText != null) { - mEditText.setText(mDefaultText); - } - mEditText.setInputType(mEditInputType); - builder.setView(mEditText); - break; - case PASSWORD: - mEditText = new EditText(getActivity()); - mEditText.setInputType(android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD); - mEditText.setTransformationMethod(new PasswordTransformationMethod()); - builder.setView(mEditText); - break; - default: - // No input type specified. - } - configureButtons(builder, getActivity()); - addOnCancelListener(builder, getActivity()); - mDialog = builder.show(); - mShowLatch.countDown(); - } - - private CharSequence[] getItemsAsCharSequenceArray() { - return mItems.toArray(new CharSequence[mItems.size()]); - } - - private Builder addOnCancelListener(final AlertDialog.Builder builder, final Activity activity) { - return builder.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - mResultMap.put("canceled", true); - setResult(); - } - }); - } - - private void configureButtons(final AlertDialog.Builder builder, final Activity activity) { - DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - mResultMap.put("which", "positive"); - break; - case DialogInterface.BUTTON_NEGATIVE: - mResultMap.put("which", "negative"); - break; - case DialogInterface.BUTTON_NEUTRAL: - mResultMap.put("which", "neutral"); - - break; - } - setResult(); - } - }; - if (mNegativeButtonText != null) { - builder.setNegativeButton(mNegativeButtonText, buttonListener); - } - if (mPositiveButtonText != null) { - builder.setPositiveButton(mPositiveButtonText, buttonListener); - } - if (mNeutralButtonText != null) { - builder.setNeutralButton(mNeutralButtonText, buttonListener); - } - } - - private void setResult() { - dismissDialog(); - if (mInputType == InputType.PLAIN_TEXT || mInputType == InputType.PASSWORD) { - mResultMap.put("value", mEditText.getText().toString()); - } - setResult(mResultMap); - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DatePickerDialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DatePickerDialogTask.java deleted file mode 100644 index e80bd25..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DatePickerDialogTask.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.DatePickerDialog; -import android.content.DialogInterface; -import android.util.AndroidRuntimeException; -import android.widget.DatePicker; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Wrapper class for date picker dialog running in separate thread. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -public class DatePickerDialogTask extends DialogTask { - public static int mYear; - public static int mMonth; - public static int mDay; - - public DatePickerDialogTask(int year, int month, int day) { - mYear = year; - mMonth = month - 1; - mDay = day; - } - - @Override - public void onCreate() { - super.onCreate(); - mDialog = new DatePickerDialog(getActivity(), new DatePickerDialog.OnDateSetListener() { - @Override - public void onDateSet(DatePicker view, int year, int month, int day) { - JSONObject result = new JSONObject(); - try { - result.put("which", "positive"); - result.put("year", year); - result.put("month", month + 1); - result.put("day", day); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }, mYear, mMonth, mDay); - mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface view) { - JSONObject result = new JSONObject(); - try { - result.put("which", "neutral"); - result.put("year", mYear); - result.put("month", mMonth + 1); - result.put("day", mDay); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }); - mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - JSONObject result = new JSONObject(); - try { - result.put("which", "negative"); - result.put("year", mYear); - result.put("month", mMonth + 1); - result.put("day", mDay); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }); - mDialog.show(); - mShowLatch.countDown(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DialogTask.java deleted file mode 100644 index ba48fcb..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/DialogTask.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.Dialog; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.future.FutureActivityTask; - -import java.util.concurrent.CountDownLatch; - -abstract class DialogTask extends FutureActivityTask<Object> { - - protected Dialog mDialog; - private EventFacade mEventFacade; - - public EventFacade getEventFacade() { - return mEventFacade; - } - - public void setEventFacade(EventFacade mEventFacade) { - this.mEventFacade = mEventFacade; - } - - @Override - protected void setResult(Object object) { - super.setResult(object); - EventFacade eventFacade = getEventFacade(); - if (eventFacade != null) { - eventFacade.postEvent("dialog", object); - } - } - - protected final CountDownLatch mShowLatch = new CountDownLatch(1); - - /** - * Returns the wrapped {@link Dialog}. - */ - public Dialog getDialog() { - return mDialog; - } - - /** - * Dismiss the {@link Dialog} and close {@link Sl4aActivity}. - */ - public void dismissDialog() { - if (mDialog != null) { - mDialog.dismiss(); - finish(); - } - mDialog = null; - } - - /** - * Returns the {@link CountDownLatch} that is counted down when the dialog is shown. - */ - public CountDownLatch getShowLatch() { - return mShowLatch; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/FullScreenTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/FullScreenTask.java deleted file mode 100644 index a97d51d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/FullScreenTask.java +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.R; -import android.os.Handler; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup.LayoutParams; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.future.FutureActivityTask; - -import java.io.StringReader; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; - -import org.json.JSONArray; -import org.xmlpull.v1.XmlPullParser; - -public class FullScreenTask extends FutureActivityTask<Object> implements OnClickListener, - OnItemClickListener { - private EventFacade mEventFacade; - private UiFacade mUiFacade; - public View mView = null; - protected ViewInflater mInflater = new ViewInflater(); - protected String mLayout; - protected final CountDownLatch mShowLatch = new CountDownLatch(1); - protected Handler mHandler = null; - private List<Integer> mOverrideKeys; - protected String mTitle; - - public FullScreenTask(String layout, String title) { - super(); - mLayout = layout; - if (title != null) { - mTitle = title; - } else { - mTitle = "SL4a"; - } - } - - @Override - public void onCreate() { - // super.onCreate(); - if (mHandler == null) { - mHandler = new Handler(); - } - mInflater.getErrors().clear(); - try { - if (mView == null) { - StringReader sr = new StringReader(mLayout); - XmlPullParser xml = ViewInflater.getXml(sr); - mView = mInflater.inflate(getActivity(), xml); - } - } catch (Exception e) { - mInflater.getErrors().add(e.toString()); - mView = defaultView(); - mInflater.setIdList(R.id.class); - } - getActivity().setContentView(mView); - getActivity().setTitle(mTitle); - mInflater.setClickListener(mView, this, this); - mShowLatch.countDown(); - } - - @Override - public void onDestroy() { - mEventFacade.postEvent("screen", "destroy"); - super.onDestroy(); - } - - /** default view in case of errors */ - protected View defaultView() { - LinearLayout result = new LinearLayout(getActivity()); - result.setOrientation(LinearLayout.VERTICAL); - TextView text = new TextView(getActivity()); - text.setText("Sample Layout"); - result.addView(text, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - Button b = new Button(getActivity()); - b.setText("OK"); - result.addView(b, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - return result; - } - - public EventFacade getEventFacade() { - return mEventFacade; - } - - public void setEventFacade(EventFacade eventFacade) { - mEventFacade = eventFacade; - } - - public void setUiFacade(UiFacade uiFacade) { - mUiFacade = uiFacade; - } - - public CountDownLatch getShowLatch() { - return mShowLatch; - } - - public Map<String, Map<String, String>> getViewAsMap() { - return mInflater.getViewAsMap(mView); - } - - private View getViewByName(String idName) { - View result = null; - int id = mInflater.getId(idName); - if (id != 0) { - result = mView.findViewById(id); - } - return result; - } - - public Map<String, String> getViewDetail(String idName) { - Map<String, String> result = new HashMap<String, String>(); - result.put("error", "id not found (" + idName + ")"); - View v = getViewByName(idName); - if (v != null) { - result = mInflater.getViewInfo(v); - } - return result; - } - - public String setViewProperty(String idName, String property, String value) { - View v = getViewByName(idName); - mInflater.getErrors().clear(); - if (v != null) { - SetProperty p = new SetProperty(v, property, value); - mHandler.post(p); - try { - p.mLatch.await(); - } catch (InterruptedException e) { - mInflater.getErrors().add(e.toString()); - } - } else { - return "View " + idName + " not found."; - } - if (mInflater.getErrors().size() == 0) { - return "OK"; - } - return mInflater.getErrors().get(0); - } - - public String setList(String id, JSONArray items) { - View v = getViewByName(id); - mInflater.getErrors().clear(); - if (v != null) { - SetList p = new SetList(v, items); - mHandler.post(p); - try { - p.mLatch.await(); - } catch (InterruptedException e) { - mInflater.getErrors().add(e.toString()); - } - } else { - return "View " + id + " not found."; - } - if (mInflater.getErrors().size() == 0) { - return "OK"; - } - return mInflater.getErrors().get(0); - } - - @Override - public void onClick(View view) { - mEventFacade.postEvent("click", mInflater.getViewInfo(view)); - } - - public void loadLayout(String layout) { - ViewInflater inflater = new ViewInflater(); - View view; - StringReader sr = new StringReader(layout); - try { - XmlPullParser xml = ViewInflater.getXml(sr); - view = inflater.inflate(getActivity(), xml); - mView = view; - mInflater = inflater; - getActivity().setContentView(mView); - mInflater.setClickListener(mView, this, this); - mLayout = layout; - mView.invalidate(); - } catch (Exception e) { - mInflater.getErrors().add(e.toString()); - } - } - - private class SetProperty implements Runnable { - View mView; - String mProperty; - String mValue; - CountDownLatch mLatch = new CountDownLatch(1); - - SetProperty(View view, String property, String value) { - mView = view; - mProperty = property; - mValue = value; - } - - @Override - public void run() { - // TODO Auto-generated method stub - mInflater.setProperty(mView, mProperty, mValue); - mView.invalidate(); - mLatch.countDown(); - } - } - - private class SetList implements Runnable { - View mView; - JSONArray mItems; - CountDownLatch mLatch = new CountDownLatch(1); - - SetList(View view, JSONArray items) { - mView = view; - mItems = items; - mLatch.countDown(); - } - - @Override - public void run() { - mInflater.setListAdapter(mView, mItems); - mView.invalidate(); - } - } - - private class SetLayout implements Runnable { - String mLayout; - CountDownLatch mLatch = new CountDownLatch(1); - - SetLayout(String layout) { - mLayout = layout; - } - - @Override - public void run() { - loadLayout(mLayout); - mLatch.countDown(); - } - } - - private class SetTitle implements Runnable { - String mSetTitle; - CountDownLatch mLatch = new CountDownLatch(1); - - SetTitle(String title) { - mSetTitle = title; - } - - @Override - public void run() { - mTitle = mSetTitle; - getActivity().setTitle(mSetTitle); - mLatch.countDown(); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - Map<String, String> data = new HashMap<String, String>(); - data.put("key", String.valueOf(keyCode)); - data.put("action", String.valueOf(event.getAction())); - mEventFacade.postEvent("key", data); - boolean overrideKey = - (keyCode == KeyEvent.KEYCODE_BACK) - || (mOverrideKeys == null ? false : mOverrideKeys.contains(keyCode)); - return overrideKey; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - return mUiFacade.onPrepareOptionsMenu(menu); - } - - @Override - public void onItemClick(AdapterView<?> aview, View aitem, int position, long id) { - Map<String, String> data = mInflater.getViewInfo(aview); - data.put("position", String.valueOf(position)); - mEventFacade.postEvent("itemclick", data); - } - - public void setOverrideKeys(List<Integer> overrideKeys) { - mOverrideKeys = overrideKeys; - } - - // Used to hot-switch screens. - public void setLayout(String layout) { - SetLayout p = new SetLayout(layout); - mHandler.post(p); - try { - p.mLatch.await(); - } catch (InterruptedException e) { - mInflater.getErrors().add(e.toString()); - } - } - - public void setTitle(String title) { - SetTitle p = new SetTitle(title); - mHandler.post(p); - try { - p.mLatch.await(); - } catch (InterruptedException e) { - mInflater.getErrors().add(e.toString()); - } - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ProgressDialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ProgressDialogTask.java deleted file mode 100644 index 2d9aabf..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ProgressDialogTask.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.ProgressDialog; - -/** - * Wrapper class for progress dialog running in separate thread - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -class ProgressDialogTask extends DialogTask { - - private final int mStyle; - private final int mMax; - private final String mTitle; - private final String mMessage; - private final Boolean mCancelable; - - public ProgressDialogTask(int style, int max, String title, String message, boolean cancelable) { - mStyle = style; - mMax = max; - mTitle = title; - mMessage = message; - mCancelable = cancelable; - } - - @Override - public void onCreate() { - super.onCreate(); - mDialog = new ProgressDialog(getActivity()); - ((ProgressDialog) mDialog).setProgressStyle(mStyle); - ((ProgressDialog) mDialog).setMax(mMax); - mDialog.setCancelable(mCancelable); - mDialog.setTitle(mTitle); - ((ProgressDialog) mDialog).setMessage(mMessage); - mDialog.show(); - mShowLatch.countDown(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/SeekBarDialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/SeekBarDialogTask.java deleted file mode 100644 index 3930972..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/SeekBarDialogTask.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.AlertDialog.Builder; -import android.content.DialogInterface; -import android.util.AndroidRuntimeException; -import android.widget.SeekBar; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Wrapper class for dialog box with seek bar. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -public class SeekBarDialogTask extends DialogTask { - - private SeekBar mSeekBar; - private final int mProgress; - private final int mMax; - private final String mTitle; - private final String mMessage; - private String mPositiveButtonText; - private String mNegativeButtonText; - - public SeekBarDialogTask(int progress, int max, String title, String message) { - mProgress = progress; - mMax = max; - mTitle = title; - mMessage = message; - } - - public void setPositiveButtonText(String text) { - mPositiveButtonText = text; - } - - public void setNegativeButtonText(String text) { - mNegativeButtonText = text; - } - - @Override - public void onCreate() { - super.onCreate(); - mSeekBar = new SeekBar(getActivity()); - mSeekBar.setMax(mMax); - mSeekBar.setProgress(mProgress); - mSeekBar.setPadding(10, 0, 10, 3); - mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - - @Override - public void onStopTrackingTouch(SeekBar arg0) { - } - - @Override - public void onStartTrackingTouch(SeekBar arg0) { - } - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - EventFacade eventFacade = getEventFacade(); - if (eventFacade != null) { - JSONObject result = new JSONObject(); - try { - result.put("which", "seekbar"); - result.put("progress", mSeekBar.getProgress()); - result.put("fromuser", fromUser); - eventFacade.postEvent("dialog", result); - } catch (JSONException e) { - Log.e(e); - } - } - } - }); - - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - if (mTitle != null) { - builder.setTitle(mTitle); - } - if (mMessage != null) { - builder.setMessage(mMessage); - } - builder.setView(mSeekBar); - configureButtons(builder, getActivity()); - addOnCancelListener(builder, getActivity()); - mDialog = builder.show(); - mShowLatch.countDown(); - } - - private Builder addOnCancelListener(final AlertDialog.Builder builder, final Activity activity) { - return builder.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - JSONObject result = new JSONObject(); - try { - result.put("canceled", true); - result.put("progress", mSeekBar.getProgress()); - } catch (JSONException e) { - Log.e(e); - } - dismissDialog(); - setResult(result); - } - }); - } - - private void configureButtons(final AlertDialog.Builder builder, final Activity activity) { - DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - JSONObject result = new JSONObject(); - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - try { - result.put("which", "positive"); - result.put("progress", mSeekBar.getProgress()); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - break; - case DialogInterface.BUTTON_NEGATIVE: - try { - result.put("which", "negative"); - result.put("progress", mSeekBar.getProgress()); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - break; - } - dismissDialog(); - setResult(result); - } - }; - if (mNegativeButtonText != null) { - builder.setNegativeButton(mNegativeButtonText, buttonListener); - } - if (mPositiveButtonText != null) { - builder.setPositiveButton(mPositiveButtonText, buttonListener); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/TimePickerDialogTask.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/TimePickerDialogTask.java deleted file mode 100644 index ad71cd3..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/TimePickerDialogTask.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.TimePickerDialog; -import android.content.DialogInterface; -import android.util.AndroidRuntimeException; -import android.widget.TimePicker; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Wrapper class for time picker dialog running in separate thread. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -public class TimePickerDialogTask extends DialogTask { - private final int mHour; - private final int mMinute; - private final boolean mIs24Hour; - - public TimePickerDialogTask(int hour, int minute, boolean is24hour) { - mHour = hour; - mMinute = minute; - mIs24Hour = is24hour; - } - - @Override - public void onCreate() { - super.onCreate(); - mDialog = new TimePickerDialog(getActivity(), new TimePickerDialog.OnTimeSetListener() { - @Override - public void onTimeSet(TimePicker view, int hour, int minute) { - JSONObject result = new JSONObject(); - try { - result.put("which", "positive"); - result.put("hour", hour); - result.put("minute", minute); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }, mHour, mMinute, mIs24Hour); - mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface view) { - JSONObject result = new JSONObject(); - try { - result.put("which", "neutral"); - result.put("hour", mHour); - result.put("minute", mMinute); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }); - mDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - JSONObject result = new JSONObject(); - try { - result.put("which", "negative"); - result.put("hour", mHour); - result.put("minute", mMinute); - setResult(result); - } catch (JSONException e) { - throw new AndroidRuntimeException(e); - } - } - }); - mDialog.show(); - mShowLatch.countDown(); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/UiFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/UiFacade.java deleted file mode 100644 index 7eb4e02..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/UiFacade.java +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.ProgressDialog; -import android.app.Service; -import android.util.AndroidRuntimeException; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.json.JSONArray; -import org.json.JSONException; - -/** - * User Interface Facade. <br> - * <br> - * <b>Usage Notes</b><br> - * <br> - * The UI facade provides access to a selection of dialog boxes for general user interaction, and - * also hosts the {@link #webViewShow} call which allows interactive use of html pages.<br> - * The general use of the dialog functions is as follows:<br> - * <ol> - * <li>Create a dialog using one of the following calls: - * <ul> - * <li>{@link #dialogCreateInput} - * <li>{@link #dialogCreateAlert} - * <li>{@link #dialogCreateDatePicker} - * <li>{@link #dialogCreateHorizontalProgress} - * <li>{@link #dialogCreatePassword} - * <li>{@link #dialogCreateSeekBar} - * <li>{@link #dialogCreateSpinnerProgress} - * </ul> - * <li>Set additional features to your dialog - * <ul> - * <li>{@link #dialogSetItems} Set a list of items. Used like a menu. - * <li>{@link #dialogSetMultiChoiceItems} Set a multichoice list of items. - * <li>{@link #dialogSetSingleChoiceItems} Set a single choice list of items. - * <li>{@link #dialogSetPositiveButtonText} - * <li>{@link #dialogSetNeutralButtonText} - * <li>{@link #dialogSetNegativeButtonText} - * <li>{@link #dialogSetMaxProgress} Set max progress for your progress bar. - * </ul> - * <li>Display the dialog using {@link #dialogShow} - * <li>Update dialog information if needed - * <ul> - * <li>{@link #dialogSetCurrentProgress} - * </ul> - * <li>Get the results - * <ul> - * <li>Using {@link #dialogGetResponse}, which will wait until the user performs an action to close - * the dialog box, or - * <li>Use eventPoll to wait for a "dialog" event. - * <li>You can find out which list items were selected using {@link #dialogGetSelectedItems}, which - * returns an array of numeric indices to your list. For a single choice list, there will only ever - * be one of these. - * </ul> - * <li>Once done, use {@link #dialogDismiss} to remove the dialog. - * </ol> - * <br> - * You can also manipulate menu options. The menu options are available for both {@link #dialogShow} - * and {@link #fullShow}. - * <ul> - * <li>{@link #clearOptionsMenu} - * <li>{@link #addOptionsMenuItem} - * </ul> - * <br> - * <b>Some notes:</b><br> - * Not every dialogSet function is relevant to every dialog type, ie, dialogSetMaxProgress obviously - * only applies to dialogs created with a progress bar. Also, an Alert Dialog may have a message or - * items, not both. If you set both, items will take priority.<br> - * In addition to the above functions, {@link #dialogGetInput} and {@link #dialogGetPassword} are - * convenience functions that create, display and return the relevant dialogs in one call.<br> - * There is only ever one instance of a dialog. Any dialogCreate call will cause the existing dialog - * to be destroyed. - * - * @author MeanEYE.rcf (meaneye.rcf@gmail.com) - */ -public class UiFacade extends RpcReceiver { - // This value should not be used for menu groups outside this class. - private static final int MENU_GROUP_ID = Integer.MAX_VALUE; - private static final String blankLayout = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" - + "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"" - + "android:id=\"@+id/background\" android:orientation=\"vertical\"" - + "android:layout_width=\"match_parent\" android:layout_height=\"match_parent\"" - + "android:background=\"#ff000000\"></LinearLayout>"; - - private final Service mService; - private final FutureActivityTaskExecutor mTaskQueue; - private DialogTask mDialogTask; - private FullScreenTask mFullScreenTask; - - private final List<UiMenuItem> mContextMenuItems; - private final List<UiMenuItem> mOptionsMenuItems; - private final AtomicBoolean mMenuUpdated; - - private final EventFacade mEventFacade; - private List<Integer> mOverrideKeys = Collections.synchronizedList(new ArrayList<Integer>()); - - private float mLastXPosition; - - public UiFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mTaskQueue = ((BaseApplication) mService.getApplication()).getTaskExecutor(); - mContextMenuItems = new CopyOnWriteArrayList<UiMenuItem>(); - mOptionsMenuItems = new CopyOnWriteArrayList<UiMenuItem>(); - mEventFacade = manager.getReceiver(EventFacade.class); - mMenuUpdated = new AtomicBoolean(false); - } - - /** - * For inputType, see <a - * href="http://developer.android.com/reference/android/R.styleable.html#TextView_inputType" - * >InputTypes</a>. Some useful ones are text, number, and textUri. Multiple flags can be - * supplied, seperated by "|", ie: "textUri|textAutoComplete" - */ - @Rpc(description = "Create a text input dialog.") - public void dialogCreateInput( - @RpcParameter(name = "title", description = "title of the input box") @RpcDefault("Value") final String title, - @RpcParameter(name = "message", description = "message to display above the input box") @RpcDefault("Please enter value:") final String message, - @RpcParameter(name = "defaultText", description = "text to insert into the input box") @RpcOptional final String text, - @RpcParameter(name = "inputType", description = "type of input data, ie number or text") @RpcOptional final String inputType) - throws InterruptedException { - dialogDismiss(); - mDialogTask = new AlertDialogTask(title, message); - ((AlertDialogTask) mDialogTask).setTextInput(text); - if (inputType != null) { - ((AlertDialogTask) mDialogTask).setEditInputType(inputType); - } - } - - @Rpc(description = "Create a password input dialog.") - public void dialogCreatePassword( - @RpcParameter(name = "title", description = "title of the input box") @RpcDefault("Password") final String title, - @RpcParameter(name = "message", description = "message to display above the input box") @RpcDefault("Please enter password:") final String message) { - dialogDismiss(); - mDialogTask = new AlertDialogTask(title, message); - ((AlertDialogTask) mDialogTask).setPasswordInput(); - } - - /** - * The result is the user's input, or None (null) if cancel was hit. <br> - * Example (python) - * - * <pre> - * import android - * droid=android.Android() - * - * print droid.dialogGetInput("Title","Message","Default").result - * </pre> - * - */ - @SuppressWarnings("unchecked") - @Rpc(description = "Queries the user for a text input.") - public String dialogGetInput( - @RpcParameter(name = "title", description = "title of the input box") @RpcDefault("Value") final String title, - @RpcParameter(name = "message", description = "message to display above the input box") @RpcDefault("Please enter value:") final String message, - @RpcParameter(name = "defaultText", description = "text to insert into the input box") @RpcOptional final String text) - throws InterruptedException { - dialogCreateInput(title, message, text, "text"); - dialogSetNegativeButtonText("Cancel"); - dialogSetPositiveButtonText("Ok"); - dialogShow(); - Map<String, Object> response = (Map<String, Object>) dialogGetResponse(); - if ("positive".equals(response.get("which"))) { - return (String) response.get("value"); - } else { - return null; - } - } - - @SuppressWarnings("unchecked") - @Rpc(description = "Queries the user for a password.") - public String dialogGetPassword( - @RpcParameter(name = "title", description = "title of the password box") @RpcDefault("Password") final String title, - @RpcParameter(name = "message", description = "message to display above the input box") @RpcDefault("Please enter password:") final String message) - throws InterruptedException { - dialogCreatePassword(title, message); - dialogSetNegativeButtonText("Cancel"); - dialogSetPositiveButtonText("Ok"); - dialogShow(); - Map<String, Object> response = (Map<String, Object>) dialogGetResponse(); - if ("positive".equals(response.get("which"))) { - return (String) response.get("value"); - } else { - return null; - } - } - - @Rpc(description = "Create a spinner progress dialog.") - public void dialogCreateSpinnerProgress(@RpcParameter(name = "title") @RpcOptional String title, - @RpcParameter(name = "message") @RpcOptional String message, - @RpcParameter(name = "maximum progress") @RpcDefault("100") Integer max) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = new ProgressDialogTask(ProgressDialog.STYLE_SPINNER, max, title, message, true); - } - - @Rpc(description = "Create a horizontal progress dialog.") - public void dialogCreateHorizontalProgress( - @RpcParameter(name = "title") @RpcOptional String title, - @RpcParameter(name = "message") @RpcOptional String message, - @RpcParameter(name = "maximum progress") @RpcDefault("100") Integer max) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = - new ProgressDialogTask(ProgressDialog.STYLE_HORIZONTAL, max, title, message, true); - } - - /** - * <b>Example (python)</b> - * - * <pre> - * import android - * droid=android.Android() - * droid.dialogCreateAlert("I like swords.","Do you like swords?") - * droid.dialogSetPositiveButtonText("Yes") - * droid.dialogSetNegativeButtonText("No") - * droid.dialogShow() - * response=droid.dialogGetResponse().result - * droid.dialogDismiss() - * if response.has_key("which"): - * result=response["which"] - * if result=="positive": - * print "Yay! I like swords too!" - * elif result=="negative": - * print "Oh. How sad." - * elif response.has_key("canceled"): # Yes, I know it's mispelled. - * print "You can't even make up your mind?" - * else: - * print "Unknown response=",response - * - * print "Done" - * </pre> - */ - @Rpc(description = "Create alert dialog.") - public void dialogCreateAlert(@RpcParameter(name = "title") @RpcOptional String title, - @RpcParameter(name = "message") @RpcOptional String message) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = new AlertDialogTask(title, message); - } - - /** - * Will produce "dialog" events on change, containing: - * <ul> - * <li>"progress" - Position chosen, between 0 and max - * <li>"which" = "seekbar" - * <li>"fromuser" = true/false change is from user input - * </ul> - * Response will contain a "progress" element. - */ - @Rpc(description = "Create seek bar dialog.") - public void dialogCreateSeekBar( - @RpcParameter(name = "starting value") @RpcDefault("50") Integer progress, - @RpcParameter(name = "maximum value") @RpcDefault("100") Integer max, - @RpcParameter(name = "title") String title, @RpcParameter(name = "message") String message) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = new SeekBarDialogTask(progress, max, title, message); - } - - @Rpc(description = "Create time picker dialog.") - public void dialogCreateTimePicker( - @RpcParameter(name = "hour") @RpcDefault("0") Integer hour, - @RpcParameter(name = "minute") @RpcDefault("0") Integer minute, - @RpcParameter(name = "is24hour", description = "Use 24 hour clock") @RpcDefault("false") Boolean is24hour) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = new TimePickerDialogTask(hour, minute, is24hour); - } - - @Rpc(description = "Create date picker dialog.") - public void dialogCreateDatePicker(@RpcParameter(name = "year") @RpcDefault("1970") Integer year, - @RpcParameter(name = "month") @RpcDefault("1") Integer month, - @RpcParameter(name = "day") @RpcDefault("1") Integer day) { - dialogDismiss(); // Dismiss any existing dialog. - mDialogTask = new DatePickerDialogTask(year, month, day); - } - - @Rpc(description = "Dismiss dialog.") - public void dialogDismiss() { - if (mDialogTask != null) { - mDialogTask.dismissDialog(); - mDialogTask = null; - } - } - - @Rpc(description = "Show dialog.") - public void dialogShow() throws InterruptedException { - if (mDialogTask != null && mDialogTask.getDialog() == null) { - mDialogTask.setEventFacade(mEventFacade); - mTaskQueue.execute(mDialogTask); - mDialogTask.getShowLatch().await(); - } else { - throw new RuntimeException("No dialog to show."); - } - } - - @Rpc(description = "Set progress dialog current value.") - public void dialogSetCurrentProgress(@RpcParameter(name = "current") Integer current) { - if (mDialogTask != null && mDialogTask instanceof ProgressDialogTask) { - ((ProgressDialog) mDialogTask.getDialog()).setProgress(current); - } else { - throw new RuntimeException("No valid dialog to assign value to."); - } - } - - @Rpc(description = "Set progress dialog maximum value.") - public void dialogSetMaxProgress(@RpcParameter(name = "max") Integer max) { - if (mDialogTask != null && mDialogTask instanceof ProgressDialogTask) { - ((ProgressDialog) mDialogTask.getDialog()).setMax(max); - } else { - throw new RuntimeException("No valid dialog to set maximum value of."); - } - } - - @Rpc(description = "Set alert dialog positive button text.") - public void dialogSetPositiveButtonText(@RpcParameter(name = "text") String text) { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setPositiveButtonText(text); - } else if (mDialogTask != null && mDialogTask instanceof SeekBarDialogTask) { - ((SeekBarDialogTask) mDialogTask).setPositiveButtonText(text); - } else { - throw new AndroidRuntimeException("No dialog to add button to."); - } - } - - @Rpc(description = "Set alert dialog button text.") - public void dialogSetNegativeButtonText(@RpcParameter(name = "text") String text) { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setNegativeButtonText(text); - } else if (mDialogTask != null && mDialogTask instanceof SeekBarDialogTask) { - ((SeekBarDialogTask) mDialogTask).setNegativeButtonText(text); - } else { - throw new AndroidRuntimeException("No dialog to add button to."); - } - } - - @Rpc(description = "Set alert dialog button text.") - public void dialogSetNeutralButtonText(@RpcParameter(name = "text") String text) { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setNeutralButtonText(text); - } else { - throw new AndroidRuntimeException("No dialog to add button to."); - } - } - - // TODO(damonkohler): Make RPC layer translate between JSONArray and List<Object>. - /** - * This effectively creates list of options. Clicking on an item will immediately return an "item" - * element, which is the index of the selected item. - */ - @Rpc(description = "Set alert dialog list items.") - public void dialogSetItems(@RpcParameter(name = "items") JSONArray items) { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setItems(items); - } else { - throw new AndroidRuntimeException("No dialog to add list to."); - } - } - - /** - * This creates a list of radio buttons. You can select one item out of the list. A response will - * not be returned until the dialog is closed, either with the Cancel key or a button - * (positive/negative/neutral). Use {@link #dialogGetSelectedItems()} to find out what was - * selected. - */ - @Rpc(description = "Set dialog single choice items and selected item.") - public void dialogSetSingleChoiceItems( - @RpcParameter(name = "items") JSONArray items, - @RpcParameter(name = "selected", description = "selected item index") @RpcDefault("0") Integer selected) { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setSingleChoiceItems(items, selected); - } else { - throw new AndroidRuntimeException("No dialog to add list to."); - } - } - - /** - * This creates a list of check boxes. You can select multiple items out of the list. A response - * will not be returned until the dialog is closed, either with the Cancel key or a button - * (positive/negative/neutral). Use {@link #dialogGetSelectedItems()} to find out what was - * selected. - */ - - @Rpc(description = "Set dialog multiple choice items and selection.") - public void dialogSetMultiChoiceItems( - @RpcParameter(name = "items") JSONArray items, - @RpcParameter(name = "selected", description = "list of selected items") @RpcOptional JSONArray selected) - throws JSONException { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - ((AlertDialogTask) mDialogTask).setMultiChoiceItems(items, selected); - } else { - throw new AndroidRuntimeException("No dialog to add list to."); - } - } - - @Rpc(description = "Returns dialog response.") - public Object dialogGetResponse() { - try { - return mDialogTask.getResult(); - } catch (Exception e) { - throw new AndroidRuntimeException(e); - } - } - - @Rpc(description = "This method provides list of items user selected.", returns = "Selected items") - public Set<Integer> dialogGetSelectedItems() { - if (mDialogTask != null && mDialogTask instanceof AlertDialogTask) { - return ((AlertDialogTask) mDialogTask).getSelectedItems(); - } else { - throw new AndroidRuntimeException("No dialog to add list to."); - } - } - - @Rpc(description = "Adds a new item to context menu.") - public void addContextMenuItem( - @RpcParameter(name = "label", description = "label for this menu item") String label, - @RpcParameter(name = "event", description = "event that will be generated on menu item click") String event, - @RpcParameter(name = "eventData") @RpcOptional Object data) { - mContextMenuItems.add(new UiMenuItem(label, event, data, null)); - } - - /** - * <b>Example (python)</b> - * - * <pre> - * import android - * droid=android.Android() - * - * droid.addOptionsMenuItem("Silly","silly",None,"star_on") - * droid.addOptionsMenuItem("Sensible","sensible","I bet.","star_off") - * droid.addOptionsMenuItem("Off","off",None,"ic_menu_revert") - * - * print "Hit menu to see extra options." - * print "Will timeout in 10 seconds if you hit nothing." - * - * while True: # Wait for events from the menu. - * response=droid.eventWait(10000).result - * if response==None: - * break - * print response - * if response["name"]=="off": - * break - * print "And done." - * - * </pre> - */ - @Rpc(description = "Adds a new item to options menu.") - public void addOptionsMenuItem( - @RpcParameter(name = "label", description = "label for this menu item") String label, - @RpcParameter(name = "event", description = "event that will be generated on menu item click") String event, - @RpcParameter(name = "eventData") @RpcOptional Object data, - @RpcParameter(name = "iconName", description = "Android system menu icon, see http://developer.android.com/reference/android/R.drawable.html") @RpcOptional String iconName) { - mOptionsMenuItems.add(new UiMenuItem(label, event, data, iconName)); - mMenuUpdated.set(true); - } - - @Rpc(description = "Removes all items previously added to context menu.") - public void clearContextMenu() { - mContextMenuItems.clear(); - } - - @Rpc(description = "Removes all items previously added to options menu.") - public void clearOptionsMenu() { - mOptionsMenuItems.clear(); - mMenuUpdated.set(true); - } - - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - for (UiMenuItem item : mContextMenuItems) { - MenuItem menuItem = menu.add(item.mmTitle); - menuItem.setOnMenuItemClickListener(item.mmListener); - } - } - - public boolean onPrepareOptionsMenu(Menu menu) { - if (mMenuUpdated.getAndSet(false)) { - menu.removeGroup(MENU_GROUP_ID); - for (UiMenuItem item : mOptionsMenuItems) { - MenuItem menuItem = menu.add(MENU_GROUP_ID, Menu.NONE, Menu.NONE, item.mmTitle); - if (item.mmIcon != null) { - menuItem.setIcon(mService.getResources() - .getIdentifier(item.mmIcon, "drawable", "android")); - } - menuItem.setOnMenuItemClickListener(item.mmListener); - } - return true; - } - return true; - } - - /** - * See <a href=http://code.google.com/p/android-scripting/wiki/FullScreenUI>wiki page</a> for more - * detail. - */ - @Rpc(description = "Show Full Screen.") - public List<String> fullShow( - @RpcParameter(name = "layout", description = "String containing View layout") String layout, - @RpcParameter(name = "title", description = "Activity Title") @RpcOptional String title) - throws InterruptedException { - if (mFullScreenTask != null) { - // fullDismiss(); - mFullScreenTask.setLayout(layout); - if (title != null) { - mFullScreenTask.setTitle(title); - } - } else { - mFullScreenTask = new FullScreenTask(layout, title); - mFullScreenTask.setEventFacade(mEventFacade); - mFullScreenTask.setUiFacade(this); - mFullScreenTask.setOverrideKeys(mOverrideKeys); - mTaskQueue.execute(mFullScreenTask); - mFullScreenTask.getShowLatch().await(); - } - return mFullScreenTask.mInflater.getErrors(); - } - - @Rpc(description = "Dismiss Full Screen.") - public void fullDismiss() { - if (mFullScreenTask != null) { - mFullScreenTask.finish(); - mFullScreenTask = null; - } - } - - class MouseMotionListener implements View.OnGenericMotionListener { - - @Override - public boolean onGenericMotion(View v, MotionEvent event) { - Log.d("Generic motion triggered."); - if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { - mLastXPosition = event.getAxisValue(MotionEvent.AXIS_X); - Log.d("New mouse x coord: " + mLastXPosition); -// Bundle msg = new Bundle(); -// msg.putFloat("value", mLastXPosition); -// mEventFacade.postEvent("MouseXPositionUpdate", msg); - return true; - } - return false; - } - } - - @Rpc(description = "Get Fullscreen Properties") - public Map<String, Map<String, String>> fullQuery() { - if (mFullScreenTask == null) { - throw new RuntimeException("No screen displayed."); - } - return mFullScreenTask.getViewAsMap(); - } - - @Rpc(description = "Get fullscreen properties for a specific widget") - public Map<String, String> fullQueryDetail( - @RpcParameter(name = "id", description = "id of layout widget") String id) { - if (mFullScreenTask == null) { - throw new RuntimeException("No screen displayed."); - } - return mFullScreenTask.getViewDetail(id); - } - - @Rpc(description = "Set fullscreen widget property") - public String fullSetProperty( - @RpcParameter(name = "id", description = "id of layout widget") String id, - @RpcParameter(name = "property", description = "name of property to set") String property, - @RpcParameter(name = "value", description = "value to set property to") String value) { - if (mFullScreenTask == null) { - throw new RuntimeException("No screen displayed."); - } - return mFullScreenTask.setViewProperty(id, property, value); - } - - @Rpc(description = "Attach a list to a fullscreen widget") - public String fullSetList( - @RpcParameter(name = "id", description = "id of layout widget") String id, - @RpcParameter(name = "list", description = "List to set") JSONArray items) { - if (mFullScreenTask == null) { - throw new RuntimeException("No screen displayed."); - } - return mFullScreenTask.setList(id, items); - } - - @Rpc(description = "Set the Full Screen Activity Title") - public void fullSetTitle( - @RpcParameter(name = "title", description = "Activity Title") String title) { - if (mFullScreenTask == null) { - throw new RuntimeException("No screen displayed."); - } - mFullScreenTask.setTitle(title); - } - - /** - * This will override the default behaviour of keys while in the fullscreen mode. ie: - * - * <pre> - * droid.fullKeyOverride([24,25],True) - * </pre> - * - * This will override the default behaviour of the volume keys (codes 24 and 25) so that they do - * not actually adjust the volume. <br> - * Returns a list of currently overridden keycodes. - */ - @Rpc(description = "Override default key actions") - public JSONArray fullKeyOverride( - @RpcParameter(name = "keycodes", description = "List of keycodes to override") JSONArray keycodes, - @RpcParameter(name = "enable", description = "Turn overriding or off") @RpcDefault(value = "true") Boolean enable) - throws JSONException { - for (int i = 0; i < keycodes.length(); i++) { - int value = (int) keycodes.getLong(i); - if (value > 0) { - if (enable) { - if (!mOverrideKeys.contains(value)) { - mOverrideKeys.add(value); - } - } else { - int index = mOverrideKeys.indexOf(value); - if (index >= 0) { - mOverrideKeys.remove(index); - } - } - } - } - if (mFullScreenTask != null) { - mFullScreenTask.setOverrideKeys(mOverrideKeys); - } - return new JSONArray(mOverrideKeys); - } - - @Rpc(description = "Start tracking mouse cursor x coordinate.") - public void startTrackingMouseXCoord() throws InterruptedException { - View.OnGenericMotionListener l = new MouseMotionListener(); - fullShow(blankLayout, "Blank"); - mFullScreenTask.mView.setOnGenericMotionListener(l); - } - - @Rpc(description = "Stop tracking mouse cursor x coordinate.") - public void stopTrackingMouseXCoord() throws InterruptedException { - fullDismiss(); - } - - @Rpc(description = "Return the latest X position of mouse cursor.") - public float getLatestMouseXCoord() { - return mLastXPosition; - } - -@Override - public void shutdown() { - fullDismiss(); - } - - private class UiMenuItem { - - private final String mmTitle; - private final String mmEvent; - private final Object mmEventData; - private final String mmIcon; - private final MenuItem.OnMenuItemClickListener mmListener; - - public UiMenuItem(String title, String event, Object data, String icon) { - mmTitle = title; - mmEvent = event; - mmEventData = data; - mmIcon = icon; - mmListener = new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - // TODO(damonkohler): Does mmEventData need to be cloned somehow? - mEventFacade.postEvent(mmEvent, mmEventData); - return true; - } - }; - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ViewInflater.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ViewInflater.java deleted file mode 100644 index 871c562..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/ui/ViewInflater.java +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.ui; - -import android.app.Activity; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Typeface; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.text.InputType; -import android.text.method.DigitsKeyListener; -import android.util.DisplayMetrics; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.ArrayAdapter; -import android.widget.ListAdapter; -import android.widget.RelativeLayout; -import android.widget.Spinner; -import android.widget.SpinnerAdapter; -import android.widget.TableLayout; -import android.widget.TextView; - -import com.googlecode.android_scripting.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.json.JSONArray; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -public class ViewInflater { - private static XmlPullParserFactory mFactory; - public static final String ANDROID = "http://schemas.android.com/apk/res/android"; - public static final int BASESEQ = 0x7f0f0000; - private int mNextSeq = BASESEQ; - private final Map<String, Integer> mIdList = new HashMap<String, Integer>(); - private final List<String> mErrors = new ArrayList<String>(); - private Context mContext; - private DisplayMetrics mMetrics; - private static final Map<String, Integer> mInputTypes = new HashMap<String, Integer>(); - public static final Map<String, String> mColorNames = new HashMap<String, String>(); - public static final Map<String, Integer> mRelative = new HashMap<String, Integer>(); - static { - mColorNames.put("aliceblue", "#f0f8ff"); - mColorNames.put("antiquewhite", "#faebd7"); - mColorNames.put("aqua", "#00ffff"); - mColorNames.put("aquamarine", "#7fffd4"); - mColorNames.put("azure", "#f0ffff"); - mColorNames.put("beige", "#f5f5dc"); - mColorNames.put("bisque", "#ffe4c4"); - mColorNames.put("black", "#000000"); - mColorNames.put("blanchedalmond", "#ffebcd"); - mColorNames.put("blue", "#0000ff"); - mColorNames.put("blueviolet", "#8a2be2"); - mColorNames.put("brown", "#a52a2a"); - mColorNames.put("burlywood", "#deb887"); - mColorNames.put("cadetblue", "#5f9ea0"); - mColorNames.put("chartreuse", "#7fff00"); - mColorNames.put("chocolate", "#d2691e"); - mColorNames.put("coral", "#ff7f50"); - mColorNames.put("cornflowerblue", "#6495ed"); - mColorNames.put("cornsilk", "#fff8dc"); - mColorNames.put("crimson", "#dc143c"); - mColorNames.put("cyan", "#00ffff"); - mColorNames.put("darkblue", "#00008b"); - mColorNames.put("darkcyan", "#008b8b"); - mColorNames.put("darkgoldenrod", "#b8860b"); - mColorNames.put("darkgray", "#a9a9a9"); - mColorNames.put("darkgrey", "#a9a9a9"); - mColorNames.put("darkgreen", "#006400"); - mColorNames.put("darkkhaki", "#bdb76b"); - mColorNames.put("darkmagenta", "#8b008b"); - mColorNames.put("darkolivegreen", "#556b2f"); - mColorNames.put("darkorange", "#ff8c00"); - mColorNames.put("darkorchid", "#9932cc"); - mColorNames.put("darkred", "#8b0000"); - mColorNames.put("darksalmon", "#e9967a"); - mColorNames.put("darkseagreen", "#8fbc8f"); - mColorNames.put("darkslateblue", "#483d8b"); - mColorNames.put("darkslategray", "#2f4f4f"); - mColorNames.put("darkslategrey", "#2f4f4f"); - mColorNames.put("darkturquoise", "#00ced1"); - mColorNames.put("darkviolet", "#9400d3"); - mColorNames.put("deeppink", "#ff1493"); - mColorNames.put("deepskyblue", "#00bfff"); - mColorNames.put("dimgray", "#696969"); - mColorNames.put("dimgrey", "#696969"); - mColorNames.put("dodgerblue", "#1e90ff"); - mColorNames.put("firebrick", "#b22222"); - mColorNames.put("floralwhite", "#fffaf0"); - mColorNames.put("forestgreen", "#228b22"); - mColorNames.put("fuchsia", "#ff00ff"); - mColorNames.put("gainsboro", "#dcdcdc"); - mColorNames.put("ghostwhite", "#f8f8ff"); - mColorNames.put("gold", "#ffd700"); - mColorNames.put("goldenrod", "#daa520"); - mColorNames.put("gray", "#808080"); - mColorNames.put("grey", "#808080"); - mColorNames.put("green", "#008000"); - mColorNames.put("greenyellow", "#adff2f"); - mColorNames.put("honeydew", "#f0fff0"); - mColorNames.put("hotpink", "#ff69b4"); - mColorNames.put("indianred ", "#cd5c5c"); - mColorNames.put("indigo ", "#4b0082"); - mColorNames.put("ivory", "#fffff0"); - mColorNames.put("khaki", "#f0e68c"); - mColorNames.put("lavender", "#e6e6fa"); - mColorNames.put("lavenderblush", "#fff0f5"); - mColorNames.put("lawngreen", "#7cfc00"); - mColorNames.put("lemonchiffon", "#fffacd"); - mColorNames.put("lightblue", "#add8e6"); - mColorNames.put("lightcoral", "#f08080"); - mColorNames.put("lightcyan", "#e0ffff"); - mColorNames.put("lightgoldenrodyellow", "#fafad2"); - mColorNames.put("lightgray", "#d3d3d3"); - mColorNames.put("lightgrey", "#d3d3d3"); - mColorNames.put("lightgreen", "#90ee90"); - mColorNames.put("lightpink", "#ffb6c1"); - mColorNames.put("lightsalmon", "#ffa07a"); - mColorNames.put("lightseagreen", "#20b2aa"); - mColorNames.put("lightskyblue", "#87cefa"); - mColorNames.put("lightslategray", "#778899"); - mColorNames.put("lightslategrey", "#778899"); - mColorNames.put("lightsteelblue", "#b0c4de"); - mColorNames.put("lightyellow", "#ffffe0"); - mColorNames.put("lime", "#00ff00"); - mColorNames.put("limegreen", "#32cd32"); - mColorNames.put("linen", "#faf0e6"); - mColorNames.put("magenta", "#ff00ff"); - mColorNames.put("maroon", "#800000"); - mColorNames.put("mediumaquamarine", "#66cdaa"); - mColorNames.put("mediumblue", "#0000cd"); - mColorNames.put("mediumorchid", "#ba55d3"); - mColorNames.put("mediumpurple", "#9370d8"); - mColorNames.put("mediumseagreen", "#3cb371"); - mColorNames.put("mediumslateblue", "#7b68ee"); - mColorNames.put("mediumspringgreen", "#00fa9a"); - mColorNames.put("mediumturquoise", "#48d1cc"); - mColorNames.put("mediumvioletred", "#c71585"); - mColorNames.put("midnightblue", "#191970"); - mColorNames.put("mintcream", "#f5fffa"); - mColorNames.put("mistyrose", "#ffe4e1"); - mColorNames.put("moccasin", "#ffe4b5"); - mColorNames.put("navajowhite", "#ffdead"); - mColorNames.put("navy", "#000080"); - mColorNames.put("oldlace", "#fdf5e6"); - mColorNames.put("olive", "#808000"); - mColorNames.put("olivedrab", "#6b8e23"); - mColorNames.put("orange", "#ffa500"); - mColorNames.put("orangered", "#ff4500"); - mColorNames.put("orchid", "#da70d6"); - mColorNames.put("palegoldenrod", "#eee8aa"); - mColorNames.put("palegreen", "#98fb98"); - mColorNames.put("paleturquoise", "#afeeee"); - mColorNames.put("palevioletred", "#d87093"); - mColorNames.put("papayawhip", "#ffefd5"); - mColorNames.put("peachpuff", "#ffdab9"); - mColorNames.put("peru", "#cd853f"); - mColorNames.put("pink", "#ffc0cb"); - mColorNames.put("plum", "#dda0dd"); - mColorNames.put("powderblue", "#b0e0e6"); - mColorNames.put("purple", "#800080"); - mColorNames.put("red", "#ff0000"); - mColorNames.put("rosybrown", "#bc8f8f"); - mColorNames.put("royalblue", "#4169e1"); - mColorNames.put("saddlebrown", "#8b4513"); - mColorNames.put("salmon", "#fa8072"); - mColorNames.put("sandybrown", "#f4a460"); - mColorNames.put("seagreen", "#2e8b57"); - mColorNames.put("seashell", "#fff5ee"); - mColorNames.put("sienna", "#a0522d"); - mColorNames.put("silver", "#c0c0c0"); - mColorNames.put("skyblue", "#87ceeb"); - mColorNames.put("slateblue", "#6a5acd"); - mColorNames.put("slategray", "#708090"); - mColorNames.put("slategrey", "#708090"); - mColorNames.put("snow", "#fffafa"); - mColorNames.put("springgreen", "#00ff7f"); - mColorNames.put("steelblue", "#4682b4"); - mColorNames.put("tan", "#d2b48c"); - mColorNames.put("teal", "#008080"); - mColorNames.put("thistle", "#d8bfd8"); - mColorNames.put("tomato", "#ff6347"); - mColorNames.put("turquoise", "#40e0d0"); - mColorNames.put("violet", "#ee82ee"); - mColorNames.put("wheat", "#f5deb3"); - mColorNames.put("white", "#ffffff"); - mColorNames.put("whitesmoke", "#f5f5f5"); - mColorNames.put("yellow", "#ffff00"); - mColorNames.put("yellowgreen", "#9acd32"); - - mRelative.put("above", RelativeLayout.ABOVE); - mRelative.put("alignBaseline", RelativeLayout.ALIGN_BASELINE); - mRelative.put("alignBottom", RelativeLayout.ALIGN_BOTTOM); - mRelative.put("alignLeft", RelativeLayout.ALIGN_LEFT); - mRelative.put("alignParentBottom", RelativeLayout.ALIGN_PARENT_BOTTOM); - mRelative.put("alignParentLeft", RelativeLayout.ALIGN_PARENT_LEFT); - mRelative.put("alignParentRight", RelativeLayout.ALIGN_PARENT_RIGHT); - mRelative.put("alignParentTop", RelativeLayout.ALIGN_PARENT_TOP); - mRelative.put("alignRight", RelativeLayout.ALIGN_PARENT_RIGHT); - mRelative.put("alignTop", RelativeLayout.ALIGN_TOP); - // mRelative.put("alignWithParentIfMissing",RelativeLayout.); // No idea what this translates - // to. - mRelative.put("below", RelativeLayout.BELOW); - mRelative.put("centerHorizontal", RelativeLayout.CENTER_HORIZONTAL); - mRelative.put("centerInParent", RelativeLayout.CENTER_IN_PARENT); - mRelative.put("centerVertical", RelativeLayout.CENTER_VERTICAL); - mRelative.put("toLeftOf", RelativeLayout.LEFT_OF); - mRelative.put("toRightOf", RelativeLayout.RIGHT_OF); - } - - public static XmlPullParserFactory getFactory() throws XmlPullParserException { - if (mFactory == null) { - mFactory = XmlPullParserFactory.newInstance(); - mFactory.setNamespaceAware(true); - } - return mFactory; - } - - public static XmlPullParser getXml() throws XmlPullParserException { - return getFactory().newPullParser(); - } - - public static XmlPullParser getXml(InputStream is) throws XmlPullParserException { - XmlPullParser xml = getXml(); - xml.setInput(is, null); - return xml; - } - - public static XmlPullParser getXml(Reader ir) throws XmlPullParserException { - XmlPullParser xml = getXml(); - xml.setInput(ir); - return xml; - } - - public View inflate(Activity context, XmlPullParser xml) throws XmlPullParserException, - IOException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { - int event; - mContext = context; - mErrors.clear(); - mMetrics = new DisplayMetrics(); - context.getWindowManager().getDefaultDisplay().getMetrics(mMetrics); - do { - event = xml.next(); - if (event == XmlPullParser.END_DOCUMENT) { - return null; - } - } while (event != XmlPullParser.START_TAG); - View view = inflateView(context, xml, null); - return view; - } - - private void addln(Object msg) { - Log.d(msg.toString()); - } - - @SuppressWarnings("rawtypes") - public void setClickListener(View v, android.view.View.OnClickListener listener, - OnItemClickListener itemListener) { - if (v.isClickable()) { - - if (v instanceof AdapterView) { - try { - ((AdapterView) v).setOnItemClickListener(itemListener); - } catch (RuntimeException e) { - // Ignore this, not all controls support OnItemClickListener - } - } - try { - v.setOnClickListener(listener); - } catch (RuntimeException e) { - // And not all controls support OnClickListener. - } - } - if (v instanceof ViewGroup) { - ViewGroup vg = (ViewGroup) v; - for (int i = 0; i < vg.getChildCount(); i++) { - setClickListener(vg.getChildAt(i), listener, itemListener); - } - } - } - - private View inflateView(Context context, XmlPullParser xml, ViewGroup root) - throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, - XmlPullParserException, IOException { - View view = buildView(context, xml, root); - if (view == null) { - return view; - } - int event; - while ((event = xml.next()) != XmlPullParser.END_DOCUMENT) { - switch (event) { - case XmlPullParser.START_TAG: - if (view == null || view instanceof ViewGroup) { - inflateView(context, xml, (ViewGroup) view); - } else { - skipTag(xml); // Not really a view, probably, skip it. - } - break; - case XmlPullParser.END_TAG: - return view; - } - } - return view; - } - - private void skipTag(XmlPullParser xml) throws XmlPullParserException, IOException { - int depth = xml.getDepth(); - int event; - while ((event = xml.next()) != XmlPullParser.END_DOCUMENT) { - if (event == XmlPullParser.END_TAG && xml.getDepth() <= depth) { - break; - } - } - } - - private View buildView(Context context, XmlPullParser xml, ViewGroup root) - throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - View view = viewClass(context, xml.getName()); - if (view != null) { - getLayoutParams(view, root); // Make quite sure every view has a layout param. - for (int i = 0; i < xml.getAttributeCount(); i++) { - String ns = xml.getAttributeNamespace(i); - String attr = xml.getAttributeName(i); - if (ANDROID.equals(ns)) { - setProperty(view, root, attr, xml.getAttributeValue(i)); - } - } - if (root != null) { - root.addView(view); - } - } - - return view; - } - - private int getLayoutValue(String value) { - if (value == null) { - return 0; - } - if (value.equals("match_parent")) { - return LayoutParams.MATCH_PARENT; - } - if (value.equals("wrap_content")) { - return LayoutParams.WRAP_CONTENT; - } - if (value.equals("fill_parent")) { - return LayoutParams.MATCH_PARENT; - } - return (int) getFontSize(value); - } - - private float getFontSize(String value) { - int i; - float size; - String unit = "px"; - for (i = 0; i < value.length(); i++) { - char c = value.charAt(i); - if (!(Character.isDigit(c) || c == '.')) { - break; - } - } - size = Float.parseFloat(value.substring(0, i)); - if (i < value.length()) { - unit = value.substring(i).trim(); - } - if (unit.equals("px")) { - return size; - } - if (unit.equals("sp")) { - return mMetrics.scaledDensity * size; - } - if (unit.equals("dp") || unit.equals("dip")) { - return mMetrics.density * size; - } - float inches = mMetrics.ydpi * size; - if (unit.equals("in")) { - return inches; - } - if (unit.equals("pt")) { - return inches / 72; - } - if (unit.equals("mm")) { - return (float) (inches / 2.54); - } - return 0; - } - - private int calcId(String value) { - if (value == null) { - return 0; - } - if (value.startsWith("@+id/")) { - return tryGetId(value.substring(5)); - } - if (value.startsWith("@id/")) { - return tryGetId(value.substring(4)); - } - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return 0; - } - } - - private int tryGetId(String value) { - Integer id = mIdList.get(value); - if (id == null) { - id = new Integer(mNextSeq++); - mIdList.put(value, id); - } - return id; - } - - private LayoutParams getLayoutParams(View view, ViewGroup root) { - LayoutParams result = view.getLayoutParams(); - if (result == null) { - result = createLayoutParams(root); - view.setLayoutParams(result); - } - return result; - } - - private LayoutParams createLayoutParams(ViewGroup root) { - LayoutParams result = null; - if (root != null) { - try { - String lookfor = root.getClass().getName() + "$LayoutParams"; - addln(lookfor); - Class<? extends LayoutParams> clazz = Class.forName(lookfor).asSubclass(LayoutParams.class); - if (clazz != null) { - Constructor<? extends LayoutParams> ct = clazz.getConstructor(int.class, int.class); - result = ct.newInstance(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - } - } catch (Exception e) { - result = null; - } - } - if (result == null) { - result = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - } - return result; - } - - public void setProperty(View view, String attr, String value) { - try { - setProperty(view, (ViewGroup) view.getParent(), attr, value); - } catch (Exception e) { - mErrors.add(e.toString()); - } - } - - private void setProperty(View view, ViewGroup root, String attr, String value) - throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - addln(attr + ":" + value); - if (attr.startsWith("layout_")) { - setLayoutProperty(view, root, attr, value); - } else if (attr.equals("id")) { - view.setId(calcId(value)); - } else if (attr.equals("gravity")) { - setInteger(view, attr, getInteger(Gravity.class, value)); - } else if (attr.equals("width") || attr.equals("height")) { - setInteger(view, attr, (int) getFontSize(value)); - } else if (attr.equals("inputType")) { - setInteger(view, attr, getInteger(InputType.class, value)); - } else if (attr.equals("background")) { - setBackground(view, value); - } else if (attr.equals("digits") && view instanceof TextView) { - ((TextView) view).setKeyListener(DigitsKeyListener.getInstance(value)); - } else if (attr.startsWith("nextFocus")) { - setInteger(view, attr + "Id", calcId(value)); - } else if (attr.equals("padding")) { - int size = (int) getFontSize(value); - view.setPadding(size, size, size, size); - } else if (attr.equals("stretchColumns")) { - setStretchColumns(view, value); - } else if (attr.equals("textSize")) { - setFloat(view, attr, getFontSize(value)); - } else if (attr.equals("textColor")) { - setInteger(view, attr, getColor(value)); - } else if (attr.equals("textHighlightColor")) { - setInteger(view, "HighlightColor", getColor(value)); - } else if (attr.equals("textColorHint")) { - setInteger(view, "LinkTextColor", getColor(value)); - } else if (attr.equals("textStyle")) { - TextView textview = (TextView) view; - int style = getInteger(Typeface.class, value); - if (style == 0) { - textview.setTypeface(Typeface.DEFAULT); - } else { - textview.setTypeface(textview.getTypeface(), style); - } - } else if (attr.equals("typeface")) { - TextView textview = (TextView) view; - Typeface typeface = textview.getTypeface(); - int style = typeface == null ? 0 : typeface.getStyle(); - textview.setTypeface(Typeface.create(value, style)); - } else if (attr.equals("src")) { - setImage(view, value); - } else { - setDynamicProperty(view, attr, value); - } - } - - private void setStretchColumns(View view, String value) { - TableLayout table = (TableLayout) view; - String[] values = value.split(","); - for (String column : values) { - table.setColumnStretchable(Integer.parseInt(column), true); - } - } - - private void setLayoutProperty(View view, ViewGroup root, String attr, String value) { - LayoutParams layout = getLayoutParams(view, root); - String layoutAttr = attr.substring(7); - if (layoutAttr.equals("width")) { - layout.width = getLayoutValue(value); - } else if (layoutAttr.equals("height")) { - layout.height = getLayoutValue(value); - } else if (layoutAttr.equals("gravity")) { - setIntegerField(layout, "gravity", getInteger(Gravity.class, value)); - } else { - if (layoutAttr.startsWith("margin") && layout instanceof MarginLayoutParams) { - int size = (int) getFontSize(value); - MarginLayoutParams margins = (MarginLayoutParams) layout; - if (layoutAttr.equals("marginBottom")) { - margins.bottomMargin = size; - } else if (layoutAttr.equals("marginTop")) { - margins.topMargin = size; - } else if (layoutAttr.equals("marginLeft")) { - margins.leftMargin = size; - } else if (layoutAttr.equals("marginRight")) { - margins.rightMargin = size; - } - } else if (layout instanceof RelativeLayout.LayoutParams) { - int anchor = calcId(value); - if (anchor == 0) { - anchor = getInteger(RelativeLayout.class, value); - } - int rule = mRelative.get(layoutAttr); - ((RelativeLayout.LayoutParams) layout).addRule(rule, anchor); - } else { - setIntegerField(layout, layoutAttr, getInteger(layout.getClass(), value)); - } - } - } - - private void setBackground(View view, String value) { - if (value.startsWith("#")) { - view.setBackgroundColor(getColor(value)); - } else if (value.startsWith("@")) { - setInteger(view, "backgroundResource", getInteger(view, value)); - } else { - view.setBackground(getDrawable(value)); - } - } - - private Drawable getDrawable(String value) { - try { - Uri uri = Uri.parse(value); - if ("file".equals(uri.getScheme())) { - BitmapDrawable bd = new BitmapDrawable(mContext.getResources(), uri.getPath()); - return bd; - } - } catch (Exception e) { - mErrors.add("failed to load drawable " + value); - } - return null; - } - - private void setImage(View view, String value) { - if (value.startsWith("@")) { - setInteger(view, "imageResource", getInteger(view, value)); - } else { - try { - Uri uri = Uri.parse(value); - if ("file".equals(uri.getScheme())) { - Bitmap bm = BitmapFactory.decodeFile(uri.getPath()); - Method method = view.getClass().getMethod("setImageBitmap", Bitmap.class); - method.invoke(view, bm); - } else { - mErrors.add("Only 'file' currently supported for images"); - } - } catch (Exception e) { - mErrors.add("failed to set image " + value); - } - } - } - - private void setIntegerField(Object target, String fieldName, int value) { - try { - Field f = target.getClass().getField(fieldName); - f.setInt(target, value); - } catch (Exception e) { - mErrors.add("set field)" + fieldName + " failed. " + e.toString()); - } - } - - /** Expand single digit color to 2 digits. */ - private int expandColor(String colorValue) { - return Integer.parseInt(colorValue + colorValue, 16); - } - - private int getColor(String value) { - int a = 0xff, r = 0, g = 0, b = 0; - if (value.startsWith("#")) { - try { - value = value.substring(1); - if (value.length() == 4) { - a = expandColor(value.substring(0, 1)); - value = value.substring(1); - } - if (value.length() == 3) { - r = expandColor(value.substring(0, 1)); - g = expandColor(value.substring(1, 2)); - b = expandColor(value.substring(2, 3)); - } else { - if (value.length() == 8) { - a = Integer.parseInt(value.substring(0, 2), 16); - value = value.substring(2); - } - if (value.length() == 6) { - r = Integer.parseInt(value.substring(0, 2), 16); - g = Integer.parseInt(value.substring(2, 4), 16); - b = Integer.parseInt(value.substring(4, 6), 16); - } - } - long result = (a << 24) | (r << 16) | (g << 8) | b; - return (int) result; - } catch (Exception e) { - } - } else if (mColorNames.containsKey(value.toLowerCase())) { - return getColor(mColorNames.get(value.toLowerCase())); - } - mErrors.add("Unknown color " + value); - return 0; - } - - private int getInputType(String value) { - int result = 0; - Integer v = getInputTypes().get(value); - if (v == null) { - mErrors.add("Unkown input type " + value); - } else { - result = v; - } - return result; - } - - private void setInteger(View view, String attr, int value) { - String name = "set" + PCase(attr); - Method m; - try { - if ((m = tryMethod(view, name, Context.class, int.class)) != null) { - m.invoke(view, mContext, value); - } else if ((m = tryMethod(view, name, int.class)) != null) { - m.invoke(view, value); - } - } catch (Exception e) { - addln(name + ":" + value + ":" + e.toString()); - } - - } - - private void setFloat(View view, String attr, float value) { - String name = "set" + PCase(attr); - Method m; - try { - if ((m = tryMethod(view, name, Context.class, float.class)) != null) { - m.invoke(view, mContext, value); - } else if ((m = tryMethod(view, name, float.class)) != null) { - m.invoke(view, value); - } - } catch (Exception e) { - addln(name + ":" + value + ":" + e.toString()); - } - - } - - private void setDynamicProperty(View view, String attr, String value) - throws IllegalArgumentException, IllegalAccessException, InvocationTargetException { - String name = "set" + PCase(attr); - try { - Method m = tryMethod(view, name, CharSequence.class); - if (m != null) { - m.invoke(view, value); - } else if ((m = tryMethod(view, name, Context.class, int.class)) != null) { - m.invoke(view, mContext, getInteger(view, value)); - } else if ((m = tryMethod(view, name, int.class)) != null) { - m.invoke(view, getInteger(view, value)); - } else if ((m = tryMethod(view, name, float.class)) != null) { - m.invoke(view, Float.parseFloat(value)); - } else if ((m = tryMethod(view, name, boolean.class)) != null) { - m.invoke(view, Boolean.parseBoolean(value)); - } else if ((m = tryMethod(view, name, Object.class)) != null) { - m.invoke(view, value); - } else { - mErrors.add(view.getClass().getSimpleName() + ":" + attr + " Property not found."); - } - } catch (Exception e) { - addln(name + ":" + value + ":" + e.toString()); - mErrors.add(name + ":" + value + ":" + e.toString()); - } - } - - private String PCase(String s) { - if (s == null) { - return null; - } - if (s.length() > 0) { - return s.substring(0, 1).toUpperCase() + s.substring(1); - } - return ""; - } - - private Method tryMethod(Object o, String name, Class<?>... parameters) { - Method result; - try { - result = o.getClass().getMethod(name, parameters); - } catch (Exception e) { - result = null; - } - return result; - } - - public String camelCase(String s) { - if (s == null) { - return ""; - } else if (s.length() < 2) { - return s.toUpperCase(); - } else { - return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); - } - } - - private Integer getInteger(Class<?> clazz, String value) { - Integer result = null; - if (value.contains("|")) { - int work = 0; - for (String s : value.split("\\|")) { - work |= getInteger(clazz, s); - } - result = work; - } else { - if (value.startsWith("?")) { - result = parseTheme(value); - } else if (value.startsWith("@")) { - result = parseTheme(value); - } else if (value.startsWith("0x")) { - try { - result = (int) Long.parseLong(value.substring(2), 16); - } catch (NumberFormatException e) { - result = 0; - } - } else { - try { - result = Integer.parseInt(value); - } catch (NumberFormatException e) { - if (clazz == InputType.class) { - return getInputType(value); - } - try { - Field f = clazz.getField(value.toUpperCase()); - result = f.getInt(null); - } catch (Exception ex) { - mErrors.add("Unknown value: " + value); - result = 0; - } - } - } - } - return result; - } - - private Integer getInteger(View view, String value) { - return getInteger(view.getClass(), value); - } - - private Integer parseTheme(String value) { - int result; - try { - String query = ""; - int i; - value = value.substring(1); // skip past "?" - i = value.indexOf(":"); - if (i >= 0) { - query = value.substring(0, i) + "."; - value = value.substring(i + 1); - } - query += "R"; - i = value.indexOf("/"); - if (i >= 0) { - query += "$" + value.substring(0, i); - value = value.substring(i + 1); - } - Class<?> clazz = Class.forName(query); - Field f = clazz.getField(value); - result = f.getInt(null); - } catch (Exception e) { - result = 0; - } - return result; - } - - private View viewClass(Context context, String name) { - View result = null; - result = viewClassTry(context, "android.view." + name); - if (result == null) { - result = viewClassTry(context, "android.widget." + name); - } - if (result == null) { - result = viewClassTry(context, name); - } - return result; - } - - private View viewClassTry(Context context, String name) { - View result = null; - try { - Class<? extends View> viewclass = Class.forName(name).asSubclass(View.class); - if (viewclass != null) { - Constructor<? extends View> ct = viewclass.getConstructor(Context.class); - result = ct.newInstance(context); - } - } catch (Exception e) { - } - return result; - - } - - public Map<String, Integer> getIdList() { - return mIdList; - } - - public List<String> getErrors() { - return mErrors; - } - - public String getIdName(int id) { - for (String key : mIdList.keySet()) { - if (mIdList.get(key) == id) { - return key; - } - } - return null; - } - - public int getId(String name) { - return mIdList.get(name); - } - - public Map<String, Map<String, String>> getViewAsMap(View v) { - Map<String, Map<String, String>> result = new HashMap<String, Map<String, String>>(); - for (Entry<String, Integer> entry : mIdList.entrySet()) { - View tmp = v.findViewById(entry.getValue()); - if (tmp != null) { - result.put(entry.getKey(), getViewInfo(tmp)); - } - } - return result; - } - - public Map<String, String> getViewInfo(View v) { - Map<String, String> result = new HashMap<String, String>(); - if (v.getId() != 0) { - result.put("id", getIdName(v.getId())); - } - result.put("type", v.getClass().getSimpleName()); - addProperty(v, "text", result); - addProperty(v, "visibility", result); - addProperty(v, "checked", result); - addProperty(v, "tag", result); - addProperty(v, "selectedItemPosition", result); - addProperty(v, "progress", result); - return result; - } - - private void addProperty(View v, String attr, Map<String, String> dest) { - String result = getProperty(v, attr); - if (result != null) { - dest.put(attr, result); - } - } - - private String getProperty(View v, String attr) { - String name = PCase(attr); - Method m = tryMethod(v, "get" + name); - if (m == null) { - m = tryMethod(v, "is" + name); - } - String result = null; - if (m != null) { - try { - Object o = m.invoke(v); - if (o != null) { - result = o.toString(); - } - } catch (Exception e) { - result = null; - } - } - return result; - } - - public static Map<String, Integer> getInputTypes() { - if (mInputTypes.size() == 0) { - mInputTypes.put("none", 0x00000000); - mInputTypes.put("text", 0x00000001); - mInputTypes.put("textCapCharacters", 0x00001001); - mInputTypes.put("textCapWords", 0x00002001); - mInputTypes.put("textCapSentences", 0x00004001); - mInputTypes.put("textAutoCorrect", 0x00008001); - mInputTypes.put("textAutoComplete", 0x00010001); - mInputTypes.put("textMultiLine", 0x00020001); - mInputTypes.put("textImeMultiLine", 0x00040001); - mInputTypes.put("textNoSuggestions", 0x00080001); - mInputTypes.put("textUri", 0x00000011); - mInputTypes.put("textEmailAddress", 0x00000021); - mInputTypes.put("textEmailSubject", 0x00000031); - mInputTypes.put("textShortMessage", 0x00000041); - mInputTypes.put("textLongMessage", 0x00000051); - mInputTypes.put("textPersonName", 0x00000061); - mInputTypes.put("textPostalAddress", 0x00000071); - mInputTypes.put("textPassword", 0x00000081); - mInputTypes.put("textVisiblePassword", 0x00000091); - mInputTypes.put("textWebEditText", 0x000000a1); - mInputTypes.put("textFilter", 0x000000b1); - mInputTypes.put("textPhonetic", 0x000000c1); - mInputTypes.put("textWebEmailAddress", 0x000000d1); - mInputTypes.put("textWebPassword", 0x000000e1); - mInputTypes.put("number", 0x00000002); - mInputTypes.put("numberSigned", 0x00001002); - mInputTypes.put("numberDecimal", 0x00002002); - mInputTypes.put("numberPassword", 0x00000012); - mInputTypes.put("phone", 0x00000003); - mInputTypes.put("datetime", 0x00000004); - mInputTypes.put("date", 0x00000014); - mInputTypes.put("time", 0x00000024); - } - return mInputTypes; - } - - /** Query class (typically R.id) to extract id names */ - public void setIdList(Class<?> idClass) { - mIdList.clear(); - for (Field f : idClass.getDeclaredFields()) { - try { - String name = f.getName(); - int value = f.getInt(null); - mIdList.put(name, value); - } catch (Exception e) { - // Ignore - } - } - } - - public void setListAdapter(View view, JSONArray items) { - List<String> list = new ArrayList<String>(); - try { - for (int i = 0; i < items.length(); i++) { - list.add(items.get(i).toString()); - } - ArrayAdapter<String> adapter; - if (view instanceof Spinner) { - adapter = - new ArrayAdapter<String>(mContext, android.R.layout.simple_spinner_item, - android.R.id.text1, list); - } else { - adapter = - new ArrayAdapter<String>(mContext, android.R.layout.simple_list_item_1, - android.R.id.text1, list); - } - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - Method m = tryMethod(view, "setAdapter", SpinnerAdapter.class); - if (m == null) { - m = view.getClass().getMethod("setAdapter", ListAdapter.class); - } - m.invoke(view, adapter); - } catch (Exception e) { - mErrors.add("failed to load list " + e.getMessage()); - } - } - - public void clearAll() { - getErrors().clear(); - mIdList.clear(); - mNextSeq = BASESEQ; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/HttpFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/HttpFacade.java deleted file mode 100644 index 75bf888..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/HttpFacade.java +++ /dev/null @@ -1,216 +0,0 @@ - -package com.googlecode.android_scripting.facade.wifi; - -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.net.URL; -import java.net.UnknownHostException; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; -import com.googlecode.android_scripting.rpc.RpcOptional; - -/** - * Basic http operations. - */ -public class HttpFacade extends RpcReceiver { - - private ServerSocket mServerSocket = null; - private int mServerTimeout = -1; - private HashMap<Integer, Socket> mSockets = null; - private int socketCnt = 0; - - public HttpFacade(FacadeManager manager) throws IOException { - super(manager); - mSockets = new HashMap<Integer, Socket>(); - } - - private void inputStreamToOutputStream(InputStream in, OutputStream out) throws IOException { - if (in == null) { - Log.e("InputStream is null."); - return; - } - if (out == null) { - Log.e("OutputStream is null."); - return; - } - try { - int read = 0; - byte[] bytes = new byte[1024]; - while ((read = in.read(bytes)) != -1) { - out.write(bytes, 0, read); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - in.close(); - out.close(); - } - - } - - private String inputStreamToString(InputStream in) throws IOException { - BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)); - StringBuilder sb = new StringBuilder(); - String str = null; - while ((str = r.readLine()) != null) { - sb.append(str); - } - return sb.toString(); - } - - /** - * Send an http request and get the response. - * - * @param url The url to send request to. - * @return The HttpURLConnection object. - */ - private HttpURLConnection httpRequest(String url) throws IOException { - URL targetURL = new URL(url); - HttpURLConnection urlConnection = null; - try { - urlConnection = (HttpURLConnection) targetURL.openConnection(); - urlConnection.connect(); - int respCode = urlConnection.getResponseCode(); - String respMsg = urlConnection.getResponseMessage(); - Log.d("Got response code: " + respCode + " and response msg: " + respMsg); - } catch (IOException e) { - Log.e("Failed to open a connection to " + url); - Log.e(e.toString()); - } finally { - if (urlConnection != null) { - urlConnection.disconnect(); - } - } - return urlConnection; - } - - @Rpc(description = "Start waiting for a connection request on a specified port.", - returns = "The index of the connection.") - public Integer httpAcceptConnection(Integer port) throws IOException { - mServerSocket = new ServerSocket(port); - if (mServerTimeout > 0) { - mServerSocket.setSoTimeout(mServerTimeout); - } - Socket sock = mServerSocket.accept(); - socketCnt += 1; - mSockets.put(socketCnt, sock); - return socketCnt; - } - - @Rpc(description = "Download a file from specified url.") - public void httpDownloadFile(String url) throws IOException { - HttpURLConnection urlConnection = httpRequest(url); - String filename = null; - String contentDisposition = urlConnection.getHeaderField("Content-Disposition"); - // Try to figure out the name of the file being downloaded. - // If the server returned a filename, use it. - if (contentDisposition != null) { - int idx = contentDisposition.toLowerCase().indexOf("filename"); - if (idx != -1) { - filename = contentDisposition.substring(idx + 9); - Log.d("Using name returned by server: " + filename); - } - } - // If the server did not provide a filename to us, use the last part of url. - if (filename == null) { - int lastIdx = url.lastIndexOf('/'); - filename = url.substring(lastIdx + 1); - Log.d("Using name from url: " + filename); - } - InputStream in = new BufferedInputStream(urlConnection.getInputStream()); - String outPath = "/sdcard/Download/" + filename; - OutputStream output = new FileOutputStream(new File(outPath)); - inputStreamToOutputStream(in, output); - Log.d("Downloaded file at " + outPath); - } - - @Rpc(description = "Make an http request and return the response message.") - public HttpURLConnection httpPing(@RpcParameter(name = "url") String url) throws IOException { - try { - HttpURLConnection urlConnection = null; - urlConnection = httpRequest(url); - return urlConnection; - } catch (UnknownHostException e) { - return null; - } - } - - @Rpc(description = "Make an http request and return the response content as a string.") - public String httpRequestString(@RpcParameter(name = "url") String url) throws IOException { - HttpURLConnection urlConnection = httpRequest(url); - InputStream in = new BufferedInputStream(urlConnection.getInputStream()); - String result = inputStreamToString(in); - Log.d("Fetched: " + result); - return result; - } - - @Rpc(description = "Set how many milliseconds to wait for an incoming connection.") - public void httpSetServerTimeout(@RpcParameter(name = "timeout") Integer timeout) - throws SocketException { - mServerSocket.setSoTimeout(timeout); - mServerTimeout = timeout; - } - - @Rpc(description = "Ping to host(URL or IP), return success (true) or fail (false).") - // The optional timeout parameter is in unit of second. - public Boolean pingHost(@RpcParameter(name = "host") String hostString, - @RpcParameter(name = "timeout") @RpcOptional Integer timeout) { - try { - String host; - try { - URL url = new URL(hostString); - host = url.getHost(); - } catch (java.net.MalformedURLException e) { - Log.d("hostString is not URL, it may be IP address."); - host = hostString; - } - - Log.d("Host:" + host); - String pingCmdString = "ping -c 1 "; - if (timeout != null) { - pingCmdString = pingCmdString + "-W " + timeout + " "; - } - pingCmdString = pingCmdString + host; - Log.d("Execute command: " + pingCmdString); - Process p1 = java.lang.Runtime.getRuntime().exec(pingCmdString); - int returnVal = p1.waitFor(); - boolean reachable = (returnVal == 0); - Log.d("Ping return Value:" + returnVal); - return reachable; - } catch (Exception e){ - e.printStackTrace(); - return false; - } - /*TODO see b/18899134 for more information. - */ - } - - @Override - public void shutdown() { - for (int key : mSockets.keySet()) { - Socket sock = mSockets.get(key); - try { - sock.close(); - } catch (IOException e) { - Log.e("Failed to close socket " + key + " on port " + sock.getLocalPort()); - e.printStackTrace(); - } - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java deleted file mode 100755 index c0efe0f..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiManagerFacade.java +++ /dev/null @@ -1,887 +0,0 @@ - -package com.googlecode.android_scripting.facade.wifi; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.net.ConnectException; -import java.security.GeneralSecurityException; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; -import java.util.ArrayList; -import java.util.List; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.DhcpInfo; -import android.net.Network; -import android.net.NetworkInfo; -import android.net.NetworkInfo.DetailedState; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiActivityEnergyInfo; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiConfiguration.AuthAlgorithm; -import android.net.wifi.WifiConfiguration.KeyMgmt; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.net.wifi.WifiManager.WifiLock; -import android.net.wifi.WpsInfo; -import android.os.Bundle; -import android.provider.Settings.Global; -import android.provider.Settings.SettingNotFoundException; -import android.util.Base64; - -/** - * WifiManager functions. - */ -// TODO: make methods handle various wifi states properly -// e.g. wifi connection result will be null when flight mode is on -public class WifiManagerFacade extends RpcReceiver { - private final static String mEventType = "WifiManager"; - private final Service mService; - private final WifiManager mWifi; - private final EventFacade mEventFacade; - - private final IntentFilter mScanFilter; - private final IntentFilter mStateChangeFilter; - private final IntentFilter mTetherFilter; - private final WifiScanReceiver mScanResultsAvailableReceiver; - private final WifiStateChangeReceiver mStateChangeReceiver; - private boolean mTrackingWifiStateChange; - - private final BroadcastReceiver mTetherStateReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(action)) { - Log.d("Wifi AP state changed."); - int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, - WifiManager.WIFI_AP_STATE_FAILED); - if (state == WifiManager.WIFI_AP_STATE_ENABLED) { - mEventFacade.postEvent("WifiManagerApEnabled", null); - } else if (state == WifiManager.WIFI_AP_STATE_DISABLED) { - mEventFacade.postEvent("WifiManagerApDisabled", null); - } - } else if (ConnectivityManager.ACTION_TETHER_STATE_CHANGED.equals(action)) { - Log.d("Tether state changed."); - ArrayList<String> available = intent.getStringArrayListExtra( - ConnectivityManager.EXTRA_AVAILABLE_TETHER); - ArrayList<String> active = intent.getStringArrayListExtra( - ConnectivityManager.EXTRA_ACTIVE_TETHER); - ArrayList<String> errored = intent.getStringArrayListExtra( - ConnectivityManager.EXTRA_ERRORED_TETHER); - Bundle msg = new Bundle(); - msg.putStringArrayList("AVAILABLE_TETHER", available); - msg.putStringArrayList("ACTIVE_TETHER", active); - msg.putStringArrayList("ERRORED_TETHER", errored); - mEventFacade.postEvent("TetherStateChanged", msg); - } - } - }; - - private WifiLock mLock = null; - private boolean mIsConnected = false; - - public WifiManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mWifi = (WifiManager) mService.getSystemService(Context.WIFI_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - - mScanFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); - mStateChangeFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION); - mStateChangeFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); - mStateChangeFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); - mStateChangeFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1); - - mTetherFilter = new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); - mTetherFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); - - mScanResultsAvailableReceiver = new WifiScanReceiver(mEventFacade); - mStateChangeReceiver = new WifiStateChangeReceiver(); - mTrackingWifiStateChange = false; - } - - private void makeLock(int wifiMode) { - if (mLock == null) { - mLock = mWifi.createWifiLock(wifiMode, "sl4a"); - mLock.acquire(); - } - } - - /** - * Handle Broadcast receiver for Scan Result - * - * @parm eventFacade Object of EventFacade - */ - class WifiScanReceiver extends BroadcastReceiver { - private final EventFacade mEventFacade; - - WifiScanReceiver(EventFacade eventFacade) { - mEventFacade = eventFacade; - } - - @Override - public void onReceive(Context c, Intent intent) { - String action = intent.getAction(); - if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - Bundle mResults = new Bundle(); - Log.d("Wifi connection scan finished, results available."); - mResults.putLong("Timestamp", System.currentTimeMillis() / 1000); - mEventFacade.postEvent(mEventType + "ScanResultsAvailable", mResults); - mService.unregisterReceiver(mScanResultsAvailableReceiver); - } - } - } - - class WifiActionListener implements WifiManager.ActionListener { - private final EventFacade mEventFacade; - private final String TAG; - - public WifiActionListener(EventFacade eventFacade, String tag) { - mEventFacade = eventFacade; - this.TAG = tag; - } - - @Override - public void onSuccess() { - Log.d("WifiActionListener onSuccess called for " + mEventType + TAG + "OnSuccess"); - mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null); - } - - @Override - public void onFailure(int reason) { - Log.d("WifiActionListener onFailure called for" + mEventType); - Bundle msg = new Bundle(); - msg.putInt("reason", reason); - mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg); - } - } - - public class WifiStateChangeReceiver extends BroadcastReceiver { - String mCachedWifiInfo = ""; - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - Log.d("Wifi network state changed."); - NetworkInfo nInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - WifiInfo wInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); - Log.d("NetworkInfo " + nInfo); - Log.d("WifiInfo " + wInfo); - // If network info is of type wifi, send wifi events. - if (nInfo.getType() == ConnectivityManager.TYPE_WIFI) { - if (wInfo != null && nInfo.getDetailedState().equals(DetailedState.CONNECTED)) { - String bssid = wInfo.getBSSID(); - if (bssid != null && !mCachedWifiInfo.equals(wInfo.toString())) { - Log.d("WifiNetworkConnected"); - mEventFacade.postEvent("WifiNetworkConnected", wInfo); - } - mCachedWifiInfo = wInfo.toString(); - } else { - if (nInfo.getDetailedState().equals(DetailedState.DISCONNECTED)) { - if (!mCachedWifiInfo.equals("")) { - mCachedWifiInfo = ""; - mEventFacade.postEvent("WifiNetworkDisconnected", null); - } - } - } - } - } else if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { - Log.d("Supplicant connection state changed."); - mIsConnected = intent - .getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false); - Bundle msg = new Bundle(); - msg.putBoolean("Connected", mIsConnected); - mEventFacade.postEvent("SupplicantConnectionChanged", msg); - } - } - } - - public class WifiWpsCallback extends WifiManager.WpsCallback { - private static final String tag = "WifiWps"; - - @Override - public void onStarted(String pin) { - Bundle msg = new Bundle(); - msg.putString("pin", pin); - mEventFacade.postEvent(tag + "OnStarted", msg); - } - - @Override - public void onSucceeded() { - Log.d("Wps op succeeded"); - mEventFacade.postEvent(tag + "OnSucceeded", null); - } - - @Override - public void onFailed(int reason) { - Bundle msg = new Bundle(); - msg.putInt("reason", reason); - mEventFacade.postEvent(tag + "OnFailed", msg); - } - } - - private void applyingkeyMgmt(WifiConfiguration config, ScanResult result) { - if (result.capabilities.contains("WEP")) { - config.allowedKeyManagement.set(KeyMgmt.NONE); - config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); - config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); - } else if (result.capabilities.contains("PSK")) { - config.allowedKeyManagement.set(KeyMgmt.WPA_PSK); - } else if (result.capabilities.contains("EAP")) { - // this is probably wrong, as we don't have a way to enter the enterprise config - config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); - config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); - } else { - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - } - } - - private WifiConfiguration genWifiConfig(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - WifiConfiguration config = new WifiConfiguration(); - if (j.has("SSID")) { - config.SSID = "\"" + j.getString("SSID") + "\""; - } else if (j.has("ssid")) { - config.SSID = "\"" + j.getString("ssid") + "\""; - } - if (j.has("password")) { - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - config.preSharedKey = "\"" + j.getString("password") + "\""; - } else { - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - } - if (j.has("BSSID")) { - config.BSSID = j.getString("BSSID"); - } - if (j.has("hiddenSSID")) { - config.hiddenSSID = j.getBoolean("hiddenSSID"); - } - if (j.has("priority")) { - config.priority = j.getInt("priority"); - } - if (j.has("apBand")) { - config.apBand = j.getInt("apBand"); - } - if (j.has("preSharedKey")) { - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - config.preSharedKey = j.getString("preSharedKey"); - } - if (j.has("wepKeys")) { - // Looks like we only support static WEP. - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); - config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); - config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED); - JSONArray keys = j.getJSONArray("wepKeys"); - String[] wepKeys = new String[keys.length()]; - for (int i = 0; i < keys.length(); i++) { - wepKeys[i] = keys.getString(i); - } - config.wepKeys = wepKeys; - } - if (j.has("wepTxKeyIndex")) { - config.wepTxKeyIndex = j.getInt("wepTxKeyIndex"); - } - return config; - } - - private WifiConfiguration genWifiEnterpriseConfig(JSONObject j) throws JSONException, - GeneralSecurityException { - if (j == null) { - return null; - } - WifiConfiguration config = new WifiConfiguration(); - config.allowedKeyManagement.set(KeyMgmt.WPA_EAP); - config.allowedKeyManagement.set(KeyMgmt.IEEE8021X); - if (j.has("SSID")) { - config.SSID = j.getString("SSID"); - } - if (j.has("FQDN")) { - config.FQDN = j.getString("FQDN"); - } - if (j.has("providerFriendlyName")) { - config.providerFriendlyName = j.getString("providerFriendlyName"); - } - if (j.has("roamingConsortiumIds")) { - JSONArray ids = j.getJSONArray("roamingConsortiumIds"); - long[] rIds = new long[ids.length()]; - for (int i = 0; i < ids.length(); i++) { - rIds[i] = ids.getLong(i); - } - config.roamingConsortiumIds = rIds; - } - WifiEnterpriseConfig eConfig = new WifiEnterpriseConfig(); - if (j.has(WifiEnterpriseConfig.EAP_KEY)) { - int eap = j.getInt(WifiEnterpriseConfig.EAP_KEY); - eConfig.setEapMethod(eap); - } - if (j.has(WifiEnterpriseConfig.PHASE2_KEY)) { - int p2Method = j.getInt(WifiEnterpriseConfig.PHASE2_KEY); - eConfig.setPhase2Method(p2Method); - } - if (j.has(WifiEnterpriseConfig.CA_CERT_KEY)) { - String certStr = j.getString(WifiEnterpriseConfig.CA_CERT_KEY); - Log.v("CA Cert String is " + certStr); - eConfig.setCaCertificate(strToX509Cert(certStr)); - } - if (j.has(WifiEnterpriseConfig.CLIENT_CERT_KEY) - && j.has(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY)) { - String certStr = j.getString(WifiEnterpriseConfig.CLIENT_CERT_KEY); - String keyStr = j.getString(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY); - Log.v("Client Cert String is " + certStr); - Log.v("Client Key String is " + keyStr); - X509Certificate cert = strToX509Cert(certStr); - PrivateKey privKey = strToPrivateKey(keyStr); - Log.v("Cert is " + cert); - Log.v("Private Key is " + privKey); - eConfig.setClientKeyEntry(privKey, cert); - } - if (j.has(WifiEnterpriseConfig.IDENTITY_KEY)) { - String identity = j.getString(WifiEnterpriseConfig.IDENTITY_KEY); - Log.v("Setting identity to " + identity); - eConfig.setIdentity(identity); - } - if (j.has(WifiEnterpriseConfig.PASSWORD_KEY)) { - String pwd = j.getString(WifiEnterpriseConfig.PASSWORD_KEY); - Log.v("Setting password to " + pwd); - eConfig.setPassword(pwd); - } - if (j.has(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY)) { - String altSub = j.getString(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY); - Log.v("Setting Alt Subject to " + altSub); - eConfig.setAltSubjectMatch(altSub); - } - if (j.has(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY)) { - String domSuffix = j.getString(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY); - Log.v("Setting Domain Suffix Match to " + domSuffix); - eConfig.setDomainSuffixMatch(domSuffix); - } - if (j.has(WifiEnterpriseConfig.REALM_KEY)) { - String realm = j.getString(WifiEnterpriseConfig.REALM_KEY); - Log.v("Setting Domain Suffix Match to " + realm); - eConfig.setRealm(realm); - } - config.enterpriseConfig = eConfig; - return config; - } - - private boolean matchScanResult(ScanResult result, String id) { - if (result.BSSID.equals(id) || result.SSID.equals(id)) { - return true; - } - return false; - } - - private WpsInfo parseWpsInfo(String infoStr) throws JSONException { - if (infoStr == null) { - return null; - } - JSONObject j = new JSONObject(infoStr); - WpsInfo info = new WpsInfo(); - if (j.has("setup")) { - info.setup = j.getInt("setup"); - } - if (j.has("BSSID")) { - info.BSSID = j.getString("BSSID"); - } - if (j.has("pin")) { - info.pin = j.getString("pin"); - } - return info; - } - - private byte[] base64StrToBytes(String input) { - return Base64.decode(input, Base64.DEFAULT); - } - - private X509Certificate strToX509Cert(String certStr) throws CertificateException { - byte[] certBytes = base64StrToBytes(certStr); - InputStream certStream = new ByteArrayInputStream(certBytes); - CertificateFactory cf = CertificateFactory.getInstance("X509"); - return (X509Certificate) cf.generateCertificate(certStream); - } - - private PrivateKey strToPrivateKey(String key) throws NoSuchAlgorithmException, - InvalidKeySpecException { - byte[] keyBytes = base64StrToBytes(key); - PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); - KeyFactory fact = KeyFactory.getInstance("RSA"); - PrivateKey priv = fact.generatePrivate(keySpec); - return priv; - } - - private PublicKey strToPublicKey(String key) throws NoSuchAlgorithmException, - InvalidKeySpecException { - byte[] keyBytes = base64StrToBytes(key); - X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); - KeyFactory fact = KeyFactory.getInstance("RSA"); - PublicKey pub = fact.generatePublic(keySpec); - return pub; - } - - private WifiConfiguration wifiConfigurationFromScanResult(ScanResult result) { - if (result == null) - return null; - WifiConfiguration config = new WifiConfiguration(); - config.SSID = "\"" + result.SSID + "\""; - applyingkeyMgmt(config, result); - config.BSSID = result.BSSID; - return config; - } - - @Rpc(description = "test.") - public String wifiTest(String certString) throws CertificateException, IOException { - // TODO(angli): Make this work. Convert a X509Certificate back to a string. - X509Certificate caCert = strToX509Cert(certString); - caCert.getEncoded(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutput out = new ObjectOutputStream(bos); - out.writeObject(caCert); - byte[] data = bos.toByteArray(); - bos.close(); - return Base64.encodeToString(data, Base64.DEFAULT); - } - - @Rpc(description = "Add a network.") - public Integer wifiAddNetwork(@RpcParameter(name = "wifiConfig") JSONObject wifiConfig) - throws JSONException { - return mWifi.addNetwork(genWifiConfig(wifiConfig)); - } - - @Rpc(description = "Builds a WifiConfiguration from Hotspot 2.0 MIME file.") - public WifiConfiguration wifiBuildConfig( - @RpcParameter(name = "uriString") String uriString, - @RpcParameter(name = "mimeType") String mimeType, - String dataString) - throws JSONException { - byte[] data = base64StrToBytes(dataString); - return mWifi.buildWifiConfig(uriString, mimeType, data); - } - - @Rpc(description = "Cancel Wi-fi Protected Setup.") - public void wifiCancelWps() throws JSONException { - WifiWpsCallback listener = new WifiWpsCallback(); - mWifi.cancelWps(listener); - } - - @Rpc(description = "Checks Wifi state.", returns = "True if Wifi is enabled.") - public Boolean wifiCheckState() { - return mWifi.getWifiState() == WifiManager.WIFI_STATE_ENABLED; - } - - /** - * Connects to a WPA protected wifi network - * - * @param wifiSSID SSID of the wifi network - * @param wifiPassword password for the wifi network - * @return true on success - * @throws ConnectException - * @throws JSONException - */ - @Rpc(description = "Connects a wifi network by ssid", returns = "True if the operation succeeded.") - public Boolean wifiConnect(@RpcParameter(name = "config") JSONObject config) - throws ConnectException, JSONException { - WifiConfiguration wifiConfig = genWifiConfig(config); - int nId = mWifi.addNetwork(wifiConfig); - if (nId < 0) { - Log.e("Got negative network Id."); - return false; - } - mWifi.disconnect(); - mWifi.enableNetwork(nId, true); - return mWifi.reconnect(); - } - - @Rpc(description = "Disconnects from the currently active access point.", returns = "True if the operation succeeded.") - public Boolean wifiDisconnect() { - return mWifi.disconnect(); - } - - @Rpc(description = "Enable/disable autojoin scan and switch network when connected.") - public Boolean wifiEnableAutoJoinWhenAssociated(@RpcParameter(name = "enable") Boolean enable) { - return mWifi.enableAutoJoinWhenAssociated(enable); - } - - @Rpc(description = "Enable a configured network. Initiate a connection if disableOthers is true", returns = "True if the operation succeeded.") - public Boolean wifiEnableNetwork(@RpcParameter(name = "netId") Integer netId, - @RpcParameter(name = "disableOthers") Boolean disableOthers) { - return mWifi.enableNetwork(netId, disableOthers); - } - - @Rpc(description = "Enable WiFi verbose logging.") - public void wifiEnableVerboseLogging(@RpcParameter(name = "level") Integer level) { - mWifi.enableVerboseLogging(level); - } - - @Rpc(description = "Connect to a wifi network that uses Enterprise authentication methods.") - public void wifiEnterpriseConnect(@RpcParameter(name = "config") JSONObject config) - throws JSONException, GeneralSecurityException { - // Create Certificate - WifiActionListener listener = new WifiActionListener(mEventFacade, "EnterpriseConnect"); - WifiConfiguration wifiConfig = genWifiEnterpriseConfig(config); - if (wifiConfig.isPasspoint()) { - Log.d("Got a passpoint config, add it and save config."); - mWifi.addNetwork(wifiConfig); - mWifi.saveConfiguration(); - } else { - Log.d("Got a non-passpoint enterprise config, connect directly."); - mWifi.connect(wifiConfig, listener); - } - } - - @Rpc(description = "Resets all WifiManager settings.") - public void wifiFactoryReset() { - mWifi.factoryReset(); - } - - /** - * Forget a wifi network with priority - * - * @param networkID Id of wifi network - */ - @Rpc(description = "Forget a wifi network with priority") - public void wifiForgetNetwork(@RpcParameter(name = "wifiSSID") Integer newtorkId) { - WifiActionListener listener = new WifiActionListener(mEventFacade, "ForgetNetwork"); - mWifi.forget(newtorkId, listener); - } - - @Rpc(description = "Gets the Wi-Fi AP Configuration.") - public WifiConfiguration wifiGetApConfiguration() { - return mWifi.getWifiApConfiguration(); - } - - @Rpc(description = "Returns the file in which IP and proxy configuration data is stored.") - public String wifiGetConfigFile() { - return mWifi.getConfigFile(); - } - - @Rpc(description = "Return a list of all the configured wifi networks.") - public List<WifiConfiguration> wifiGetConfiguredNetworks() { - return mWifi.getConfiguredNetworks(); - } - - @Rpc(description = "Returns information about the currently active access point.") - public WifiInfo wifiGetConnectionInfo() { - return mWifi.getConnectionInfo(); - } - - @Rpc(description = "Returns wifi activity and energy usage info.") - public WifiActivityEnergyInfo wifiGetControllerActivityEnergyInfo() { - return mWifi.getControllerActivityEnergyInfo(0); - } - - @Rpc(description = "Get the country code used by WiFi.") - public String wifiGetCountryCode() { - return mWifi.getCountryCode(); - } - - @Rpc(description = "Get the current network.") - public Network wifiGetCurrentNetwork() { - return mWifi.getCurrentNetwork(); - } - - @Rpc(description = "Get the info from last successful DHCP request.") - public DhcpInfo wifiGetDhcpInfo() { - return mWifi.getDhcpInfo(); - } - - @Rpc(description = "Get setting for Framework layer autojoin enable status.") - public Boolean wifiGetEnableAutoJoinWhenAssociated() { - return mWifi.getEnableAutoJoinWhenAssociated(); - } - - @Rpc(description = "Returns 1 if autojoin offload thru Wifi HAL layer is enabled, 0 otherwise.") - public Integer wifiGetHalBasedAutojoinOffload() { - return mWifi.getHalBasedAutojoinOffload(); - } - - @Rpc(description = "Get privileged configured networks.") - public List<WifiConfiguration> wifiGetPrivilegedConfiguredNetworks() { - return mWifi.getPrivilegedConfiguredNetworks(); - } - - @Rpc(description = "Returns the list of access points found during the most recent Wifi scan.") - public List<ScanResult> wifiGetScanResults() { - return mWifi.getScanResults(); - } - - @Rpc(description = "Get the current level of WiFi verbose logging.") - public Integer wifiGetVerboseLoggingLevel() { - return mWifi.getVerboseLoggingLevel(); - } - - @Rpc(description = "true if this adapter supports 5 GHz band.") - public Boolean wifiIs5GHzBandSupported() { - return mWifi.is5GHzBandSupported(); - } - - @Rpc(description = "true if this adapter supports multiple simultaneous connections.") - public Boolean wifiIsAdditionalStaSupported() { - return mWifi.isAdditionalStaSupported(); - } - - @Rpc(description = "Return whether Wi-Fi AP is enabled or disabled.") - public Boolean wifiIsApEnabled() { - return mWifi.isWifiApEnabled(); - } - - @Rpc(description = "Check if Device-to-AP RTT is supported.") - public Boolean wifiIsDeviceToApRttSupported() { - return mWifi.isDeviceToApRttSupported(); - } - - @Rpc(description = "Check if Device-to-device RTT is supported.") - public Boolean wifiIsDeviceToDeviceRttSupported() { - return mWifi.isDeviceToDeviceRttSupported(); - } - - @Rpc(description = "Check if the chipset supports dual frequency band (2.4 GHz and 5 GHz).") - public Boolean wifiIsDualBandSupported() { - return mWifi.isDualBandSupported(); - } - - @Rpc(description = "Check if this adapter supports advanced power/performance counters.") - public Boolean wifiIsEnhancedPowerReportingSupported() { - return mWifi.isEnhancedPowerReportingSupported(); - } - - @Rpc(description = "Check if multicast is enabled.") - public Boolean wifiIsMulticastEnabled() { - return mWifi.isMulticastEnabled(); - } - - @Rpc(description = "true if this adapter supports Neighbour Awareness Network APIs.") - public Boolean wifiIsNanSupported() { - return mWifi.isNanSupported(); - } - - @Rpc(description = "true if this adapter supports Off Channel Tunnel Directed Link Setup.") - public Boolean wifiIsOffChannelTdlsSupported() { - return mWifi.isOffChannelTdlsSupported(); - } - - @Rpc(description = "true if this adapter supports WifiP2pManager (Wi-Fi Direct).") - public Boolean wifiIsP2pSupported() { - return mWifi.isP2pSupported(); - } - - @Rpc(description = "true if this adapter supports passpoint.") - public Boolean wifiIsPasspointSupported() { - return mWifi.isPasspointSupported(); - } - - @Rpc(description = "true if this adapter supports portable Wi-Fi hotspot.") - public Boolean wifiIsPortableHotspotSupported() { - return mWifi.isPortableHotspotSupported(); - } - - @Rpc(description = "true if this adapter supports offloaded connectivity scan.") - public Boolean wifiIsPreferredNetworkOffloadSupported() { - return mWifi.isPreferredNetworkOffloadSupported(); - } - - @Rpc(description = "Check if wifi scanner is supported on this device.") - public Boolean wifiIsScannerSupported() { - return mWifi.isWifiScannerSupported(); - } - - @Rpc(description = "Check if tdls is supported on this device.") - public Boolean wifiIsTdlsSupported() { - return mWifi.isTdlsSupported(); - } - - @Rpc(description = "Acquires a full Wifi lock.") - public void wifiLockAcquireFull() { - makeLock(WifiManager.WIFI_MODE_FULL); - } - - @Rpc(description = "Acquires a scan only Wifi lock.") - public void wifiLockAcquireScanOnly() { - makeLock(WifiManager.WIFI_MODE_SCAN_ONLY); - } - - @Rpc(description = "Releases a previously acquired Wifi lock.") - public void wifiLockRelease() { - if (mLock != null) { - mLock.release(); - mLock = null; - } - } - - /** - * Connects to a wifi network with priority - * - * @param wifiSSID SSID of the wifi network - * @param wifiPassword password for the wifi network - * @throws JSONException - */ - @Rpc(description = "Connects a wifi network as priority by pasing ssid") - public void wifiPriorityConnect(@RpcParameter(name = "config") JSONObject config) - throws JSONException { - WifiConfiguration wifiConfig = genWifiConfig(config); - WifiActionListener listener = new WifiActionListener(mEventFacade, "PriorityConnect"); - mWifi.connect(wifiConfig, listener); - } - - @Rpc(description = "Reassociates with the currently active access point.", returns = "True if the operation succeeded.") - public Boolean wifiReassociate() { - return mWifi.reassociate(); - } - - @Rpc(description = "Reconnects to the currently active access point.", returns = "True if the operation succeeded.") - public Boolean wifiReconnect() { - return mWifi.reconnect(); - } - - @Rpc(description = "Remove a configured network.", returns = "True if the operation succeeded.") - public Boolean wifiRemoveNetwork(@RpcParameter(name = "netId") Integer netId) { - return mWifi.removeNetwork(netId); - } - - @Rpc(description = "Start/stop wifi soft AP.") - public Boolean wifiSetApEnabled( - @RpcParameter(name = "enable") Boolean enable, - @RpcParameter(name = "configJson") JSONObject configJson) throws JSONException { - int wifiState = mWifi.getWifiState(); - if (enable) { - if ((wifiState == WifiManager.WIFI_STATE_ENABLING) || - (wifiState == WifiManager.WIFI_STATE_ENABLED)) { - mWifi.setWifiEnabled(false); - } - WifiConfiguration config = genWifiConfig(configJson); - // Need to strip of extra quotation marks for SSID and password. - String ssid = config.SSID; - if (ssid != null) { - config.SSID = ssid.substring(1, ssid.length() - 1); - } - String pwd = config.preSharedKey; - if (pwd != null) { - config.preSharedKey = pwd.substring(1, pwd.length() - 1); - } - return mWifi.setWifiApEnabled(config, enable); - } else { - return mWifi.setWifiApEnabled(null, false); - } - } - - @Rpc(description = "Set the country code used by WiFi.") - public void wifiSetCountryCode( - @RpcParameter(name = "country") String country, - @RpcParameter(name = "persist") Boolean persist) { - mWifi.setCountryCode(country, persist); - } - - @Rpc(description = "Enable/disable autojoin offload through Wifi HAL layer.") - public void wifiSetHalBasedAutojoinOffload( - @RpcParameter(name = "enable") Integer enable) { - mWifi.setHalBasedAutojoinOffload(enable); - } - - @Rpc(description = "Enable/disable tdls with a mac address.") - public void wifiSetTdlsEnabledWithMacAddress( - @RpcParameter(name = "remoteMacAddress") String remoteMacAddress, - @RpcParameter(name = "enable") Boolean enable) { - mWifi.setTdlsEnabledWithMacAddress(remoteMacAddress, enable); - } - - @Rpc(description = "Starts a scan for Wifi access points.", returns = "True if the scan was initiated successfully.") - public Boolean wifiStartScan() { - mService.registerReceiver(mScanResultsAvailableReceiver, mScanFilter); - return mWifi.startScan(); - } - - @Rpc(description = "Start Wi-fi Protected Setup.") - public void wifiStartWps( - @RpcParameter(name = "config", description = "A json string with fields \"setup\", \"BSSID\", and \"pin\"") String config) - throws JSONException { - WpsInfo info = parseWpsInfo(config); - WifiWpsCallback listener = new WifiWpsCallback(); - Log.d("Starting wps with: " + info); - mWifi.startWps(info, listener); - } - - @Rpc(description = "Start listening for wifi state change related broadcasts.") - public void wifiStartTrackingStateChange() { - mService.registerReceiver(mStateChangeReceiver, mStateChangeFilter); - mService.registerReceiver(mTetherStateReceiver, mTetherFilter); - mTrackingWifiStateChange = true; - } - - @Rpc(description = "Stop listening for wifi state change related broadcasts.") - public void wifiStopTrackingStateChange() { - if (mTrackingWifiStateChange == true) { - mService.unregisterReceiver(mTetherStateReceiver); - mService.unregisterReceiver(mStateChangeReceiver); - mTrackingWifiStateChange = false; - } - } - - @Rpc(description = "Toggle Wifi on and off.", returns = "True if Wifi is enabled.") - public Boolean wifiToggleState(@RpcParameter(name = "enabled") @RpcOptional Boolean enabled) { - if (enabled == null) { - enabled = !wifiCheckState(); - } - mWifi.setWifiEnabled(enabled); - return enabled; - } - - @Rpc(description = "Toggle Wifi scan always available on and off.", returns = "True if Wifi scan is always available.") - public Boolean wifiToggleScanAlwaysAvailable( - @RpcParameter(name = "enabled") @RpcOptional Boolean enabled) - throws SettingNotFoundException { - ContentResolver cr = mService.getContentResolver(); - int isSet = 0; - if (enabled == null) { - isSet = Global.getInt(cr, Global.WIFI_SCAN_ALWAYS_AVAILABLE); - isSet ^= 1; - } else if (enabled == true) { - isSet = 1; - } - Global.putInt(cr, Global.WIFI_SCAN_ALWAYS_AVAILABLE, isSet); - if (isSet == 1) { - return true; - } - return false; - } - - @Override - public void shutdown() { - wifiLockRelease(); - if (mTrackingWifiStateChange == true) { - wifiStopTrackingStateChange(); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiNanManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiNanManagerFacade.java deleted file mode 100644 index 5863e8d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiNanManagerFacade.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * 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 com.googlecode.android_scripting.facade.wifi; - -import android.app.Service; -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.wifi.nan.ConfigRequest; -import android.net.wifi.nan.PublishData; -import android.net.wifi.nan.PublishSettings; -import android.net.wifi.nan.SubscribeData; -import android.net.wifi.nan.SubscribeSettings; -import android.net.wifi.nan.TlvBufferUtils; -import android.net.wifi.nan.WifiNanEventListener; -import android.net.wifi.nan.WifiNanManager; -import android.net.wifi.nan.WifiNanSession; -import android.net.wifi.nan.WifiNanSessionListener; -import android.os.Bundle; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.RemoteException; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * WifiNanManager functions. - */ -public class WifiNanManagerFacade extends RpcReceiver { - private final Service mService; - private final EventFacade mEventFacade; - - private WifiNanManager mMgr; - private WifiNanSession mSession; - private HandlerThread mNanFacadeThread; - private ConnectivityManager mConnMgr; - - private static TlvBufferUtils.TlvConstructor getFilterData(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - TlvBufferUtils.TlvConstructor constructor = new TlvBufferUtils.TlvConstructor(0, 1); - constructor.allocate(255); - - if (j.has("int0")) { - constructor.putShort(0, (short) j.getInt("int0")); - } - - if (j.has("int1")) { - constructor.putShort(0, (short) j.getInt("int1")); - } - - if (j.has("data0")) { - constructor.putString(0, j.getString("data0")); - } - - if (j.has("data1")) { - constructor.putString(0, j.getString("data1")); - } - - return constructor; - } - - private static ConfigRequest getConfigRequest(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - ConfigRequest.Builder builder = new ConfigRequest.Builder(); - - if (j.has("Support5gBand")) { - builder.setSupport5gBand(j.getBoolean("Support5gBand")); - } - if (j.has("MasterPreference")) { - builder.setMasterPreference(j.getInt("MasterPreference")); - } - if (j.has("ClusterLow")) { - builder.setClusterLow(j.getInt("ClusterLow")); - } - if (j.has("ClusterHigh")) { - builder.setClusterHigh(j.getInt("ClusterHigh")); - } - - return builder.build(); - } - - private static PublishData getPublishData(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - PublishData.Builder builder = new PublishData.Builder(); - - if (j.has("ServiceName")) { - builder.setServiceName(j.getString("ServiceName")); - } - - if (j.has("ServiceSpecificInfo")) { - String ssi = j.getString("ServiceSpecificInfo"); - builder.setServiceSpecificInfo(ssi.getBytes(), ssi.length()); - } - - if (j.has("TxFilter")) { - TlvBufferUtils.TlvConstructor constructor = getFilterData(j.getJSONObject("TxFilter")); - builder.setTxFilter(constructor.getArray(), constructor.getActualLength()); - } - - if (j.has("RxFilter")) { - TlvBufferUtils.TlvConstructor constructor = getFilterData(j.getJSONObject("RxFilter")); - builder.setRxFilter(constructor.getArray(), constructor.getActualLength()); - } - - return builder.build(); - } - - private static PublishSettings getPublishSettings(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - PublishSettings.Builder builder = new PublishSettings.Builder(); - - if (j.has("PublishType")) { - builder.setPublishType(j.getInt("PublishType")); - } - if (j.has("PublishCount")) { - builder.setPublishCount(j.getInt("PublishCount")); - } - if (j.has("TtlSec")) { - builder.setTtlSec(j.getInt("TtlSec")); - } - - return builder.build(); - } - - private static SubscribeData getSubscribeData(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - SubscribeData.Builder builder = new SubscribeData.Builder(); - - if (j.has("ServiceName")) { - builder.setServiceName(j.getString("ServiceName")); - } - - if (j.has("ServiceSpecificInfo")) { - String ssi = j.getString("ServiceSpecificInfo"); - builder.setServiceSpecificInfo(ssi); - } - - if (j.has("TxFilter")) { - TlvBufferUtils.TlvConstructor constructor = getFilterData(j.getJSONObject("TxFilter")); - builder.setTxFilter(constructor.getArray(), constructor.getActualLength()); - } - - if (j.has("RxFilter")) { - TlvBufferUtils.TlvConstructor constructor = getFilterData(j.getJSONObject("RxFilter")); - builder.setRxFilter(constructor.getArray(), constructor.getActualLength()); - } - - return builder.build(); - } - - private static SubscribeSettings getSubscribeSettings(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - - SubscribeSettings.Builder builder = new SubscribeSettings.Builder(); - - if (j.has("SubscribeType")) { - builder.setSubscribeType(j.getInt("SubscribeType")); - } - if (j.has("SubscribeCount")) { - builder.setSubscribeCount(j.getInt("SubscribeCount")); - } - if (j.has("TtlSec")) { - builder.setTtlSec(j.getInt("TtlSec")); - } - - return builder.build(); - } - - public WifiNanManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - - mNanFacadeThread = new HandlerThread("nanFacadeThread"); - mNanFacadeThread.start(); - - mMgr = (WifiNanManager) mService.getSystemService(Context.WIFI_NAN_SERVICE); - mMgr.connect(new NanEventListenerPostsEvents(mNanFacadeThread.getLooper()), - WifiNanEventListener.LISTEN_CONFIG_COMPLETED - | WifiNanEventListener.LISTEN_CONFIG_FAILED - | WifiNanEventListener.LISTEN_NAN_DOWN - | WifiNanEventListener.LISTEN_IDENTITY_CHANGED); - - mConnMgr = (ConnectivityManager) mService.getSystemService(Context.CONNECTIVITY_SERVICE); - - mEventFacade = manager.getReceiver(EventFacade.class); - } - - @Override - public void shutdown() { - } - - @Rpc(description = "Start NAN.") - public void wifiNanEnable(@RpcParameter(name = "nanConfig") JSONObject nanConfig) - throws RemoteException, JSONException { - mMgr.requestConfig(getConfigRequest(nanConfig)); - } - - @Rpc(description = "Stop NAN.") - public void wifiNanDisable() throws RemoteException, JSONException { - mMgr.disconnect(); - } - - @Rpc(description = "Publish.") - public void wifiNanPublish(@RpcParameter(name = "publishData") JSONObject publishData, - @RpcParameter(name = "publishSettings") JSONObject publishSettings, - @RpcParameter(name = "listenerId") Integer listenerId) - throws RemoteException, JSONException { - mSession = mMgr.publish(getPublishData(publishData), getPublishSettings(publishSettings), - new NanSessionListenerPostsEvents(mNanFacadeThread.getLooper(), listenerId), - WifiNanSessionListener.LISTEN_PUBLISH_FAIL - | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED - | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL - | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED - | WifiNanSessionListener.LISTEN_MATCH - | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS - | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL - | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED); - } - - @Rpc(description = "Subscribe.") - public void wifiNanSubscribe(@RpcParameter(name = "subscribeData") JSONObject subscribeData, - @RpcParameter(name = "subscribeSettings") JSONObject subscribeSettings, - @RpcParameter(name = "listenerId") Integer listenerId) - throws RemoteException, JSONException { - - mSession = mMgr.subscribe(getSubscribeData(subscribeData), - getSubscribeSettings(subscribeSettings), - new NanSessionListenerPostsEvents(mNanFacadeThread.getLooper(), listenerId), - WifiNanSessionListener.LISTEN_PUBLISH_FAIL - | WifiNanSessionListener.LISTEN_PUBLISH_TERMINATED - | WifiNanSessionListener.LISTEN_SUBSCRIBE_FAIL - | WifiNanSessionListener.LISTEN_SUBSCRIBE_TERMINATED - | WifiNanSessionListener.LISTEN_MATCH - | WifiNanSessionListener.LISTEN_MESSAGE_SEND_SUCCESS - | WifiNanSessionListener.LISTEN_MESSAGE_SEND_FAIL - | WifiNanSessionListener.LISTEN_MESSAGE_RECEIVED); - } - - @Rpc(description = "Send peer-to-peer NAN message") - public void wifiNanSendMessage( - @RpcParameter(name = "peerId", description = "The ID of the peer being communicated " - + "with. Obtained from a previous message or match session.") Integer peerId, - @RpcParameter(name = "message") String message, - @RpcParameter(name = "messageId", description = "Arbitrary handle used for " - + "identification of the message in the message status callbacks") - Integer messageId) - throws RemoteException { - mSession.sendMessage(peerId, message.getBytes(), message.length(), messageId); - } - - private class NanEventListenerPostsEvents extends WifiNanEventListener { - public NanEventListenerPostsEvents(Looper looper) { - super(looper); - } - - @Override - public void onConfigCompleted(ConfigRequest configRequest) { - Bundle mResults = new Bundle(); - mResults.putParcelable("configRequest", configRequest); - mEventFacade.postEvent("WifiNanOnConfigCompleted", mResults); - } - - @Override - public void onConfigFailed(ConfigRequest failedConfig, int reason) { - Bundle mResults = new Bundle(); - mResults.putParcelable("failedConfig", failedConfig); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanOnConfigFailed", mResults); - } - - @Override - public void onNanDown(int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanOnNanDown", mResults); - } - - @Override - public void onIdentityChanged() { - Bundle mResults = new Bundle(); - mEventFacade.postEvent("WifiNanOnIdentityChanged", mResults); - } - } - - private class NanSessionListenerPostsEvents extends WifiNanSessionListener { - private int mListenerId; - - public NanSessionListenerPostsEvents(Looper looper, int listenerId) { - super(looper); - mListenerId = listenerId; - } - - @Override - public void onPublishFail(int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanSessionOnPublishFail", mResults); - } - - @Override - public void onPublishTerminated(int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanSessionOnPublishTerminated", mResults); - } - - @Override - public void onSubscribeFail(int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanSessionOnSubscribeFail", mResults); - } - - @Override - public void onSubscribeTerminated(int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanSessionOnSubscribeTerminated", mResults); - } - - @Override - public void onMatch(int peerId, byte[] serviceSpecificInfo, - int serviceSpecificInfoLength, byte[] matchFilter, int matchFilterLength) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("peerId", peerId); - mResults.putInt("serviceSpecificInfoLength", serviceSpecificInfoLength); - mResults.putByteArray("serviceSpecificInfo", serviceSpecificInfo); // TODO: base64 - mResults.putInt("matchFilterLength", matchFilterLength); - mResults.putByteArray("matchFilter", matchFilter); // TODO: base64 - mEventFacade.postEvent("WifiNanSessionOnMatch", mResults); - } - - @Override - public void onMessageSendSuccess(int messageId) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("messageId", messageId); - mEventFacade.postEvent("WifiNanSessionOnMessageSendSuccess", mResults); - } - - @Override - public void onMessageSendFail(int messageId, int reason) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("messageId", messageId); - mResults.putInt("reason", reason); - mEventFacade.postEvent("WifiNanSessionOnMessageSendFail", mResults); - } - - @Override - public void onMessageReceived(int peerId, byte[] message, int messageLength) { - Bundle mResults = new Bundle(); - mResults.putInt("listenerId", mListenerId); - mResults.putInt("peerId", peerId); - mResults.putInt("messageLength", messageLength); - mResults.putByteArray("message", message); // TODO: base64 - mResults.putString("messageAsString", new String(message, 0, messageLength)); - mEventFacade.postEvent("WifiNanSessionOnMessageReceived", mResults); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java deleted file mode 100644 index d0514b9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiP2pManagerFacade.java +++ /dev/null @@ -1,506 +0,0 @@ - -package com.googlecode.android_scripting.facade.wifi; - -import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.NetworkInfo; -import android.net.wifi.WpsInfo; -import android.net.wifi.p2p.WifiP2pConfig; -import android.net.wifi.p2p.WifiP2pDevice; -import android.net.wifi.p2p.WifiP2pDeviceList; -import android.net.wifi.p2p.WifiP2pGroup; -import android.net.wifi.p2p.WifiP2pGroupList; -import android.net.wifi.p2p.WifiP2pInfo; -import android.net.wifi.p2p.WifiP2pManager; -import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo; -import android.net.wifi.p2p.nsd.WifiP2pServiceInfo; -import android.net.wifi.p2p.nsd.WifiP2pServiceRequest; -import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.os.RemoteException; - -import com.android.internal.util.Protocol; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * WifiP2pManager functions. - */ -public class WifiP2pManagerFacade extends RpcReceiver { - - class WifiP2pActionListener implements WifiP2pManager.ActionListener { - private final EventFacade mEventFacade; - private final String mEventType; - private final String TAG; - - public WifiP2pActionListener(EventFacade eventFacade, String tag) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - TAG = tag; - } - - @Override - public void onSuccess() { - mEventFacade.postEvent(mEventType + TAG + "OnSuccess", null); - } - - @Override - public void onFailure(int reason) { - Log.d("WifiActionListener " + mEventType); - Bundle msg = new Bundle(); - if (reason == WifiP2pManager.P2P_UNSUPPORTED) { - msg.putString("reason", "P2P_UNSUPPORTED"); - } else if (reason == WifiP2pManager.ERROR) { - msg.putString("reason", "ERROR"); - } else if (reason == WifiP2pManager.BUSY) { - msg.putString("reason", "BUSY"); - } else if (reason == WifiP2pManager.NO_SERVICE_REQUESTS) { - msg.putString("reason", "NO_SERVICE_REQUESTS"); - } else { - msg.putInt("reason", reason); - } - mEventFacade.postEvent(mEventType + TAG + "OnFailure", msg); - } - } - - class WifiP2pConnectionInfoListener implements WifiP2pManager.ConnectionInfoListener { - private final EventFacade mEventFacade; - private final String mEventType; - - public WifiP2pConnectionInfoListener(EventFacade eventFacade) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - } - - @Override - public void onConnectionInfoAvailable(WifiP2pInfo info) { - Bundle msg = new Bundle(); - msg.putBoolean("groupFormed", info.groupFormed); - msg.putBoolean("isGroupOwner", info.isGroupOwner); - InetAddress addr = info.groupOwnerAddress; - String hostName = null; - String hostAddress = null; - if (addr != null) { - hostName = addr.getHostName(); - hostAddress = addr.getHostAddress(); - } - msg.putString("groupOwnerHostName", hostName); - msg.putString("groupOwnerHostAddress", hostAddress); - mEventFacade.postEvent(mEventType + "OnConnectionInfoAvailable", msg); - } - } - - class WifiP2pDnsSdServiceResponseListener implements - WifiP2pManager.DnsSdServiceResponseListener { - private final EventFacade mEventFacade; - private final String mEventType; - - public WifiP2pDnsSdServiceResponseListener(EventFacade eventFacade) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - } - - @Override - public void onDnsSdServiceAvailable(String instanceName, String registrationType, - WifiP2pDevice srcDevice) { - Bundle msg = new Bundle(); - msg.putString("InstanceName", instanceName); - msg.putString("RegistrationType", registrationType); - msg.putString("SourceDeviceName", srcDevice.deviceName); - msg.putString("SourceDeviceAddress", srcDevice.deviceAddress); - mEventFacade.postEvent(mEventType + "OnDnsSdServiceAvailable", msg); - } - } - - class WifiP2pDnsSdTxtRecordListener implements WifiP2pManager.DnsSdTxtRecordListener { - private final EventFacade mEventFacade; - private final String mEventType; - - public WifiP2pDnsSdTxtRecordListener(EventFacade eventFacade) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - } - - @Override - public void onDnsSdTxtRecordAvailable(String fullDomainName, - Map<String, String> txtRecordMap, WifiP2pDevice srcDevice) { - Bundle msg = new Bundle(); - msg.putString("FullDomainName", fullDomainName); - Bundle txtMap = new Bundle(); - for (String key : txtRecordMap.keySet()) { - txtMap.putString(key, txtRecordMap.get(key)); - } - msg.putBundle("TxtRecordMap", txtMap); - msg.putString("SourceDeviceName", srcDevice.deviceName); - msg.putString("SourceDeviceAddress", srcDevice.deviceAddress); - mEventFacade.postEvent(mEventType + "OnDnsSdTxtRecordAvailable", msg); - } - - } - - class WifiP2pGroupInfoListener implements WifiP2pManager.GroupInfoListener { - private final EventFacade mEventFacade; - private final String mEventType; - - public WifiP2pGroupInfoListener(EventFacade eventFacade) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - } - - @Override - public void onGroupInfoAvailable(WifiP2pGroup group) { - mEventFacade.postEvent(mEventType + "OnGroupInfoAvailable", parseGroupInfo(group)); - } - } - - class WifiP2pPeerListListener implements WifiP2pManager.PeerListListener { - private final EventFacade mEventFacade; - - public WifiP2pPeerListListener(EventFacade eventFacade) { - mEventFacade = eventFacade; - } - - @Override - public void onPeersAvailable(WifiP2pDeviceList newPeers) { - Collection<WifiP2pDevice> devices = newPeers.getDeviceList(); - Log.d(devices.toString()); - if (devices.size() > 0) { - mP2pPeers.clear(); - mP2pPeers.addAll(devices); - Bundle msg = new Bundle(); - msg.putParcelableList("Peers", mP2pPeers); - mEventFacade.postEvent(mEventType + "OnPeersAvailable", msg); - } - } - } - - class WifiP2pPersistentGroupInfoListener implements WifiP2pManager.PersistentGroupInfoListener { - private final EventFacade mEventFacade; - private final String mEventType; - - public WifiP2pPersistentGroupInfoListener(EventFacade eventFacade) { - mEventType = "WifiP2p"; - mEventFacade = eventFacade; - } - - @Override - public void onPersistentGroupInfoAvailable(WifiP2pGroupList groups) { - ArrayList<Bundle> gs = new ArrayList<Bundle>(); - for (WifiP2pGroup g : groups.getGroupList()) { - gs.add(parseGroupInfo(g)); - } - mEventFacade.postEvent(mEventType + "OnPersistentGroupInfoAvailable", gs); - } - - } - - class WifiP2pStateChangedReceiver extends BroadcastReceiver { - private final EventFacade mEventFacade; - private final Bundle mResults; - - WifiP2pStateChangedReceiver(EventFacade eventFacade) { - mEventFacade = eventFacade; - mResults = new Bundle(); - } - - @Override - public void onReceive(Context c, Intent intent) { - String action = intent.getAction(); - if (action.equals(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)) { - Log.d("Wifi P2p State Changed."); - int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, 0); - if (state == WifiP2pManager.WIFI_P2P_STATE_DISABLED) { - Log.d("Disabled"); - isP2pEnabled = false; - } else if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { - Log.d("Enabled"); - isP2pEnabled = true; - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)) { - Log.d("Wifi P2p Peers Changed. Requesting peers."); - WifiP2pDeviceList peers = intent - .getParcelableExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST); - Log.d(peers.toString()); - wifiP2pRequestPeers(); - } else if (action.equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) { - Log.d("Wifi P2p Connection Changed."); - WifiP2pInfo p2pInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO); - NetworkInfo networkInfo = intent - .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); - WifiP2pGroup group = intent.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP); - if (networkInfo.isConnected()) { - Log.d("Wifi P2p Connected."); - mResults.putParcelable("P2pInfo", p2pInfo); - mResults.putParcelable("Group", group); - mEventFacade.postEvent(mEventType + "Connected", mResults); - mResults.clear(); - } else { - mEventFacade.postEvent(mEventType + "Disconnected", null); - } - } else if (action.equals(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)) { - Log.d("Wifi P2p This Device Changed."); - WifiP2pDevice device = intent - .getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE); - mResults.putParcelable("Device", device); - mEventFacade.postEvent(mEventType + "ThisDeviceChanged", mResults); - mResults.clear(); - } else if (action.equals(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)) { - Log.d("Wifi P2p Discovery Changed."); - int state = intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, 0); - if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED) { - Log.d("discovery started."); - } else if (state == WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED) { - Log.d("discovery stoped."); - } - } - } - } - - private final static String mEventType = "WifiP2p"; - - private WifiP2pManager.Channel mChannel; - private final EventFacade mEventFacade; - private final WifiP2pManager mP2p; - private final WifiP2pStateChangedReceiver mP2pStateChangedReceiver; - private final Service mService; - private final IntentFilter mStateChangeFilter; - private final Map<Integer, WifiP2pServiceRequest> mServiceRequests; - - private boolean isP2pEnabled; - private int mServiceRequestCnt = 0; - private WifiP2pServiceInfo mServiceInfo = null; - private List<WifiP2pDevice> mP2pPeers = new ArrayList<WifiP2pDevice>(); - - public WifiP2pManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mP2p = (WifiP2pManager) mService.getSystemService(Context.WIFI_P2P_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - - mStateChangeFilter = new IntentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); - mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); - mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); - mStateChangeFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); - mStateChangeFilter.setPriority(999); - - mP2pStateChangedReceiver = new WifiP2pStateChangedReceiver(mEventFacade); - mServiceRequests = new HashMap<Integer, WifiP2pServiceRequest>(); - } - - public Bundle parseGroupInfo(WifiP2pGroup group) { - Bundle msg = new Bundle(); - msg.putString("Interface", group.getInterface()); - msg.putString("NetworkName", group.getNetworkName()); - msg.putString("Passphrase", group.getPassphrase()); - msg.putInt("NetworkId", group.getNetworkId()); - msg.putString("OwnerName", group.getOwner().deviceName); - msg.putString("OwnerAddress", group.getOwner().deviceAddress); - return msg; - } - - @Override - public void shutdown() { - mService.unregisterReceiver(mP2pStateChangedReceiver); - } - - @Rpc(description = "Accept p2p connection invitation.") - public void wifiP2pAcceptConnection() throws RemoteException { - Log.d("Accepting p2p connection."); - Messenger m = mP2p.getP2pStateMachineMessenger(); - int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 2; - Message msg = Message.obtain(); - msg.what = user_accept; - m.send(msg); - } - - @Rpc(description = "Reject p2p connection invitation.") - public void wifiP2pRejectConnection() throws RemoteException { - Log.d("Rejecting p2p connection."); - Messenger m = mP2p.getP2pStateMachineMessenger(); - int user_accept = Protocol.BASE_WIFI_P2P_SERVICE + 3; - Message msg = Message.obtain(); - msg.what = user_accept; - m.send(msg); - } - - @Rpc(description = "Register a local service for service discovery. One of the \"CreateXxxServiceInfo functions needs to be called first.\"") - public void wifiP2pAddLocalService() { - mP2p.addLocalService(mChannel, mServiceInfo, - new WifiP2pActionListener(mEventFacade, "AddLocalService")); - } - - @Rpc(description = "Add a service discovery request.") - public Integer wifiP2pAddServiceRequest( - @RpcParameter(name = "protocolType") Integer protocolType) { - WifiP2pServiceRequest request = WifiP2pServiceRequest.newInstance(protocolType); - mServiceRequestCnt += 1; - mServiceRequests.put(mServiceRequestCnt, request); - mP2p.addServiceRequest(mChannel, request, new WifiP2pActionListener(mEventFacade, - "AddServiceRequest")); - return mServiceRequestCnt; - } - - @Rpc(description = "Cancel any ongoing connect negotiation.") - public void wifiP2pCancelConnect() { - mP2p.cancelConnect(mChannel, new WifiP2pActionListener(mEventFacade, "CancelConnect")); - } - - @Rpc(description = "Clear all registered local services of service discovery.") - public void wifiP2pClearLocalServices() { - mP2p.clearLocalServices(mChannel, - new WifiP2pActionListener(mEventFacade, "ClearLocalServices")); - } - - @Rpc(description = "Clear all registered service discovery requests.") - public void wifiP2pClearServiceRequests() { - mP2p.clearServiceRequests(mChannel, - new WifiP2pActionListener(mEventFacade, "ClearServiceRequests")); - } - - @Rpc(description = "Connects to a discovered wifi p2p device.") - public void wifiP2pConnect(@RpcParameter(name = "deviceId") String deviceId) { - for (WifiP2pDevice d : mP2pPeers) { - if (wifiP2pDeviceMatches(d, deviceId)) { - WifiP2pConfig config = new WifiP2pConfig(); - config.deviceAddress = d.deviceAddress; - config.wps.setup = WpsInfo.PBC; - mP2p.connect(mChannel, config, - new WifiP2pActionListener(mEventFacade, "Connect")); - } - } - } - - @Rpc(description = "Create a Bonjour service info object to be used for wifiP2pAddLocalService.") - public void wifiP2pCreateBonjourServiceInfo( - @RpcParameter(name = "instanceName") String instanceName, - @RpcParameter(name = "serviceType") String serviceType, - @RpcParameter(name = "txtMap") JSONObject txtMap) throws JSONException { - Map<String, String> map = new HashMap<String, String>(); - for (String key : txtMap.keySet()) { - map.put(key, txtMap.getString(key)); - } - mServiceInfo = WifiP2pDnsSdServiceInfo.newInstance(instanceName, serviceType, map); - } - - @Rpc(description = "Create a wifi p2p group.") - public void wifiP2pCreateGroup() { - mP2p.createGroup(mChannel, new WifiP2pActionListener(mEventFacade, "CreatGroup")); - } - - @Rpc(description = "Create a Upnp service info object to be used for wifiP2pAddLocalService.") - public void wifiP2pCreateUpnpServiceInfo( - @RpcParameter(name = "uuid") String uuid, - @RpcParameter(name = "device") String device, - @RpcParameter(name = "services") List<String> services) { - mServiceInfo = WifiP2pUpnpServiceInfo.newInstance(uuid, device, services); - } - - @Rpc(description = "Delete a stored persistent group from the system settings.") - public void wifiP2pDeletePersistentGroup(@RpcParameter(name = "netId") Integer netId) { - mP2p.deletePersistentGroup(mChannel, netId, - new WifiP2pActionListener(mEventFacade, "DeletePersistentGroup")); - } - - private boolean wifiP2pDeviceMatches(WifiP2pDevice d, String deviceId) { - return d.deviceName.equals(deviceId) || d.deviceAddress.equals(deviceId); - } - - @Rpc(description = "Start peers discovery for wifi p2p.") - public void wifiP2pDiscoverPeers() { - mP2p.discoverPeers(mChannel, new WifiP2pActionListener(mEventFacade, "DiscoverPeers")); - } - - @Rpc(description = "Initiate service discovery.") - public void wifiP2pDiscoverServices() { - mP2p.discoverServices(mChannel, - new WifiP2pActionListener(mEventFacade, "DiscoverServices")); - } - - @Rpc(description = "Initialize wifi p2p. Must be called before any other p2p functions.") - public void wifiP2pInitialize() { - mService.registerReceiver(mP2pStateChangedReceiver, mStateChangeFilter); - mChannel = mP2p.initialize(mService, mService.getMainLooper(), null); - } - - @Rpc(description = "Returns true if wifi p2p is enabled, false otherwise.") - public Boolean wifiP2pIsEnabled() { - return isP2pEnabled; - } - - @Rpc(description = "Remove the current p2p group.") - public void wifiP2pRemoveGroup() { - mP2p.removeGroup(mChannel, new WifiP2pActionListener(mEventFacade, "RemoveGroup")); - } - - @Rpc(description = "Remove a registered local service added with wifiP2pAddLocalService.") - public void wifiP2pRemoveLocalService() { - mP2p.removeLocalService(mChannel, mServiceInfo, - new WifiP2pActionListener(mEventFacade, "RemoveLocalService")); - } - - @Rpc(description = "Remove a service discovery request.") - public void wifiP2pRemoveServiceRequest(@RpcParameter(name = "index") Integer index) { - mP2p.removeServiceRequest(mChannel, mServiceRequests.remove(index), - new WifiP2pActionListener(mEventFacade, "RemoveServiceRequest")); - } - - @Rpc(description = "Request device connection info.") - public void wifiP2pRequestConnectionInfo() { - mP2p.requestConnectionInfo(mChannel, new WifiP2pConnectionInfoListener(mEventFacade)); - } - - @Rpc(description = "Create a wifi p2p group.") - public void wifiP2pRequestGroupInfo() { - mP2p.requestGroupInfo(mChannel, new WifiP2pGroupInfoListener(mEventFacade)); - } - - @Rpc(description = "Request peers that are discovered for wifi p2p.") - public void wifiP2pRequestPeers() { - mP2p.requestPeers(mChannel, new WifiP2pPeerListListener(mEventFacade)); - } - - @Rpc(description = "Request a list of all the persistent p2p groups stored in system.") - public void wifiP2pRequestPersistentGroupInfo() { - mP2p.requestPersistentGroupInfo(mChannel, - new WifiP2pPersistentGroupInfoListener(mEventFacade)); - } - - @Rpc(description = "Set p2p device name.") - public void wifiP2pSetDeviceName(@RpcParameter(name = "devName") String devName) { - mP2p.setDeviceName(mChannel, devName, - new WifiP2pActionListener(mEventFacade, "SetDeviceName")); - } - - @Rpc(description = "Register a callback to be invoked on receiving Bonjour service discovery response.") - public void wifiP2pSetDnsSdResponseListeners() { - mP2p.setDnsSdResponseListeners(mChannel, - new WifiP2pDnsSdServiceResponseListener(mEventFacade), - new WifiP2pDnsSdTxtRecordListener(mEventFacade)); - } - - @Rpc(description = "Stop an ongoing peer discovery.") - public void wifiP2pStopPeerDiscovery() { - mP2p.stopPeerDiscovery(mChannel, - new WifiP2pActionListener(mEventFacade, "StopPeerDiscovery")); - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java deleted file mode 100644 index b4bf1e1..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiRttManagerFacade.java +++ /dev/null @@ -1,210 +0,0 @@ - -package com.googlecode.android_scripting.facade.wifi; - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Map; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.app.Service; -import android.content.Context; -import android.net.wifi.RttManager; -import android.net.wifi.RttManager.RttCapabilities; -import android.net.wifi.RttManager.RttListener; -import android.net.wifi.RttManager.RttParams; -import android.net.wifi.RttManager.RttResult; -import android.os.Bundle; -import android.os.Parcelable; - -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * WifiRttManager functions. - */ -public class WifiRttManagerFacade extends RpcReceiver { - private final Service mService; - private final RttManager mRtt; - private final EventFacade mEventFacade; - private final Map<Integer, RttListener> mRangingListeners; - - public WifiRttManagerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mRtt = (RttManager) mService.getSystemService(Context.WIFI_RTT_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - mRangingListeners = new Hashtable<Integer, RttListener>(); - } - - public static class RangingListener implements RttListener { - private static final String TAG = "WifiRttRanging"; - private static int sCount = 0; - private final EventFacade mEventFacade; - public final int mId; - - public RangingListener(EventFacade eventFacade) { - sCount += 1; - mId = sCount; - mEventFacade = eventFacade; - } - - private Bundle packRttResult(RttResult result) { - Bundle rttResult = new Bundle(); - rttResult.putString("BSSID", result.bssid); - rttResult.putInt("txRate", result.txRate); - rttResult.putInt("rxRate", result.rxRate); - rttResult.putInt("distance", result.distance); - rttResult.putInt("distanceStandardDeviation", - result.distanceStandardDeviation); - rttResult.putInt("distanceSpread", result.distanceSpread); - rttResult.putInt("burstDuration", result.burstDuration); - rttResult.putLong("rtt", result.rtt); - rttResult.putLong("rttStandardDeviation", - result.rttStandardDeviation); - rttResult.putLong("rttSpread", result.rttSpread); - rttResult.putLong("ts", result.ts); - rttResult.putInt("rssi", result.rssi); - rttResult.putInt("rssiSpread", result.rssiSpread); - rttResult.putInt("retryAfterDuration", result.retryAfterDuration); - rttResult.putInt("measurementType", result.measurementType); - rttResult.putInt("status", result.status); - rttResult.putInt("frameNumberPerBurstPeer", - result.frameNumberPerBurstPeer); - rttResult.putInt("successMeasurementFrameNumber", - result.successMeasurementFrameNumber); - rttResult.putInt("measurementFrameNumber", - result.measurementFrameNumber); - rttResult.putInt("burstNumber", result.burstNumber); - rttResult.putInt("status", result.status); - return rttResult; - } - - @Override - public void onSuccess(RttResult[] results) { - if (results == null) { - mEventFacade - .postEvent(RangingListener.TAG + mId + "onSuccess", null); - return; - } - Bundle msg = new Bundle(); - Parcelable[] resultBundles = new Parcelable[results.length]; - for (int i = 0; i < results.length; i++) { - resultBundles[i] = packRttResult(results[i]); - } - msg.putParcelableArray("Results", resultBundles); - mEventFacade - .postEvent(RangingListener.TAG + mId + "onSuccess", msg); - } - - @Override - public void onFailure(int reason, String description) { - Bundle msg = new Bundle(); - msg.putInt("Reason", reason); - msg.putString("Description", description); - mEventFacade - .postEvent(RangingListener.TAG + mId + "onFailure", msg); - } - - @Override - public void onAborted() { - mEventFacade.postEvent(RangingListener.TAG + mId + "onAborted", - new Bundle()); - } - } - - @Rpc(description = "Get wifi Rtt capabilities.") - public RttCapabilities wifiRttGetCapabilities() { - return mRtt.getRttCapabilities(); - } - - private RttParams parseRttParam(JSONObject j) throws JSONException { - RttParams result = new RttParams(); - if (j.has("deviceType")) { - result.deviceType = j.getInt("deviceType"); - } - if (j.has("requestType")) { - result.requestType = j.getInt("requestType"); - } - if (j.has("bssid")) { - result.bssid = j.getString("bssid"); - } - if (j.has("frequency")) { - result.frequency = j.getInt("frequency"); - } - if (j.has("channelWidth")) { - result.channelWidth = j.getInt("channelWidth"); - } - if (j.has("centerFreq0")) { - result.centerFreq0 = j.getInt("centerFreq0"); - } - if (j.has("centerFreq1")) { - result.centerFreq1 = j.getInt("centerFreq1"); - } - if (j.has("numberBurst")) { - result.numberBurst = j.getInt("numberBurst"); - } - if (j.has("burstTimeout")) { - result.burstTimeout = j.getInt("burstTimeout"); - } - if (j.has("interval")) { - result.interval = j.getInt("interval"); - } - if (j.has("numSamplesPerBurst")) { - result.numSamplesPerBurst = j.getInt("numSamplesPerBurst"); - } - if (j.has("numRetriesPerMeasurementFrame")) { - result.numRetriesPerMeasurementFrame = j - .getInt("numRetriesPerMeasurementFrame"); - } - if (j.has("numRetriesPerFTMR")) { - result.numRetriesPerFTMR = j.getInt("numRetriesPerFTMR"); - } - if (j.has("LCIRequest")) { - result.LCIRequest = j.getBoolean("LCIRequest"); - } - if (j.has("LCRRequest")) { - result.LCRRequest = j.getBoolean("LCRRequest"); - } - if (j.has("preamble")) { - result.preamble = j.getInt("preamble"); - } - if (j.has("bandwidth")) { - result.bandwidth = j.getInt("bandwidth"); - } - return result; - } - - @Rpc(description = "Start ranging.", returns = "Id of the listener associated with the started ranging.") - public Integer wifiRttStartRanging( - @RpcParameter(name = "params") JSONArray params) - throws JSONException { - RttParams[] rParams = new RttParams[params.length()]; - for (int i = 0; i < params.length(); i++) { - rParams[i] = parseRttParam(params.getJSONObject(i)); - } - RangingListener listener = new RangingListener(mEventFacade); - mRangingListeners.put(listener.mId, listener); - mRtt.startRanging(rParams, listener); - return listener.mId; - } - - @Rpc(description = "Stop ranging.") - public void wifiRttStopRanging(@RpcParameter(name = "index") Integer index) { - mRtt.stopRanging(mRangingListeners.remove(index)); - } - - @Override - public void shutdown() { - ArrayList<Integer> keys = new ArrayList<Integer>( - mRangingListeners.keySet()); - for (int k : keys) { - wifiRttStopRanging(k); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java deleted file mode 100644 index f718b90..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/facade/wifi/WifiScannerFacade.java +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) 2014 Google Inc. - * - * 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 com.googlecode.android_scripting.facade.wifi; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.MainThread; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -import android.app.Service; -import android.content.Context; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiScanner; -import android.net.wifi.WifiScanner.BssidInfo; -import android.net.wifi.WifiScanner.ChannelSpec; -import android.net.wifi.WifiScanner.ScanData; -import android.net.wifi.WifiScanner.ScanSettings; -import android.os.Bundle; -import android.os.SystemClock; -import android.provider.Settings.Global; -import android.provider.Settings.SettingNotFoundException; - -/** - * WifiScanner functions. - */ -public class WifiScannerFacade extends RpcReceiver { - private final Service mService; - private final EventFacade mEventFacade; - private final WifiScanner mScan; - // These counters are just for indexing; - // they do not represent the total number of listeners - private static int WifiScanListenerCnt; - private static int WifiChangeListenerCnt; - private static int WifiBssidListenerCnt; - private final ConcurrentHashMap<Integer, WifiScanListener> scanListeners; - private final ConcurrentHashMap<Integer, WifiScanListener> scanBackgroundListeners; - private final ConcurrentHashMap<Integer, ChangeListener> trackChangeListeners; - private final ConcurrentHashMap<Integer, WifiBssidListener> trackBssidListeners; - private static ConcurrentHashMap<Integer, ScanResult[]> wifiScannerResultList; - private static ConcurrentHashMap<Integer, ScanData[]> wifiScannerDataList; - - public WifiScannerFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mScan = (WifiScanner) mService.getSystemService(Context.WIFI_SCANNING_SERVICE); - mEventFacade = manager.getReceiver(EventFacade.class); - scanListeners = new ConcurrentHashMap<Integer, WifiScanListener>(); - scanBackgroundListeners = new ConcurrentHashMap<Integer, WifiScanListener>(); - trackChangeListeners = new ConcurrentHashMap<Integer, ChangeListener>(); - trackBssidListeners = new ConcurrentHashMap<Integer, WifiBssidListener>(); - wifiScannerResultList = new ConcurrentHashMap<Integer, ScanResult[]>(); - wifiScannerDataList = new ConcurrentHashMap<Integer, ScanData[]>(); - } - - public static List<ScanResult> getWifiScanResult(Integer listenerIndex) { - ScanResult[] sr = wifiScannerResultList.get(listenerIndex); - return Arrays.asList(sr); - } - - private class WifiActionListener implements WifiScanner.ActionListener { - private final Bundle mResults; - public int mIndex; - protected String mEventType; - private long startScanElapsedRealTime; - - public WifiActionListener(String type, int idx, Bundle resultBundle, long startScanERT) { - this.mIndex = idx; - this.mEventType = type; - this.mResults = resultBundle; - this.startScanElapsedRealTime = startScanERT; - } - - @Override - public void onSuccess() { - Log.d("onSuccess " + mEventType + " " + mIndex); - mResults.putString("Type", "onSuccess"); - mResults.putInt("Index", mIndex); - mResults.putLong("ScanElapsedRealtime", startScanElapsedRealTime); - mEventFacade.postEvent(mEventType + mIndex + "onSuccess", mResults.clone()); - mResults.clear(); - } - - @Override - public void onFailure(int reason, String description) { - Log.d("onFailure " + mEventType + " " + mIndex); - mResults.putString("Type", "onFailure"); - mResults.putInt("Index", mIndex); - mResults.putInt("Reason", reason); - mResults.putString("Description", description); - mEventFacade.postEvent(mEventType + mIndex + "onFailure", mResults.clone()); - mResults.clear(); - } - - public void reportResult(ScanResult[] results, String type) { - Log.d("reportResult " + mEventType + " " + mIndex); - mResults.putInt("Index", mIndex); - mResults.putLong("ResultElapsedRealtime", SystemClock.elapsedRealtime()); - mResults.putString("Type", type); - mResults.putParcelableArray("Results", results); - mEventFacade.postEvent(mEventType + mIndex + type, mResults.clone()); - mResults.clear(); - } - } - - /** - * Constructs a wifiScanListener obj and returns it - * - * @return WifiScanListener - */ - private WifiScanListener genWifiScanListener() { - WifiScanListener mWifiScannerListener = MainThread.run(mService, - new Callable<WifiScanListener>() { - @Override - public WifiScanListener call() throws Exception { - return new WifiScanListener(); - } - }); - scanListeners.put(mWifiScannerListener.mIndex, mWifiScannerListener); - return mWifiScannerListener; - } - - /** - * Constructs a wifiScanListener obj for background scan and returns it - * - * @return WifiScanListener - */ - private WifiScanListener genBackgroundWifiScanListener() { - WifiScanListener mWifiScannerListener = MainThread.run(mService, - new Callable<WifiScanListener>() { - @Override - public WifiScanListener call() throws Exception { - return new WifiScanListener(); - } - }); - scanBackgroundListeners.put(mWifiScannerListener.mIndex, mWifiScannerListener); - return mWifiScannerListener; - } - - private class WifiScanListener implements WifiScanner.ScanListener { - private static final String mEventType = "WifiScannerScan"; - protected final Bundle mScanResults; - protected final Bundle mScanData; - private final WifiActionListener mWAL; - public int mIndex; - - public WifiScanListener() { - mScanResults = new Bundle(); - mScanData = new Bundle(); - WifiScanListenerCnt += 1; - mIndex = WifiScanListenerCnt; - mWAL = new WifiActionListener(mEventType, mIndex, mScanResults, - SystemClock.elapsedRealtime()); - } - - @Override - public void onSuccess() { - mWAL.onSuccess(); - } - - @Override - public void onFailure(int reason, String description) { - scanListeners.remove(mIndex); - mWAL.onFailure(reason, description); - } - - @Override - public void onPeriodChanged(int periodInMs) { - Log.d("onPeriodChanged " + mEventType + " " + mIndex); - mScanResults.putString("Type", "onPeriodChanged"); - mScanResults.putInt("NewPeriod", periodInMs); - mEventFacade.postEvent(mEventType + mIndex, mScanResults.clone()); - mScanResults.clear(); - } - - @Override - public void onFullResult(ScanResult fullScanResult) { - Log.d("onFullResult WifiScanListener " + mIndex); - mWAL.reportResult(new ScanResult[] { - fullScanResult - }, "onFullResult"); - } - - public void onResults(ScanData[] results) { - Log.d("onResult WifiScanListener " + mIndex); - wifiScannerDataList.put(mIndex, results); - mScanData.putInt("Index", mIndex); - mScanData.putLong("ResultElapsedRealtime", SystemClock.elapsedRealtime()); - mScanData.putString("Type", "onResults"); - mScanData.putParcelableArray("Results", results); - mEventFacade.postEvent(mEventType + mIndex + "onResults", mScanData.clone()); - mScanData.clear(); - } - } - - /** - * Constructs a ChangeListener obj and returns it - * - * @return ChangeListener - */ - private ChangeListener genWifiChangeListener() { - ChangeListener mWifiChangeListener = MainThread.run(mService, - new Callable<ChangeListener>() { - @Override - public ChangeListener call() throws Exception { - return new ChangeListener(); - } - }); - trackChangeListeners.put(mWifiChangeListener.mIndex, mWifiChangeListener); - return mWifiChangeListener; - } - - private class ChangeListener implements WifiScanner.WifiChangeListener { - private static final String mEventType = "WifiScannerChange"; - protected final Bundle mResults; - private final WifiActionListener mWAL; - public int mIndex; - - public ChangeListener() { - mResults = new Bundle(); - WifiChangeListenerCnt += 1; - mIndex = WifiChangeListenerCnt; - mWAL = new WifiActionListener(mEventType, mIndex, mResults, - SystemClock.elapsedRealtime()); - } - - @Override - public void onSuccess() { - mWAL.onSuccess(); - } - - @Override - public void onFailure(int reason, String description) { - trackChangeListeners.remove(mIndex); - mWAL.onFailure(reason, description); - } - - /** - * indicates that changes were detected in wifi environment - * - * @param results indicate the access points that exhibited change - */ - @Override - public void onChanging(ScanResult[] results) { /* changes are found */ - mWAL.reportResult(results, "onChanging"); - } - - /** - * indicates that no wifi changes are being detected for a while - * - * @param results indicate the access points that are bing monitored for change - */ - @Override - public void onQuiescence(ScanResult[] results) { /* changes settled down */ - mWAL.reportResult(results, "onQuiescence"); - } - } - - private WifiBssidListener genWifiBssidListener() { - WifiBssidListener mWifiBssidListener = MainThread.run(mService, - new Callable<WifiBssidListener>() { - @Override - public WifiBssidListener call() throws Exception { - return new WifiBssidListener(); - } - }); - trackBssidListeners.put(mWifiBssidListener.mIndex, mWifiBssidListener); - return mWifiBssidListener; - } - - private class WifiBssidListener implements WifiScanner.BssidListener { - private static final String mEventType = "WifiScannerBssid"; - protected final Bundle mResults; - private final WifiActionListener mWAL; - public int mIndex; - - public WifiBssidListener() { - mResults = new Bundle(); - WifiBssidListenerCnt += 1; - mIndex = WifiBssidListenerCnt; - mWAL = new WifiActionListener(mEventType, mIndex, mResults, - SystemClock.elapsedRealtime()); - } - - @Override - public void onSuccess() { - mWAL.onSuccess(); - } - - @Override - public void onFailure(int reason, String description) { - trackBssidListeners.remove(mIndex); - mWAL.onFailure(reason, description); - } - - @Override - public void onFound(ScanResult[] results) { - mWAL.reportResult(results, "onFound"); - } - - @Override - public void onLost(ScanResult[] results) { - mWAL.reportResult(results, "onLost"); - } - } - - private ScanSettings parseScanSettings(JSONObject j) throws JSONException { - if (j == null) { - return null; - } - ScanSettings result = new ScanSettings(); - if (j.has("band")) { - result.band = j.optInt("band"); - } - if (j.has("channels")) { - JSONArray chs = j.getJSONArray("channels"); - ChannelSpec[] channels = new ChannelSpec[chs.length()]; - for (int i = 0; i < channels.length; i++) { - channels[i] = new ChannelSpec(chs.getInt(i)); - } - result.channels = channels; - } - if (j.has("maxScansToCache")) { - result.maxScansToCache = j.getInt("maxScansToCache"); - } - /* periodInMs and reportEvents are required */ - result.periodInMs = j.getInt("periodInMs"); - if (j.has("maxPeriodInMs")) { - result.maxPeriodInMs = j.getInt("maxPeriodInMs"); - } - if (j.has("stepCount")) { - result.stepCount = j.getInt("stepCount"); - } - result.reportEvents = j.getInt("reportEvents"); - if (j.has("numBssidsPerScan")) { - result.numBssidsPerScan = j.getInt("numBssidsPerScan"); - } - return result; - } - - private BssidInfo[] parseBssidInfo(JSONArray jBssids) throws JSONException { - BssidInfo[] bssids = new BssidInfo[jBssids.length()]; - for (int i = 0; i < bssids.length; i++) { - JSONObject bi = (JSONObject) jBssids.get(i); - BssidInfo bssidInfo = new BssidInfo(); - bssidInfo.bssid = bi.getString("BSSID"); - bssidInfo.high = bi.getInt("high"); - bssidInfo.low = bi.getInt("low"); - if (bi.has("frequencyHint")) { - bssidInfo.frequencyHint = bi.getInt("frequencyHint"); - } - bssids[i] = bssidInfo; - } - return bssids; - } - - /** - * Starts periodic WifiScanner scan - * - * @param scanSettings - * @return the id of the scan listener associated with this scan - * @throws JSONException - */ - @Rpc(description = "Starts a WifiScanner Background scan") - public Integer wifiScannerStartBackgroundScan( - @RpcParameter(name = "scanSettings") JSONObject scanSettings) - throws JSONException { - ScanSettings ss = parseScanSettings(scanSettings); - Log.d("startWifiScannerScan with " + ss.channels); - WifiScanListener listener = genBackgroundWifiScanListener(); - mScan.startBackgroundScan(ss, listener); - return listener.mIndex; - } - - /** - * Get currently available scan results on appropriate listeners - * - * @return true if all scan results were reported correctly - * @throws JSONException - */ - @Rpc(description = "Get currently available scan results on appropriate listeners") - public Boolean wifiScannerGetScanResults() throws JSONException { - mScan.getScanResults(); - return true; - } - - /** - * Stops a WifiScanner scan - * - * @param listenerIndex the id of the scan listener whose scan to stop - * @throws Exception - */ - @Rpc(description = "Stops an ongoing WifiScanner Background scan") - public void wifiScannerStopBackgroundScan( - @RpcParameter(name = "listener") Integer listenerIndex) - throws Exception { - if (!scanBackgroundListeners.containsKey(listenerIndex)) { - throw new Exception("Background scan session " + listenerIndex + " does not exist"); - } - WifiScanListener listener = scanBackgroundListeners.get(listenerIndex); - Log.d("stopWifiScannerScan listener " + listener.mIndex); - mScan.stopBackgroundScan(listener); - wifiScannerResultList.remove(listenerIndex); - scanBackgroundListeners.remove(listenerIndex); - } - - /** - * Starts periodic WifiScanner scan - * - * @param scanSettings - * @return the id of the scan listener associated with this scan - * @throws JSONException - */ - @Rpc(description = "Starts a WifiScanner single scan") - public Integer wifiScannerStartScan( - @RpcParameter(name = "scanSettings") JSONObject scanSettings) - throws JSONException { - ScanSettings ss = parseScanSettings(scanSettings); - Log.d("startWifiScannerScan with " + ss.channels); - WifiScanListener listener = genWifiScanListener(); - mScan.startScan(ss, listener); - return listener.mIndex; - } - - /** - * Stops a WifiScanner scan - * - * @param listenerIndex the id of the scan listener whose scan to stop - * @throws Exception - */ - @Rpc(description = "Stops an ongoing WifiScanner Single scan") - public void wifiScannerStopScan(@RpcParameter(name = "listener") Integer listenerIndex) - throws Exception { - if (!scanListeners.containsKey(listenerIndex)) { - throw new Exception("Single scan session " + listenerIndex + " does not exist"); - } - WifiScanListener listener = scanListeners.get(listenerIndex); - Log.d("stopWifiScannerScan listener " + listener.mIndex); - mScan.stopScan(listener); - wifiScannerResultList.remove(listener.mIndex); - scanListeners.remove(listenerIndex); - } - - /** RPC Methods */ - @Rpc(description = "Returns the channels covered by the specified band number.") - public List<Integer> wifiScannerGetAvailableChannels( - @RpcParameter(name = "band") Integer band) { - return mScan.getAvailableChannels(band); - } - - /** - * Starts tracking wifi changes - * - * @return the id of the change listener associated with this track - * @throws Exception - */ - @Rpc(description = "Starts tracking wifi changes") - public Integer wifiScannerStartTrackingChange() throws Exception { - ChangeListener listener = genWifiChangeListener(); - mScan.startTrackingWifiChange(listener); - return listener.mIndex; - } - - /** - * Stops tracking wifi changes - * - * @param listenerIndex the id of the change listener whose track to stop - * @throws Exception - */ - @Rpc(description = "Stops tracking wifi changes") - public void wifiScannerStopTrackingChange( - @RpcParameter(name = "listener") Integer listenerIndex) throws Exception { - if (!trackChangeListeners.containsKey(listenerIndex)) { - throw new Exception("Wifi change tracking session " + listenerIndex - + " does not exist"); - } - ChangeListener listener = trackChangeListeners.get(listenerIndex); - mScan.stopTrackingWifiChange(listener); - trackChangeListeners.remove(listenerIndex); - } - - /** - * Starts tracking changes of the specified bssids. - * - * @param bssidInfos An array of json strings, each representing a BssidInfo object. - * @param apLostThreshold - * @return The index of the listener used to start the tracking. - * @throws JSONException - */ - @Rpc(description = "Starts tracking changes of the specified bssids.") - public Integer wifiScannerStartTrackingBssids( - @RpcParameter(name = "bssidInfos") JSONArray bssidInfos, - @RpcParameter(name = "apLostThreshold") Integer apLostThreshold) throws JSONException { - BssidInfo[] bssids = parseBssidInfo(bssidInfos); - WifiBssidListener listener = genWifiBssidListener(); - mScan.startTrackingBssids(bssids, apLostThreshold, listener); - return listener.mIndex; - } - - /** - * Stops tracking the list of APs associated with the input listener - * - * @param listenerIndex the id of the bssid listener whose track to stop - * @throws Exception - */ - @Rpc(description = "Stops tracking changes in the APs on the list") - public void wifiScannerStopTrackingBssids( - @RpcParameter(name = "listener") Integer listenerIndex) throws Exception { - if (!trackBssidListeners.containsKey(listenerIndex)) { - throw new Exception("Bssid tracking session " + listenerIndex + " does not exist"); - } - WifiBssidListener listener = trackBssidListeners.get(listenerIndex); - mScan.stopTrackingBssids(listener); - trackBssidListeners.remove(listenerIndex); - } - - @Rpc(description = "Toggle the 'WiFi scan always available' option. If an input is given, the " - + "option is set to what the input boolean indicates.") - public void wifiScannerToggleAlwaysAvailable( - @RpcParameter(name = "alwaysAvailable") @RpcOptional Boolean alwaysAvailable) - throws SettingNotFoundException { - int new_state = 0; - if (alwaysAvailable == null) { - int current_state = Global.getInt(mService.getContentResolver(), - Global.WIFI_SCAN_ALWAYS_AVAILABLE); - new_state = current_state ^ 0x1; - } else { - new_state = alwaysAvailable ? 1 : 0; - } - Global.putInt(mService.getContentResolver(), Global.WIFI_SCAN_ALWAYS_AVAILABLE, new_state); - } - - @Rpc(description = "Returns true if WiFi scan is always available, false otherwise.") - public Boolean wifiScannerIsAlwaysAvailable() throws SettingNotFoundException { - int current_state = Global.getInt(mService.getContentResolver(), - Global.WIFI_SCAN_ALWAYS_AVAILABLE); - if (current_state == 1) { - return true; - } - return false; - } - - @Rpc(description = "Returns a list of mIndexes of existing listeners") - public Set<Integer> wifiGetCurrentScanIndexes() { - return scanListeners.keySet(); - } - - /** - * Starts tracking wifi changes - * - * @return the id of the change listener associated with this track - * @throws Exception - */ - @Rpc(description = "Starts tracking wifi changes with track settings") - public Integer wifiScannerStartTrackingChangeWithSetting( - @RpcParameter(name = "trackSettings") JSONArray bssidSettings, - @RpcParameter(name = "rssiSS") Integer rssiSS, - @RpcParameter(name = "lostApSS") Integer lostApSS, - @RpcParameter(name = "unchangedSS") Integer unchangedSS, - @RpcParameter(name = "minApsBreachingThreshold") Integer minApsBreachingThreshold, - @RpcParameter(name = "periodInMs") Integer periodInMs) throws Exception { - Log.d("starting change track with track settings"); - BssidInfo[] bssids = parseBssidInfo(bssidSettings); - mScan.configureWifiChange(rssiSS, lostApSS, unchangedSS, minApsBreachingThreshold, - periodInMs, bssids); - ChangeListener listener = genWifiChangeListener(); - mScan.startTrackingWifiChange(listener); - return listener.mIndex; - } - - /** - * Shuts down all activities associated with WifiScanner - */ - @Rpc(description = "Shuts down all WifiScanner activities and remove listeners.") - public void wifiScannerShutdown() { - this.shutdown(); - } - - /** - * Stops all activity - */ - @Override - public void shutdown() { - try { - if (!scanListeners.isEmpty()) { - Iterator<ConcurrentHashMap.Entry<Integer, WifiScanListener>> iter = scanListeners - .entrySet().iterator(); - while (iter.hasNext()) { - ConcurrentHashMap.Entry<Integer, WifiScanListener> entry = iter.next(); - this.wifiScannerStopScan(entry.getKey()); - } - } - if (!scanBackgroundListeners.isEmpty()) { - Iterator<ConcurrentHashMap.Entry<Integer, WifiScanListener>> iter = scanBackgroundListeners - .entrySet().iterator(); - while (iter.hasNext()) { - ConcurrentHashMap.Entry<Integer, WifiScanListener> entry = iter.next(); - this.wifiScannerStopBackgroundScan(entry.getKey()); - } - } - if (!trackChangeListeners.isEmpty()) { - Iterator<ConcurrentHashMap.Entry<Integer, ChangeListener>> iter = trackChangeListeners - .entrySet().iterator(); - while (iter.hasNext()) { - ConcurrentHashMap.Entry<Integer, ChangeListener> entry = iter.next(); - this.wifiScannerStopTrackingChange(entry.getKey()); - } - } - if (!trackBssidListeners.isEmpty()) { - Iterator<ConcurrentHashMap.Entry<Integer, WifiBssidListener>> iter = trackBssidListeners - .entrySet().iterator(); - while (iter.hasNext()) { - ConcurrentHashMap.Entry<Integer, WifiBssidListener> entry = iter.next(); - this.wifiScannerStopTrackingBssids(entry.getKey()); - } - } - } catch (Exception e) { - Log.e("Shutdown failed: " + e.toString()); - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/future/FutureActivityTask.java b/sl4a/Common/src/com/googlecode/android_scripting/future/FutureActivityTask.java deleted file mode 100644 index b474736..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/future/FutureActivityTask.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.future; - -import android.app.Activity; -import android.content.Intent; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.View; -import android.view.Window; -import java.util.concurrent.TimeUnit; - -/** - * Encapsulates an {@link Activity} and a {@link FutureObject}. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public abstract class FutureActivityTask<T> { - - private final FutureResult<T> mResult = new FutureResult<T>(); - private Activity mActivity; - - public void setActivity(Activity activity) { - mActivity = activity; - } - - public Activity getActivity() { - return mActivity; - } - - public void onCreate() { - mActivity.getWindow().requestFeature(Window.FEATURE_NO_TITLE); - } - - public void onStart() { - } - - public void onResume() { - } - - public void onPause() { - } - - public void onStop() { - } - - public void onDestroy() { - } - - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - } - - public boolean onPrepareOptionsMenu(Menu menu) { - return false; - } - - public void onActivityResult(int requestCode, int resultCode, Intent data) { - } - - protected void setResult(T result) { - mResult.set(result); - } - - public T getResult() throws InterruptedException { - return mResult.get(); - } - - public T getResult(long timeout, TimeUnit unit) throws InterruptedException { - return mResult.get(timeout, unit); - } - - public void finish() { - mActivity.finish(); - } - - public void startActivity(Intent intent) { - mActivity.startActivity(intent); - } - - public void startActivityForResult(Intent intent, int requestCode) { - mActivity.startActivityForResult(intent, requestCode); - } - - public boolean onKeyDown(int keyCode, KeyEvent event) { - // Placeholder. - return false; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InProcessInterpreter.java b/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InProcessInterpreter.java deleted file mode 100644 index 48de556..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InProcessInterpreter.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import java.io.FileDescriptor; - -public interface InProcessInterpreter { - public FileDescriptor getStdOut(); - - public FileDescriptor getStdIn(); - - public boolean runInteractive(); - - public void runScript(String filename); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/Interpreter.java b/sl4a/Common/src/com/googlecode/android_scripting/interpreter/Interpreter.java deleted file mode 100644 index 7a69032..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/Interpreter.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import com.googlecode.android_scripting.language.Language; -import com.googlecode.android_scripting.language.SupportedLanguages; -import com.googlecode.android_scripting.rpc.MethodDescriptor; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Combines all the execution-related specs of a particular interpreter installed in the system. - * This class is instantiated through a map received from a concrete InterpreterProfider. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class Interpreter implements InterpreterPropertyNames { - - private String mExtension; - private String mName; - private String mNiceName; - private String mInteractiveCommand; - private String mScriptExecutionCommand; - private File mBinary; - private boolean mHasInteractiveMode; - private final List<String> mArguments; - private final Map<String, String> mEnvironment; - private Language mLanguage; - - public Interpreter() { - mArguments = new ArrayList<String>(); - mEnvironment = new HashMap<String, String>(); - } - - public static Interpreter buildFromMaps(Map<String, String> data, - Map<String, String> environment_variables, Map<String, String> arguments) { - String extension = data.get(EXTENSION); - String name = data.get(NAME); - String niceName = data.get(NICE_NAME); - String binary = data.get(BINARY); - String interactiveCommand = data.get(INTERACTIVE_COMMAND); - String scriptCommand = data.get(SCRIPT_COMMAND); - Boolean hasInteractiveMode; - if (data.containsKey(HAS_INTERACTIVE_MODE)) { - hasInteractiveMode = Boolean.parseBoolean(data.get(HAS_INTERACTIVE_MODE)); - } else { - // Default to true so that older interpreter APKs that don't have this value define still - // work. - hasInteractiveMode = true; - } - Interpreter interpreter = new Interpreter(); - interpreter.setName(name); - interpreter.setNiceName(niceName); - interpreter.setExtension(extension); - interpreter.setBinary(new File(binary)); - interpreter.setInteractiveCommand(interactiveCommand); - interpreter.setScriptCommand(scriptCommand); - interpreter.setHasInteractiveMode(hasInteractiveMode); - interpreter.setLanguage(SupportedLanguages.getLanguageByExtension(extension)); - interpreter.putAllEnvironmentVariables(environment_variables); - interpreter.addAllArguments(arguments.values()); - return interpreter; - } - - // TODO(damonkohler): This should take a List<String> since order is important. - private void addAllArguments(Collection<String> arguments) { - mArguments.addAll(arguments); - } - - List<String> getArguments() { - return mArguments; - } - - private void putAllEnvironmentVariables(Map<String, String> environmentVariables) { - mEnvironment.putAll(environmentVariables); - } - - public Map<String, String> getEnvironmentVariables() { - return mEnvironment; - } - - protected void setScriptCommand(String executeParameters) { - mScriptExecutionCommand = executeParameters; - } - - public String getScriptCommand() { - return mScriptExecutionCommand; - } - - protected void setInteractiveCommand(String interactiveCommand) { - mInteractiveCommand = interactiveCommand; - } - - public String getInteractiveCommand() { - return mInteractiveCommand; - } - - protected void setBinary(File binary) { - if (!binary.exists()) { - throw new RuntimeException("Binary " + binary + " does not exist!"); - } - mBinary = binary; - } - - public File getBinary() { - return mBinary; - } - - protected void setExtension(String extension) { - mExtension = extension; - } - - protected void setHasInteractiveMode(boolean hasInteractiveMode) { - mHasInteractiveMode = hasInteractiveMode; - } - - public boolean hasInteractiveMode() { - return mHasInteractiveMode; - } - - public String getExtension() { - return mExtension; - } - - protected void setName(String name) { - mName = name; - } - - public String getName() { - return mName; - } - - protected void setNiceName(String niceName) { - mNiceName = niceName; - } - - public String getNiceName() { - return mNiceName; - } - - public String getContentTemplate() { - return mLanguage.getContentTemplate(); - } - - protected void setLanguage(Language language) { - mLanguage = language; - } - - public Language getLanguage() { - return mLanguage; - } - - public String getRpcText(String content, MethodDescriptor rpc, String[] values) { - return mLanguage.getRpcText(content, rpc, values); - } - - public boolean isInstalled() { - return mBinary.exists(); - } - - public boolean isUninstallable() { - return true; - } -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InterpreterConfiguration.java b/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InterpreterConfiguration.java deleted file mode 100644 index 27f9b7a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/InterpreterConfiguration.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.content.pm.ResolveInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.database.Cursor; -import android.net.Uri; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SingleThreadExecutor; -import com.googlecode.android_scripting.interpreter.shell.ShellInterpreter; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutorService; - -/** - * Manages and provides access to the set of available interpreters. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class InterpreterConfiguration { - - private final InterpreterListener mListener; - private final Set<Interpreter> mInterpreterSet; - private final Set<ConfigurationObserver> mObserverSet; - private final Context mContext; - private volatile boolean mIsDiscoveryComplete = false; - - public interface ConfigurationObserver { - public void onConfigurationChanged(); - } - - private class InterpreterListener extends BroadcastReceiver { - private final PackageManager mmPackageManager; - private final ContentResolver mmResolver; - private final ExecutorService mmExecutor; - private final Map<String, Interpreter> mmDiscoveredInterpreters; - - private InterpreterListener(Context context) { - mmPackageManager = context.getPackageManager(); - mmResolver = context.getContentResolver(); - mmExecutor = new SingleThreadExecutor(); - mmDiscoveredInterpreters = new HashMap<String, Interpreter>(); - } - - private void discoverForType(final String mime) { - mmExecutor.execute(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(InterpreterConstants.ACTION_DISCOVER_INTERPRETERS); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.setType(mime); - List<ResolveInfo> resolveInfos = mmPackageManager.queryIntentActivities(intent, 0); - for (ResolveInfo info : resolveInfos) { - addInterpreter(info.activityInfo.packageName); - } - mIsDiscoveryComplete = true; - notifyConfigurationObservers(); - } - }); - } - - private void discoverAll() { - mmExecutor.execute(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(InterpreterConstants.ACTION_DISCOVER_INTERPRETERS); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - intent.setType(InterpreterConstants.MIME + "*"); - List<ResolveInfo> resolveInfos = mmPackageManager.queryIntentActivities(intent, 0); - for (ResolveInfo info : resolveInfos) { - addInterpreter(info.activityInfo.packageName); - } - mIsDiscoveryComplete = true; - notifyConfigurationObservers(); - } - }); - } - - private void notifyConfigurationObservers() { - for (ConfigurationObserver observer : mObserverSet) { - observer.onConfigurationChanged(); - } - } - - private void addInterpreter(final String packageName) { - if (mmDiscoveredInterpreters.containsKey(packageName)) { - return; - } - Interpreter discoveredInterpreter = buildInterpreter(packageName); - if (discoveredInterpreter == null) { - return; - } - mmDiscoveredInterpreters.put(packageName, discoveredInterpreter); - mInterpreterSet.add(discoveredInterpreter); - Log.v("Interpreter discovered: " + packageName + "\nBinary: " - + discoveredInterpreter.getBinary()); - } - - private void remove(final String packageName) { - if (!mmDiscoveredInterpreters.containsKey(packageName)) { - return; - } - mmExecutor.execute(new Runnable() { - @Override - public void run() { - Interpreter interpreter = mmDiscoveredInterpreters.get(packageName); - if (interpreter == null) { - Log.v("Interpreter for " + packageName + " not installed."); - return; - } - mInterpreterSet.remove(interpreter); - mmDiscoveredInterpreters.remove(packageName); - notifyConfigurationObservers(); - } - }); - } - - // We require that there's only one interpreter provider per APK. - private Interpreter buildInterpreter(String packageName) { - PackageInfo packInfo; - try { - packInfo = mmPackageManager.getPackageInfo(packageName, PackageManager.GET_PROVIDERS); - } catch (NameNotFoundException e) { - throw new RuntimeException("Package '" + packageName + "' not found."); - } - ProviderInfo provider = packInfo.providers[0]; - - Map<String, String> interpreterMap = - getMap(provider, InterpreterConstants.PROVIDER_PROPERTIES); - if (interpreterMap == null) { - Log.e("Null interpreter map for: " + packageName); - return null; - } - Map<String, String> environmentMap = - getMap(provider, InterpreterConstants.PROVIDER_ENVIRONMENT_VARIABLES); - if (environmentMap == null) { - throw new RuntimeException("Null environment map for: " + packageName); - } - Map<String, String> argumentsMap = getMap(provider, InterpreterConstants.PROVIDER_ARGUMENTS); - if (argumentsMap == null) { - throw new RuntimeException("Null arguments map for: " + packageName); - } - return Interpreter.buildFromMaps(interpreterMap, environmentMap, argumentsMap); - } - - private Map<String, String> getMap(ProviderInfo provider, String name) { - Uri uri = Uri.parse("content://" + provider.authority + "/" + name); - Cursor cursor = mmResolver.query(uri, null, null, null, null); - if (cursor == null) { - return null; - } - cursor.moveToFirst(); - // Use LinkedHashMap so that order is maintained (important for position CLI arguments). - Map<String, String> map = new LinkedHashMap<String, String>(); - for (int i = 0; i < cursor.getColumnCount(); i++) { - map.put(cursor.getColumnName(i), cursor.getString(i)); - } - return map; - } - - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - final String packageName = intent.getData().getSchemeSpecificPart(); - if (action.equals(InterpreterConstants.ACTION_INTERPRETER_ADDED)) { - mmExecutor.execute(new Runnable() { - @Override - public void run() { - addInterpreter(packageName); - notifyConfigurationObservers(); - } - }); - } else if (action.equals(InterpreterConstants.ACTION_INTERPRETER_REMOVED) - || action.equals(Intent.ACTION_PACKAGE_REMOVED) - || action.equals(Intent.ACTION_PACKAGE_REPLACED) - || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) { - remove(packageName); - } - } - - } - - public InterpreterConfiguration(Context context) { - mContext = context; - mInterpreterSet = new CopyOnWriteArraySet<Interpreter>(); - mInterpreterSet.add(new ShellInterpreter()); - mObserverSet = new CopyOnWriteArraySet<ConfigurationObserver>(); - IntentFilter filter = new IntentFilter(); - filter.addAction(InterpreterConstants.ACTION_INTERPRETER_ADDED); - filter.addAction(InterpreterConstants.ACTION_INTERPRETER_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_REPLACED); - filter.addDataScheme("package"); - mListener = new InterpreterListener(mContext); - mContext.registerReceiver(mListener, filter); - } - - public void startDiscovering() { - mListener.discoverAll(); - } - - public void startDiscovering(String mime) { - mListener.discoverForType(mime); - } - - public boolean isDiscoveryComplete() { - return mIsDiscoveryComplete; - } - - public void registerObserver(ConfigurationObserver observer) { - if (observer != null) { - mObserverSet.add(observer); - } - } - - public void unregisterObserver(ConfigurationObserver observer) { - if (observer != null) { - mObserverSet.remove(observer); - } - } - - /** - * Returns the list of all known interpreters. - */ - public List<? extends Interpreter> getSupportedInterpreters() { - return new ArrayList<Interpreter>(mInterpreterSet); - } - - /** - * Returns the list of all installed interpreters. - */ - public List<Interpreter> getInstalledInterpreters() { - List<Interpreter> interpreters = new ArrayList<Interpreter>(); - for (Interpreter i : mInterpreterSet) { - if (i.isInstalled()) { - interpreters.add(i); - } - } - return interpreters; - } - - /** - * Returns the list of interpreters that support interactive mode execution. - */ - public List<Interpreter> getInteractiveInterpreters() { - List<Interpreter> interpreters = new ArrayList<Interpreter>(); - for (Interpreter i : mInterpreterSet) { - if (i.isInstalled() && i.hasInteractiveMode()) { - interpreters.add(i); - } - } - return interpreters; - } - - /** - * Returns the interpreter matching the provided name or null if no interpreter was found. - */ - public Interpreter getInterpreterByName(String interpreterName) { - for (Interpreter i : mInterpreterSet) { - if (i.getName().equals(interpreterName)) { - return i; - } - } - return null; - } - - /** - * Returns the correct interpreter for the provided script name based on the script's extension or - * null if no interpreter was found. - */ - public Interpreter getInterpreterForScript(String scriptName) { - int dotIndex = scriptName.lastIndexOf('.'); - if (dotIndex == -1) { - return null; - } - String ext = scriptName.substring(dotIndex); - for (Interpreter i : mInterpreterSet) { - if (i.getExtension().equals(ext)) { - return i; - } - } - return null; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/html/HtmlActivityTask.java b/sl4a/Common/src/com/googlecode/android_scripting/interpreter/html/HtmlActivityTask.java deleted file mode 100644 index fa5d768..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/html/HtmlActivityTask.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter.html; - -import android.app.Activity; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.net.Uri; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.Menu; -import android.view.View; -import android.view.Window; -import android.webkit.JsPromptResult; -import android.webkit.JsResult; -import android.webkit.WebChromeClient; -import android.webkit.WebView; -import android.webkit.WebViewClient; - -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SingleThreadExecutor; -import com.googlecode.android_scripting.event.Event; -import com.googlecode.android_scripting.event.EventObserver; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.ui.UiFacade; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; -import com.googlecode.android_scripting.jsonrpc.JsonBuilder; -import com.googlecode.android_scripting.jsonrpc.JsonRpcResult; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.RpcError; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutorService; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class HtmlActivityTask extends FutureActivityTask<Void> { - - private static final String HTTP = "http"; - private static final String ANDROID_PROTOTYPE_JS = - "Android.prototype.%1$s = function(var_args) { " - + "return this._call(\"%1$s\", Array.prototype.slice.call(arguments)); };"; - - private static final String PREFIX = "file://"; - private static final String BASE_URL = PREFIX + InterpreterConstants.SCRIPTS_ROOT; - - private final RpcReceiverManager mReceiverManager; - private final String mJsonSource; - private final String mAndroidJsSource; - private final String mAPIWrapperSource; - private final String mUrl; - private final JavaScriptWrapper mWrapper; - private final HtmlEventObserver mObserver; - private final UiFacade mUiFacade; - private ChromeClient mChromeClient; - private WebView mView; - private MyWebViewClient mWebViewClient; - private static HtmlActivityTask reference; - private boolean mDestroyManager; - - public HtmlActivityTask(RpcReceiverManager manager, String androidJsSource, String jsonSource, - String url, boolean destroyManager) { - reference = this; - mReceiverManager = manager; - mJsonSource = jsonSource; - mAndroidJsSource = androidJsSource; - mAPIWrapperSource = generateAPIWrapper(); - mWrapper = new JavaScriptWrapper(); - mObserver = new HtmlEventObserver(); - mReceiverManager.getReceiver(EventFacade.class).addGlobalEventObserver(mObserver); - mUiFacade = mReceiverManager.getReceiver(UiFacade.class); - mUrl = url; - mDestroyManager = destroyManager; - } - - public RpcReceiverManager getRpcReceiverManager() { - return mReceiverManager; - } - - /* - * New WebviewClient - */ - private class MyWebViewClient extends WebViewClient { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - /* - * if (Uri.parse(url).getHost().equals("www.example.com")) { - * // This is my web site, so do not - * override; let my WebView load the page return false; } - * // Otherwise, the link is not for a - * page on my site, so launch another Activity that handles URLs Intent intent = new - * Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); - */ - if (!HTTP.equals(Uri.parse(url).getScheme())) { - String source = null; - try { - source = FileUtils.readToString(new File(Uri.parse(url).getPath())); - } catch (IOException e) { - throw new RuntimeException(e); - } - source = - "<script>" + mJsonSource + "</script>" + "<script>" + mAndroidJsSource + "</script>" - + "<script>" + mAPIWrapperSource + "</script>" + source; - mView.loadDataWithBaseURL(BASE_URL, source, "text/html", "utf-8", null); - } else { - mView.loadUrl(url); - } - return true; - } - } - - @Override - public void onCreate() { - mView = new WebView(getActivity()); - mView.setId(1); - mView.getSettings().setJavaScriptEnabled(true); - mView.addJavascriptInterface(mWrapper, "_rpc_wrapper"); - mView.addJavascriptInterface(new Object() { - - @SuppressWarnings("unused") - public void register(String event, int id) { - mObserver.register(event, id); - } - }, "_callback_wrapper"); - - getActivity().setContentView(mView); - mView.setOnCreateContextMenuListener(getActivity()); - mChromeClient = new ChromeClient(getActivity()); - mWebViewClient = new MyWebViewClient(); - mView.setWebChromeClient(mChromeClient); - mView.setWebViewClient(mWebViewClient); - mView.loadUrl("javascript:" + mJsonSource); - mView.loadUrl("javascript:" + mAndroidJsSource); - mView.loadUrl("javascript:" + mAPIWrapperSource); - load(); - } - - private void load() { - if (!HTTP.equals(Uri.parse(mUrl).getScheme())) { - String source = null; - try { - source = FileUtils.readToString(new File(Uri.parse(mUrl).getPath())); - } catch (IOException e) { - throw new RuntimeException(e); - } - mView.loadDataWithBaseURL(BASE_URL, source, "text/html", "utf-8", null); - } else { - mView.loadUrl(mUrl); - } - } - - @Override - public void onDestroy() { - mReceiverManager.getReceiver(EventFacade.class).removeEventObserver(mObserver); - if (mDestroyManager) { - mReceiverManager.shutdown(); - } - mView.destroy(); - mView = null; - reference = null; - setResult(null); - } - - public static void shutdown() { - if (HtmlActivityTask.reference != null) { - HtmlActivityTask.reference.finish(); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - mUiFacade.onCreateContextMenu(menu, v, menuInfo); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - return mUiFacade.onPrepareOptionsMenu(menu); - } - - private String generateAPIWrapper() { - StringBuilder wrapper = new StringBuilder(); - for (Class<? extends RpcReceiver> clazz : mReceiverManager.getRpcReceiverClasses()) { - for (MethodDescriptor rpc : MethodDescriptor.collectFrom(clazz)) { - wrapper.append(String.format(ANDROID_PROTOTYPE_JS, rpc.getName())); - } - } - return wrapper.toString(); - } - - private class JavaScriptWrapper { - @SuppressWarnings("unused") - public String call(String data) throws JSONException { - Log.v("Received: " + data); - JSONObject request = new JSONObject(data); - int id = request.getInt("id"); - String method = request.getString("method"); - JSONArray params = request.getJSONArray("params"); - MethodDescriptor rpc = mReceiverManager.getMethodDescriptor(method); - if (rpc == null) { - return JsonRpcResult.error(id, new RpcError("Unknown RPC.")).toString(); - } - try { - return JsonRpcResult.result(id, rpc.invoke(mReceiverManager, params)).toString(); - } catch (Throwable t) { - Log.e("Invocation error.", t); - return JsonRpcResult.error(id, t).toString(); - } - } - - @SuppressWarnings("unused") - public void dismiss() { - Activity parent = getActivity(); - parent.finish(); - } - } - - private class HtmlEventObserver implements EventObserver { - private Map<String, Set<Integer>> mEventMap = new HashMap<String, Set<Integer>>(); - - public void register(String eventName, Integer id) { - if (mEventMap.containsKey(eventName)) { - mEventMap.get(eventName).add(id); - } else { - Set<Integer> idSet = new HashSet<Integer>(); - idSet.add(id); - mEventMap.put(eventName, idSet); - } - } - - @Override - public void onEventReceived(Event event) { - final JSONObject json = new JSONObject(); - try { - json.put("data", JsonBuilder.build(event.getData())); - } catch (JSONException e) { - Log.e(e); - } - if (mEventMap.containsKey(event.getName())) { - for (final Integer id : mEventMap.get(event.getName())) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mView.loadUrl(String.format("javascript:droid._callback(%d, %s);", id, json)); - } - }); - } - } - } - - @SuppressWarnings("unused") - public void dismiss() { - Activity parent = getActivity(); - parent.finish(); - } - } - - private class ChromeClient extends WebChromeClient { - private final static String JS_TITLE = "JavaScript Dialog"; - - private final Activity mActivity; - private final Resources mResources; - private final ExecutorService mmExecutor; - - public ChromeClient(Activity activity) { - mActivity = activity; - mResources = mActivity.getResources(); - mmExecutor = new SingleThreadExecutor(); - } - - @Override - public void onReceivedTitle(WebView view, String title) { - mActivity.setTitle(title); - } - - @Override - public void onReceivedIcon(WebView view, Bitmap icon) { - mActivity.getWindow().requestFeature(Window.FEATURE_RIGHT_ICON); - mActivity.getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, - new BitmapDrawable(mActivity.getResources(), icon)); - } - - @Override - public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { - final UiFacade uiFacade = mReceiverManager.getReceiver(UiFacade.class); - uiFacade.dialogCreateAlert(JS_TITLE, message); - uiFacade.dialogSetPositiveButtonText(mResources.getString(android.R.string.ok)); - - mmExecutor.execute(new Runnable() { - - @Override - public void run() { - try { - uiFacade.dialogShow(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - uiFacade.dialogGetResponse(); - result.confirm(); - } - }); - return true; - } - - @SuppressWarnings("unchecked") - @Override - public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { - final UiFacade uiFacade = mReceiverManager.getReceiver(UiFacade.class); - uiFacade.dialogCreateAlert(JS_TITLE, message); - uiFacade.dialogSetPositiveButtonText(mResources.getString(android.R.string.ok)); - uiFacade.dialogSetNegativeButtonText(mResources.getString(android.R.string.cancel)); - - mmExecutor.execute(new Runnable() { - - @Override - public void run() { - try { - uiFacade.dialogShow(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - Map<String, Object> mResultMap = (Map<String, Object>) uiFacade.dialogGetResponse(); - if ("positive".equals(mResultMap.get("which"))) { - result.confirm(); - } else { - result.cancel(); - } - } - }); - - return true; - } - - @Override - public boolean onJsPrompt(WebView view, String url, final String message, - final String defaultValue, final JsPromptResult result) { - final UiFacade uiFacade = mReceiverManager.getReceiver(UiFacade.class); - mmExecutor.execute(new Runnable() { - @Override - public void run() { - String value = null; - try { - value = uiFacade.dialogGetInput(JS_TITLE, message, defaultValue); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - if (value != null) { - result.confirm(value); - } else { - result.cancel(); - } - } - }); - return true; - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/shell/ShellInterpreter.java b/sl4a/Common/src/com/googlecode/android_scripting/interpreter/shell/ShellInterpreter.java deleted file mode 100644 index a1f11ff..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/interpreter/shell/ShellInterpreter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter.shell; - -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.language.ShellLanguage; - -import java.io.File; - -/** - * Represents the shell. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ShellInterpreter extends Interpreter { - private final static String SHELL_BIN = "/system/bin/sh"; - - public ShellInterpreter() { - setExtension(".sh"); - setName("sh"); - setNiceName("Shell"); - setBinary(new File(SHELL_BIN)); - setInteractiveCommand(""); - setScriptCommand("%s"); - setLanguage(new ShellLanguage()); - setHasInteractiveMode(true); - } - - public boolean hasInterpreterArchive() { - return false; - } - - public boolean hasExtrasArchive() { - return false; - } - - public boolean hasScriptsArchive() { - return false; - } - - public int getVersion() { - return 0; - } - - @Override - public boolean isUninstallable() { - return false; - } - - @Override - public boolean isInstalled() { - return true; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java deleted file mode 100644 index 24428a4..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonBuilder.java +++ /dev/null @@ -1,1188 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.URL; -import java.security.PrivateKey; -import java.security.cert.CertificateEncodingException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.apache.commons.codec.binary.Base64Codec; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothGattCharacteristic; -import android.bluetooth.BluetoothGattDescriptor; -import android.bluetooth.BluetoothGattService; -import android.bluetooth.le.AdvertiseSettings; -import android.content.ComponentName; -import android.content.Intent; -import android.graphics.Point; -import android.location.Address; -import android.location.Location; -import android.net.DhcpInfo; -import android.net.Network; -import android.net.NetworkInfo; -import android.net.Uri; -import android.net.wifi.RttManager.RttCapabilities; -import android.net.wifi.ScanResult; -import android.net.wifi.WifiActivityEnergyInfo; -import android.net.wifi.WifiChannel; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiEnterpriseConfig; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiScanner.ScanData; -import android.net.wifi.p2p.WifiP2pDevice; -import android.net.wifi.p2p.WifiP2pGroup; -import android.net.wifi.p2p.WifiP2pInfo; -import android.os.Bundle; -import android.os.ParcelUuid; -import android.telecom.Call; -import android.telecom.CallAudioState; -import android.telecom.PhoneAccount; -import android.telecom.PhoneAccountHandle; -import android.telecom.VideoProfile; -import android.telecom.VideoProfile.CameraCapabilities; -import android.telephony.CellIdentityCdma; -import android.telephony.CellIdentityGsm; -import android.telephony.CellIdentityLte; -import android.telephony.CellIdentityWcdma; -import android.telephony.CellInfoCdma; -import android.telephony.CellInfoGsm; -import android.telephony.CellInfoLte; -import android.telephony.CellInfoWcdma; -import android.telephony.CellLocation; -import android.telephony.CellSignalStrengthCdma; -import android.telephony.CellSignalStrengthGsm; -import android.telephony.CellSignalStrengthLte; -import android.telephony.CellSignalStrengthWcdma; -import android.telephony.ModemActivityInfo; -import android.telephony.NeighboringCellInfo; -import android.telephony.SmsMessage; -import android.telephony.SignalStrength; -import android.telephony.SubscriptionInfo; -import android.telephony.gsm.GsmCellLocation; -import android.telephony.VoLteServiceState; -import android.util.Base64; -import android.util.DisplayMetrics; -import android.util.SparseArray; - -import com.googlecode.android_scripting.ConvertUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.event.Event; -//FIXME: Refactor classes, constants and conversions out of here -import com.googlecode.android_scripting.facade.telephony.InCallServiceImpl; -import com.googlecode.android_scripting.facade.telephony.TelephonyUtils; -import com.googlecode.android_scripting.facade.telephony.TelephonyConstants; - -public class JsonBuilder { - - @SuppressWarnings("unchecked") - public static Object build(Object data) throws JSONException { - if (data == null) { - return JSONObject.NULL; - } - if (data instanceof Integer) { - return data; - } - if (data instanceof Float) { - return data; - } - if (data instanceof Double) { - return data; - } - if (data instanceof Long) { - return data; - } - if (data instanceof String) { - return data; - } - if (data instanceof Boolean) { - return data; - } - if (data instanceof JsonSerializable) { - return ((JsonSerializable)data).toJSON(); - } - if (data instanceof JSONObject) { - return data; - } - if (data instanceof JSONArray) { - return data; - } - if (data instanceof Set<?>) { - List<Object> items = new ArrayList<Object>((Set<?>) data); - return buildJsonList(items); - } - if (data instanceof Collection<?>) { - List<Object> items = new ArrayList<Object>((Collection<?>) data); - return buildJsonList(items); - } - if (data instanceof List<?>) { - return buildJsonList((List<?>) data); - } - if (data instanceof Address) { - return buildJsonAddress((Address) data); - } - if (data instanceof CallAudioState) { - return buildJsonAudioState((CallAudioState) data); - } - if (data instanceof Location) { - return buildJsonLocation((Location) data); - } - if (data instanceof Bundle) { - return buildJsonBundle((Bundle) data); - } - if (data instanceof Intent) { - return buildJsonIntent((Intent) data); - } - if (data instanceof Event) { - return buildJsonEvent((Event) data); - } - if (data instanceof Map<?, ?>) { - // TODO(damonkohler): I would like to make this a checked cast if - // possible. - return buildJsonMap((Map<String, ?>) data); - } - if (data instanceof ParcelUuid) { - return data.toString(); - } - if (data instanceof ScanResult) { - return buildJsonScanResult((ScanResult) data); - } - if (data instanceof ScanData) { - return buildJsonScanData((ScanData) data); - } - if (data instanceof android.bluetooth.le.ScanResult) { - return buildJsonBleScanResult((android.bluetooth.le.ScanResult) data); - } - if (data instanceof AdvertiseSettings) { - return buildJsonBleAdvertiseSettings((AdvertiseSettings) data); - } - if (data instanceof BluetoothGattService) { - return buildJsonBluetoothGattService((BluetoothGattService) data); - } - if (data instanceof BluetoothGattCharacteristic) { - return buildJsonBluetoothGattCharacteristic((BluetoothGattCharacteristic) data); - } - if (data instanceof BluetoothGattDescriptor) { - return buildJsonBluetoothGattDescriptor((BluetoothGattDescriptor) data); - } - if (data instanceof BluetoothDevice) { - return buildJsonBluetoothDevice((BluetoothDevice) data); - } - if (data instanceof CellLocation) { - return buildJsonCellLocation((CellLocation) data); - } - if (data instanceof WifiInfo) { - return buildJsonWifiInfo((WifiInfo) data); - } - if (data instanceof NeighboringCellInfo) { - return buildNeighboringCellInfo((NeighboringCellInfo) data); - } - if (data instanceof Network) { - return buildNetwork((Network) data); - } - if (data instanceof NetworkInfo) { - return buildNetworkInfo((NetworkInfo) data); - } - if (data instanceof HttpURLConnection) { - return buildHttpURLConnection((HttpURLConnection) data); - } - if (data instanceof InetSocketAddress) { - return buildInetSocketAddress((InetSocketAddress) data); - } - if (data instanceof InetAddress) { - return buildInetAddress((InetAddress) data); - } - if (data instanceof URL) { - return buildURL((URL) data); - } - if (data instanceof Point) { - return buildPoint((Point) data); - } - if (data instanceof SmsMessage) { - return buildSmsMessage((SmsMessage) data); - } - if (data instanceof PhoneAccount) { - return buildPhoneAccount((PhoneAccount) data); - } - if (data instanceof PhoneAccountHandle) { - return buildPhoneAccountHandle((PhoneAccountHandle) data); - } - if (data instanceof SubscriptionInfo) { - return buildSubscriptionInfoRecord((SubscriptionInfo) data); - } - if (data instanceof DhcpInfo) { - return buildDhcpInfo((DhcpInfo) data); - } - if (data instanceof DisplayMetrics) { - return buildDisplayMetrics((DisplayMetrics) data); - } - if (data instanceof RttCapabilities) { - return buildRttCapabilities((RttCapabilities) data); - } - if (data instanceof WifiActivityEnergyInfo) { - return buildWifiActivityEnergyInfo((WifiActivityEnergyInfo) data); - } - if (data instanceof WifiChannel) { - return buildWifiChannel((WifiChannel) data); - } - if (data instanceof WifiConfiguration) { - return buildWifiConfiguration((WifiConfiguration) data); - } - if (data instanceof WifiP2pDevice) { - return buildWifiP2pDevice((WifiP2pDevice) data); - } - if (data instanceof WifiP2pInfo) { - return buildWifiP2pInfo((WifiP2pInfo) data); - } - if (data instanceof WifiP2pGroup) { - return buildWifiP2pGroup((WifiP2pGroup) data); - } - if (data instanceof byte[]) { - return Base64Codec.encodeBase64((byte[]) data); - } - if (data instanceof Object[]) { - return buildJSONArray((Object[]) data); - } - if (data instanceof CellInfoLte) { - return buildCellInfoLte((CellInfoLte) data); - } - if (data instanceof CellInfoWcdma) { - return buildCellInfoWcdma((CellInfoWcdma) data); - } - if (data instanceof CellInfoGsm) { - return buildCellInfoGsm((CellInfoGsm) data); - } - if (data instanceof CellInfoCdma) { - return buildCellInfoCdma((CellInfoCdma) data); - } - if (data instanceof Call) { - return buildCall((Call) data); - } - if (data instanceof Call.Details) { - return buildCallDetails((Call.Details) data); - } - if (data instanceof InCallServiceImpl.CallEvent<?>) { - return buildCallEvent((InCallServiceImpl.CallEvent<?>) data); - } - if (data instanceof VideoProfile) { - return buildVideoProfile((VideoProfile) data); - } - if (data instanceof CameraCapabilities) { - return buildCameraCapabilities((CameraCapabilities) data); - } - if (data instanceof VoLteServiceState) { - return buildVoLteServiceStateEvent((VoLteServiceState) data); - } - if (data instanceof ModemActivityInfo) { - return buildModemActivityInfo((ModemActivityInfo) data); - } - if (data instanceof SignalStrength) { - return buildSignalStrength((SignalStrength) data); - } - - - return data.toString(); - // throw new JSONException("Failed to build JSON result. " + - // data.getClass().getName()); - } - - private static JSONObject buildJsonAudioState(CallAudioState data) - throws JSONException { - JSONObject state = new JSONObject(); - state.put("isMuted", data.isMuted()); - state.put("AudioRoute", InCallServiceImpl.getAudioRouteString(data.getRoute())); - return state; - } - - private static Object buildDisplayMetrics(DisplayMetrics data) - throws JSONException { - JSONObject dm = new JSONObject(); - dm.put("widthPixels", data.widthPixels); - dm.put("heightPixels", data.heightPixels); - dm.put("noncompatHeightPixels", data.noncompatHeightPixels); - dm.put("noncompatWidthPixels", data.noncompatWidthPixels); - return dm; - } - - private static Object buildInetAddress(InetAddress data) { - JSONArray address = new JSONArray(); - address.put(data.getHostName()); - address.put(data.getHostAddress()); - return address; - } - - private static Object buildInetSocketAddress(InetSocketAddress data) { - JSONArray address = new JSONArray(); - address.put(data.getHostName()); - address.put(data.getPort()); - return address; - } - - private static JSONObject buildJsonAddress(Address address) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("admin_area", address.getAdminArea()); - result.put("country_code", address.getCountryCode()); - result.put("country_name", address.getCountryName()); - result.put("feature_name", address.getFeatureName()); - result.put("phone", address.getPhone()); - result.put("locality", address.getLocality()); - result.put("postal_code", address.getPostalCode()); - result.put("sub_admin_area", address.getSubAdminArea()); - result.put("thoroughfare", address.getThoroughfare()); - result.put("url", address.getUrl()); - return result; - } - - private static JSONArray buildJSONArray(Object[] data) throws JSONException { - JSONArray result = new JSONArray(); - for (Object o : data) { - result.put(build(o)); - } - return result; - } - - private static JSONObject buildJsonBleAdvertiseSettings( - AdvertiseSettings advertiseSettings) throws JSONException { - JSONObject result = new JSONObject(); - result.put("mode", advertiseSettings.getMode()); - result.put("txPowerLevel", advertiseSettings.getTxPowerLevel()); - result.put("isConnectable", advertiseSettings.isConnectable()); - return result; - } - - private static JSONObject buildJsonBleScanResult( - android.bluetooth.le.ScanResult scanResult) throws JSONException { - JSONObject result = new JSONObject(); - result.put("rssi", scanResult.getRssi()); - result.put("timestampNanos", scanResult.getTimestampNanos()); - result.put("deviceName", scanResult.getScanRecord().getDeviceName()); - result.put("txPowerLevel", scanResult.getScanRecord().getTxPowerLevel()); - result.put("advertiseFlags", scanResult.getScanRecord() - .getAdvertiseFlags()); - ArrayList<String> manufacturerDataList = new ArrayList<String>(); - ArrayList<Integer> idList = new ArrayList<Integer>(); - if (scanResult.getScanRecord().getManufacturerSpecificData() != null) { - SparseArray<byte[]> manufacturerSpecificData = scanResult - .getScanRecord().getManufacturerSpecificData(); - for (int i = 0; i < manufacturerSpecificData.size(); i++) { - manufacturerDataList.add(ConvertUtils - .convertByteArrayToString(manufacturerSpecificData - .valueAt(i))); - idList.add(manufacturerSpecificData.keyAt(i)); - } - } - result.put("manufacturerSpecificDataList", manufacturerDataList); - result.put("manufacturereIdList", idList); - ArrayList<String> serviceUuidList = new ArrayList<String>(); - ArrayList<String> serviceDataList = new ArrayList<String>(); - if (scanResult.getScanRecord().getServiceData() != null) { - Map<ParcelUuid, byte[]> serviceDataMap = scanResult.getScanRecord() - .getServiceData(); - for (ParcelUuid serviceUuid : serviceDataMap.keySet()) { - serviceUuidList.add(serviceUuid.toString()); - serviceDataList.add(ConvertUtils - .convertByteArrayToString(serviceDataMap - .get(serviceUuid))); - } - } - result.put("serviceUuidList", serviceUuidList); - result.put("serviceDataList", serviceDataList); - List<ParcelUuid> serviceUuids = scanResult.getScanRecord() - .getServiceUuids(); - String serviceUuidsString = ""; - if (serviceUuids != null && serviceUuids.size() > 0) { - for (ParcelUuid uuid : serviceUuids) { - serviceUuidsString = serviceUuidsString + "," + uuid; - } - } - result.put("serviceUuids", serviceUuidsString); - result.put("scanRecord", - build(ConvertUtils.convertByteArrayToString(scanResult - .getScanRecord().getBytes()))); - result.put("deviceInfo", build(scanResult.getDevice())); - return result; - } - - private static JSONObject buildJsonBluetoothDevice(BluetoothDevice data) - throws JSONException { - JSONObject deviceInfo = new JSONObject(); - deviceInfo.put("address", data.getAddress()); - deviceInfo.put("state", data.getBondState()); - deviceInfo.put("name", data.getName()); - deviceInfo.put("type", data.getType()); - return deviceInfo; - } - - private static Object buildJsonBluetoothGattCharacteristic( - BluetoothGattCharacteristic data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("instanceId", data.getInstanceId()); - result.put("permissions", data.getPermissions()); - result.put("properties", data.getProperties()); - result.put("writeType", data.getWriteType()); - result.put("descriptorsList", build(data.getDescriptors())); - result.put("uuid", data.getUuid().toString()); - result.put("value", build(data.getValue())); - - return result; - } - - private static Object buildJsonBluetoothGattDescriptor( - BluetoothGattDescriptor data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("instanceId", data.getInstanceId()); - result.put("permissions", data.getPermissions()); - result.put("characteristic", data.getCharacteristic()); - result.put("uuid", data.getUuid().toString()); - result.put("value", build(data.getValue())); - return result; - } - - private static Object buildJsonBluetoothGattService( - BluetoothGattService data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("instanceId", data.getInstanceId()); - result.put("type", data.getType()); - result.put("gattCharacteristicList", build(data.getCharacteristics())); - result.put("includedServices", build(data.getIncludedServices())); - result.put("uuid", data.getUuid().toString()); - return result; - } - - private static JSONObject buildJsonBundle(Bundle bundle) - throws JSONException { - JSONObject result = new JSONObject(); - for (String key : bundle.keySet()) { - result.put(key, build(bundle.get(key))); - } - return result; - } - - private static JSONObject buildJsonCellLocation(CellLocation cellLocation) - throws JSONException { - JSONObject result = new JSONObject(); - if (cellLocation instanceof GsmCellLocation) { - GsmCellLocation location = (GsmCellLocation) cellLocation; - result.put("lac", location.getLac()); - result.put("cid", location.getCid()); - } - // TODO(damonkohler): Add support for CdmaCellLocation. Not supported - // until API level 5. - return result; - } - - private static JSONObject buildDhcpInfo(DhcpInfo data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("ipAddress", data.ipAddress); - result.put("dns1", data.dns1); - result.put("dns2", data.dns2); - result.put("gateway", data.gateway); - result.put("serverAddress", data.serverAddress); - result.put("leaseDuration", data.leaseDuration); - return result; - } - - private static JSONObject buildJsonEvent(Event event) throws JSONException { - JSONObject result = new JSONObject(); - result.put("name", event.getName()); - result.put("data", build(event.getData())); - result.put("time", event.getCreationTime()); - return result; - } - - private static JSONObject buildJsonIntent(Intent data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("data", data.getDataString()); - result.put("type", data.getType()); - result.put("extras", build(data.getExtras())); - result.put("categories", build(data.getCategories())); - result.put("action", data.getAction()); - ComponentName component = data.getComponent(); - if (component != null) { - result.put("packagename", component.getPackageName()); - result.put("classname", component.getClassName()); - } - result.put("flags", data.getFlags()); - return result; - } - - private static <T> JSONArray buildJsonList(final List<T> list) - throws JSONException { - JSONArray result = new JSONArray(); - for (T item : list) { - result.put(build(item)); - } - return result; - } - - private static JSONObject buildJsonLocation(Location location) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("altitude", location.getAltitude()); - result.put("latitude", location.getLatitude()); - result.put("longitude", location.getLongitude()); - result.put("time", location.getTime()); - result.put("accuracy", location.getAccuracy()); - result.put("speed", location.getSpeed()); - result.put("provider", location.getProvider()); - result.put("bearing", location.getBearing()); - return result; - } - - private static JSONObject buildJsonMap(Map<String, ?> map) - throws JSONException { - JSONObject result = new JSONObject(); - for (Entry<String, ?> entry : map.entrySet()) { - String key = entry.getKey(); - if (key == null) { - key = ""; - } - result.put(key, build(entry.getValue())); - } - return result; - } - - private static JSONObject buildJsonScanResult(ScanResult scanResult) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("BSSID", scanResult.BSSID); - result.put("SSID", scanResult.SSID); - result.put("frequency", scanResult.frequency); - result.put("level", scanResult.level); - result.put("capabilities", scanResult.capabilities); - result.put("timestamp", scanResult.timestamp); - result.put("autoJoinStatus", scanResult.autoJoinStatus); - result.put("blackListTimestamp", scanResult.blackListTimestamp); - result.put("centerFreq0", scanResult.centerFreq0); - result.put("centerFreq1", scanResult.centerFreq1); - result.put("channelWidth", scanResult.channelWidth); - result.put("distanceCm", scanResult.distanceCm); - result.put("distanceSdCm", scanResult.distanceSdCm); - result.put("is80211McRTTResponder", scanResult.is80211mcResponder()); - result.put("isAutoJoinCandidate", scanResult.isAutoJoinCandidate); - result.put("numConnection", scanResult.numConnection); - result.put("passpointNetwork", scanResult.isPasspointNetwork()); - result.put("numIpConfigFailures", scanResult.numIpConfigFailures); - result.put("numUsage", scanResult.numUsage); - result.put("seen", scanResult.seen); - result.put("untrusted", scanResult.untrusted); - result.put("operatorFriendlyName", scanResult.operatorFriendlyName); - result.put("venueName", scanResult.venueName); - if (scanResult.informationElements != null) { - JSONArray infoEles = new JSONArray(); - for (ScanResult.InformationElement ie : scanResult.informationElements) { - JSONObject infoEle = new JSONObject(); - infoEle.put("id", ie.id); - infoEle.put("bytes", Base64Codec.encodeBase64(ie.bytes).toString()); - infoEles.put(infoEle); - } - result.put("InfomationElements", infoEles); - } else { - result.put("InfomationElements", null); - } - return result; - } - - private static JSONObject buildJsonScanData(ScanData scanData) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("Id", scanData.getId()); - result.put("Flags", scanData.getFlags()); - JSONArray scanResults = new JSONArray(); - for (ScanResult sr : scanData.getResults()) { - scanResults.put(buildJsonScanResult(sr)); - } - result.put("ScanResults", scanResults); - return result; - } - - private static JSONObject buildJsonWifiInfo(WifiInfo data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("hidden_ssid", data.getHiddenSSID()); - result.put("ip_address", data.getIpAddress()); - result.put("link_speed", data.getLinkSpeed()); - result.put("network_id", data.getNetworkId()); - result.put("rssi", data.getRssi()); - result.put("BSSID", data.getBSSID()); - result.put("mac_address", data.getMacAddress()); - // Trim the double quotes if exist - String ssid = data.getSSID(); - if (ssid.charAt(0) == '"' - && ssid.charAt(ssid.length() - 1) == '"') { - result.put("SSID", ssid.substring(1, ssid.length() - 1)); - } else { - result.put("SSID", ssid); - } - String supplicantState = ""; - switch (data.getSupplicantState()) { - case ASSOCIATED: - supplicantState = "associated"; - break; - case ASSOCIATING: - supplicantState = "associating"; - break; - case COMPLETED: - supplicantState = "completed"; - break; - case DISCONNECTED: - supplicantState = "disconnected"; - break; - case DORMANT: - supplicantState = "dormant"; - break; - case FOUR_WAY_HANDSHAKE: - supplicantState = "four_way_handshake"; - break; - case GROUP_HANDSHAKE: - supplicantState = "group_handshake"; - break; - case INACTIVE: - supplicantState = "inactive"; - break; - case INVALID: - supplicantState = "invalid"; - break; - case SCANNING: - supplicantState = "scanning"; - break; - case UNINITIALIZED: - supplicantState = "uninitialized"; - break; - default: - supplicantState = null; - } - result.put("supplicant_state", build(supplicantState)); - result.put("is_5ghz", data.is5GHz()); - result.put("is_24ghz", data.is24GHz()); - return result; - } - - private static JSONObject buildNeighboringCellInfo(NeighboringCellInfo data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("cid", data.getCid()); - result.put("rssi", data.getRssi()); - result.put("lac", data.getLac()); - result.put("psc", data.getPsc()); - String networkType = - TelephonyUtils.getNetworkTypeString(data.getNetworkType()); - result.put("network_type", build(networkType)); - return result; - } - - private static JSONObject buildCellInfoLte(CellInfoLte data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("rat", "lte"); - result.put("registered", data.isRegistered()); - CellIdentityLte cellidentity = - ((CellInfoLte) data).getCellIdentity(); - CellSignalStrengthLte signalstrength = - ((CellInfoLte) data).getCellSignalStrength(); - result.put("mcc", cellidentity.getMcc()); - result.put("mnc", cellidentity.getMnc()); - result.put("cid", cellidentity.getCi()); - result.put("pcid", cellidentity.getPci()); - result.put("tac", cellidentity.getTac()); - result.put("rsrp", signalstrength.getDbm()); - result.put("asulevel", signalstrength.getAsuLevel()); - result.put("timing_advance", signalstrength.getTimingAdvance()); - return result; - } - - private static JSONObject buildCellInfoGsm(CellInfoGsm data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("rat", "gsm"); - result.put("registered", data.isRegistered()); - CellIdentityGsm cellidentity = - ((CellInfoGsm) data).getCellIdentity(); - CellSignalStrengthGsm signalstrength = - ((CellInfoGsm) data).getCellSignalStrength(); - result.put("mcc", cellidentity.getMcc()); - result.put("mnc", cellidentity.getMnc()); - result.put("cid", cellidentity.getCid()); - result.put("lac", cellidentity.getLac()); - result.put("signal_strength", signalstrength.getDbm()); - result.put("asulevel", signalstrength.getAsuLevel()); - return result; - } - - private static JSONObject buildCellInfoWcdma(CellInfoWcdma data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("rat", "wcdma"); - result.put("registered", data.isRegistered()); - CellIdentityWcdma cellidentity = - ((CellInfoWcdma) data).getCellIdentity(); - CellSignalStrengthWcdma signalstrength = - ((CellInfoWcdma) data).getCellSignalStrength(); - result.put("mcc", cellidentity.getMcc()); - result.put("mnc", cellidentity.getMnc()); - result.put("cid", cellidentity.getCid()); - result.put("lac", cellidentity.getLac()); - result.put("psc", cellidentity.getPsc()); - result.put("signal_strength", signalstrength.getDbm()); - result.put("asulevel", signalstrength.getAsuLevel()); - return result; - } - - private static JSONObject buildCellInfoCdma(CellInfoCdma data) - throws JSONException { - JSONObject result = new JSONObject(); - result.put("rat", "cdma"); - result.put("registered", data.isRegistered()); - CellIdentityCdma cellidentity = - ((CellInfoCdma) data).getCellIdentity(); - CellSignalStrengthCdma signalstrength = - ((CellInfoCdma) data).getCellSignalStrength(); - result.put("network_id", cellidentity.getNetworkId()); - result.put("system_id", cellidentity.getSystemId()); - result.put("basestation_id", cellidentity.getBasestationId()); - result.put("longitude", cellidentity.getLongitude()); - result.put("latitude", cellidentity.getLatitude()); - result.put("cdma_dbm", signalstrength.getCdmaDbm()); - result.put("cdma_ecio", signalstrength.getCdmaEcio()); - result.put("evdo_dbm", signalstrength.getEvdoDbm()); - result.put("evdo_ecio", signalstrength.getEvdoEcio()); - result.put("evdo_snr", signalstrength.getEvdoSnr()); - return result; - } - - private static Object buildHttpURLConnection(HttpURLConnection data) - throws JSONException { - JSONObject con = new JSONObject(); - try { - con.put("ResponseCode", data.getResponseCode()); - con.put("ResponseMessage", data.getResponseMessage()); - } catch (IOException e) { - e.printStackTrace(); - return con; - } - con.put("ContentLength", data.getContentLength()); - con.put("ContentEncoding", data.getContentEncoding()); - con.put("ContentType", data.getContentType()); - con.put("Date", data.getDate()); - con.put("ReadTimeout", data.getReadTimeout()); - con.put("HeaderFields", buildJsonMap(data.getHeaderFields())); - con.put("URL", buildURL(data.getURL())); - return con; - } - - private static Object buildNetwork(Network data) throws JSONException { - JSONObject nw = new JSONObject(); - nw.put("netId", data.netId); - return nw; - } - - private static Object buildNetworkInfo(NetworkInfo data) - throws JSONException { - JSONObject info = new JSONObject(); - info.put("isAvailable", data.isAvailable()); - info.put("isConnected", data.isConnected()); - info.put("isFailover", data.isFailover()); - info.put("isRoaming", data.isRoaming()); - info.put("ExtraInfo", data.getExtraInfo()); - info.put("FailedReason", data.getReason()); - info.put("TypeName", data.getTypeName()); - info.put("SubtypeName", data.getSubtypeName()); - info.put("State", data.getState().name().toString()); - return info; - } - - private static Object buildURL(URL data) throws JSONException { - JSONObject url = new JSONObject(); - url.put("Authority", data.getAuthority()); - url.put("Host", data.getHost()); - url.put("Path", data.getPath()); - url.put("Port", data.getPort()); - url.put("Protocol", data.getProtocol()); - return url; - } - - private static JSONObject buildPhoneAccount(PhoneAccount data) - throws JSONException { - JSONObject acct = new JSONObject(); - acct.put("Address", data.getAddress().toSafeString()); - acct.put("SubscriptionAddress", data.getSubscriptionAddress() - .toSafeString()); - acct.put("Label", ((data.getLabel() != null) ? data.getLabel().toString() : "")); - acct.put("ShortDescription", ((data.getShortDescription() != null) ? data - .getShortDescription().toString() : "")); - return acct; - } - - private static Object buildPhoneAccountHandle(PhoneAccountHandle data) - throws JSONException { - JSONObject msg = new JSONObject(); - msg.put("id", data.getId()); - msg.put("ComponentName", data.getComponentName().flattenToString()); - return msg; - } - - private static Object buildSubscriptionInfoRecord(SubscriptionInfo data) - throws JSONException { - JSONObject msg = new JSONObject(); - msg.put("subscriptionId", data.getSubscriptionId()); - msg.put("iccId", data.getIccId()); - msg.put("simSlotIndex", data.getSimSlotIndex()); - msg.put("displayName", data.getDisplayName()); - msg.put("nameSource", data.getNameSource()); - msg.put("iconTint", data.getIconTint()); - msg.put("number", data.getNumber()); - msg.put("dataRoaming", data.getDataRoaming()); - msg.put("mcc", data.getMcc()); - msg.put("mnc", data.getMnc()); - return msg; - } - - private static Object buildPoint(Point data) throws JSONException { - JSONObject point = new JSONObject(); - point.put("x", data.x); - point.put("y", data.y); - return point; - } - - private static Object buildRttCapabilities(RttCapabilities data) - throws JSONException { - JSONObject cap = new JSONObject(); - cap.put("bwSupported", data.bwSupported); - cap.put("lciSupported", data.lciSupported); - cap.put("lcrSupported", data.lcrSupported); - cap.put("oneSidedRttSupported", data.oneSidedRttSupported); - cap.put("preambleSupported", data.preambleSupported); - cap.put("twoSided11McRttSupported", data.twoSided11McRttSupported); - return cap; - } - - private static Object buildSmsMessage(SmsMessage data) throws JSONException { - JSONObject msg = new JSONObject(); - msg.put("originatingAddress", data.getOriginatingAddress()); - msg.put("messageBody", data.getMessageBody()); - return msg; - } - - private static JSONObject buildWifiActivityEnergyInfo( - WifiActivityEnergyInfo data) throws JSONException { - JSONObject result = new JSONObject(); - result.put("ControllerEnergyUsed", data.getControllerEnergyUsed()); - result.put("ControllerIdleTimeMillis", - data.getControllerIdleTimeMillis()); - result.put("ControllerRxTimeMillis", data.getControllerRxTimeMillis()); - result.put("ControllerTxTimeMillis", data.getControllerTxTimeMillis()); - result.put("StackState", data.getStackState()); - result.put("TimeStamp", data.getTimeStamp()); - return result; - } - - private static Object buildWifiChannel(WifiChannel data) throws JSONException { - JSONObject channel = new JSONObject(); - channel.put("channelNum", data.channelNum); - channel.put("freqMHz", data.freqMHz); - channel.put("isDFS", data.isDFS); - channel.put("isValid", data.isValid()); - return channel; - } - - private static Object buildWifiConfiguration(WifiConfiguration data) - throws JSONException { - JSONObject config = new JSONObject(); - config.put("networkId", data.networkId); - // Trim the double quotes if exist - if (data.SSID.charAt(0) == '"' - && data.SSID.charAt(data.SSID.length() - 1) == '"') { - config.put("SSID", data.SSID.substring(1, data.SSID.length() - 1)); - } else { - config.put("SSID", data.SSID); - } - config.put("BSSID", data.BSSID); - config.put("priority", data.priority); - config.put("hiddenSSID", data.hiddenSSID); - config.put("FQDN", data.FQDN); - config.put("providerFriendlyName", data.providerFriendlyName); - config.put("isPasspoint", data.isPasspoint()); - config.put("hiddenSSID", data.hiddenSSID); - if (data.status == WifiConfiguration.Status.CURRENT) { - config.put("status", "CURRENT"); - } else if (data.status == WifiConfiguration.Status.DISABLED) { - config.put("status", "DISABLED"); - } else if (data.status == WifiConfiguration.Status.ENABLED) { - config.put("status", "ENABLED"); - } else { - config.put("status", "UNKNOWN"); - } - // config.put("enterpriseConfig", buildWifiEnterpriseConfig(data.enterpriseConfig)); - return config; - } - - private static Object buildWifiEnterpriseConfig(WifiEnterpriseConfig data) - throws JSONException, CertificateEncodingException { - JSONObject config = new JSONObject(); - config.put(WifiEnterpriseConfig.PLMN_KEY, data.getPlmn()); - config.put(WifiEnterpriseConfig.REALM_KEY, data.getRealm()); - config.put(WifiEnterpriseConfig.EAP_KEY, data.getEapMethod()); - config.put(WifiEnterpriseConfig.PHASE2_KEY, data.getPhase2Method()); - config.put(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, data.getAltSubjectMatch()); - X509Certificate caCert = data.getCaCertificate(); - String caCertString = Base64.encodeToString(caCert.getEncoded(), Base64.DEFAULT); - config.put(WifiEnterpriseConfig.CA_CERT_KEY, caCertString); - X509Certificate clientCert = data.getClientCertificate(); - String clientCertString = Base64.encodeToString(clientCert.getEncoded(), Base64.DEFAULT); - config.put(WifiEnterpriseConfig.CLIENT_CERT_KEY, clientCertString); - PrivateKey pk = data.getClientPrivateKey(); - String privateKeyString = Base64.encodeToString(pk.getEncoded(), Base64.DEFAULT); - config.put(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, privateKeyString); - config.put(WifiEnterpriseConfig.PASSWORD_KEY, data.getPassword()); - return config; - } - - private static JSONObject buildWifiP2pDevice(WifiP2pDevice data) - throws JSONException { - JSONObject deviceInfo = new JSONObject(); - deviceInfo.put("Name", data.deviceName); - deviceInfo.put("Address", data.deviceAddress); - return deviceInfo; - } - - private static JSONObject buildWifiP2pGroup(WifiP2pGroup data) - throws JSONException { - JSONObject group = new JSONObject(); - Log.d("build p2p group."); - group.put("ClientList", build(data.getClientList())); - group.put("Interface", data.getInterface()); - group.put("Networkname", data.getNetworkName()); - group.put("Owner", data.getOwner()); - group.put("Passphrase", data.getPassphrase()); - group.put("NetworkId", data.getNetworkId()); - return group; - } - - private static JSONObject buildWifiP2pInfo(WifiP2pInfo data) - throws JSONException { - JSONObject info = new JSONObject(); - Log.d("build p2p info."); - info.put("groupFormed", data.groupFormed); - info.put("isGroupOwner", data.isGroupOwner); - info.put("groupOwnerAddress", data.groupOwnerAddress); - return info; - } - - private static <T> JSONObject buildCallEvent(InCallServiceImpl.CallEvent<T> callEvent) - throws JSONException { - JSONObject jsonEvent = new JSONObject(); - jsonEvent.put("CallId", callEvent.getCallId()); - jsonEvent.put("Event", build(callEvent.getEvent())); - return jsonEvent; - } - - private static JSONObject buildUri(Uri uri) throws JSONException { - return new JSONObject().put("Uri", build((uri != null) ? uri.toString() : "")); - } - - private static JSONObject buildCallDetails(Call.Details details) throws JSONException { - - JSONObject callDetails = new JSONObject(); - - callDetails.put("Handle", buildUri(details.getHandle())); - callDetails.put("HandlePresentation", - build(InCallServiceImpl.getCallPresentationInfoString( - details.getHandlePresentation()))); - callDetails.put("CallerDisplayName", build(details.getCallerDisplayName())); - - // TODO AccountHandle - // callDetails.put("AccountHandle", build("")); - - callDetails.put("Capabilities", - build(InCallServiceImpl.getCallCapabilitiesString(details.getCallCapabilities()))); - - callDetails.put("Properties", - build(InCallServiceImpl.getCallPropertiesString(details.getCallProperties()))); - - // TODO Parse fields in Disconnect Cause - callDetails.put("DisconnectCause", build((details.getDisconnectCause() != null) ? details - .getDisconnectCause().toString() : "")); - callDetails.put("ConnectTimeMillis", build(details.getConnectTimeMillis())); - - // TODO: GatewayInfo - // callDetails.put("GatewayInfo", build("")); - - callDetails.put("VideoState", - build(InCallServiceImpl.getVideoCallStateString(details.getVideoState()))); - - // TODO: StatusHints - // callDetails.put("StatusHints", build("")); - - callDetails.put("Extras", build(details.getExtras())); - - return callDetails; - } - - private static JSONObject buildCall(Call call) throws JSONException { - - JSONObject callInfo = new JSONObject(); - - callInfo.put("Parent", build(InCallServiceImpl.getCallId(call))); - - // TODO:Make a function out of this for consistency - ArrayList<String> children = new ArrayList<String>(); - for (Call child : call.getChildren()) { - children.add(InCallServiceImpl.getCallId(child)); - } - callInfo.put("Children", build(children)); - - // TODO:Make a function out of this for consistency - ArrayList<String> conferenceables = new ArrayList<String>(); - for (Call conferenceable : call.getChildren()) { - children.add(InCallServiceImpl.getCallId(conferenceable)); - } - callInfo.put("ConferenceableCalls", build(conferenceables)); - - callInfo.put("State", build(InCallServiceImpl.getCallStateString(call.getState()))); - callInfo.put("CannedTextResponses", build(call.getCannedTextResponses())); - callInfo.put("VideoCall", InCallServiceImpl.getVideoCallId(call.getVideoCall())); - callInfo.put("Details", build(call.getDetails())); - - return callInfo; - } - - private static JSONObject buildVideoProfile(VideoProfile videoProfile) throws JSONException { - JSONObject profile = new JSONObject(); - - profile.put("VideoState", - InCallServiceImpl.getVideoCallStateString(videoProfile.getVideoState())); - profile.put("VideoQuality", - InCallServiceImpl.getVideoCallQualityString(videoProfile.getQuality())); - - return profile; - } - - private static JSONObject buildCameraCapabilities(CameraCapabilities cameraCapabilities) - throws JSONException { - JSONObject capabilities = new JSONObject(); - - capabilities.put("Height", build(cameraCapabilities.getHeight())); - capabilities.put("Width", build(cameraCapabilities.getWidth())); - capabilities.put("ZoomSupported", build(cameraCapabilities.isZoomSupported())); - capabilities.put("MaxZoom", build(cameraCapabilities.getMaxZoom())); - - return capabilities; - } - - private static JSONObject buildVoLteServiceStateEvent( - VoLteServiceState volteInfo) - throws JSONException { - JSONObject info = new JSONObject(); - info.put(TelephonyConstants.VoLteServiceStateContainer.SRVCC_STATE, - TelephonyUtils.getSrvccStateString(volteInfo.getSrvccState())); - return info; - } - - private static JSONObject buildModemActivityInfo(ModemActivityInfo modemInfo) - throws JSONException { - JSONObject info = new JSONObject(); - - info.put("Timestamp", modemInfo.getTimestamp()); - info.put("SleepTimeMs", modemInfo.getSleepTimeMillis()); - info.put("IdleTimeMs", modemInfo.getIdleTimeMillis()); - //convert from int[] to List<Integer> for proper JSON translation - int[] txTimes = modemInfo.getTxTimeMillis(); - List<Integer> tmp = new ArrayList<Integer>(txTimes.length); - for(int val : txTimes) { - tmp.add(val); - } - info.put("TxTimeMs", build(tmp)); - info.put("RxTimeMs", modemInfo.getRxTimeMillis()); - info.put("EnergyUsedMw", modemInfo.getEnergyUsed()); - return info; - } - private static JSONObject buildSignalStrength(SignalStrength signalStrength) - throws JSONException { - JSONObject info = new JSONObject(); - info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM, - signalStrength.getGsmSignalStrength()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_DBM, - signalStrength.getGsmDbm()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_LEVEL, - signalStrength.getGsmLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_ASU_LEVEL, - signalStrength.getGsmAsuLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_GSM_BIT_ERROR_RATE, - signalStrength.getGsmBitErrorRate()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_DBM, - signalStrength.getCdmaDbm()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_LEVEL, - signalStrength.getCdmaLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_ASU_LEVEL, - signalStrength.getCdmaAsuLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_CDMA_ECIO, - signalStrength.getCdmaEcio()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_EVDO_DBM, - signalStrength.getEvdoDbm()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_EVDO_ECIO, - signalStrength.getEvdoEcio()); - info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE, - signalStrength.getLteSignalStrength()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_DBM, - signalStrength.getLteDbm()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_LEVEL, - signalStrength.getLteLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LTE_ASU_LEVEL, - signalStrength.getLteAsuLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_LEVEL, - signalStrength.getLevel()); - info.put( - TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_ASU_LEVEL, - signalStrength.getAsuLevel()); - info.put(TelephonyConstants.SignalStrengthContainer.SIGNAL_STRENGTH_DBM, - signalStrength.getDbm()); - return info; - } - - private JsonBuilder() { - // This is a utility class. - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonDeserializable.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonDeserializable.java deleted file mode 100644 index a577fdc..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonDeserializable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import org.json.JSONException; -import org.json.JSONObject; - -public interface JsonDeserializable { - public JSONObject fromJSON() throws JSONException; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcResult.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcResult.java deleted file mode 100644 index b9f3d67..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcResult.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Represents a JSON RPC result. - * - * @see http://json-rpc.org/wiki/specification - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class JsonRpcResult { - - private JsonRpcResult() { - // Utility class. - } - - public static JSONObject empty(int id) throws JSONException { - JSONObject json = new JSONObject(); - json.put("id", id); - json.put("result", JSONObject.NULL); - json.put("error", JSONObject.NULL); - return json; - } - - public static JSONObject result(int id, Object data) throws JSONException { - JSONObject json = new JSONObject(); - json.put("id", id); - json.put("result", JsonBuilder.build(data)); - json.put("error", JSONObject.NULL); - return json; - } - - public static JSONObject error(int id, Throwable t) throws JSONException { - JSONObject json = new JSONObject(); - json.put("id", id); - json.put("result", JSONObject.NULL); - json.put("error", t.toString()); - return json; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcServer.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcServer.java deleted file mode 100644 index 5bdd99a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonRpcServer.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import java.io.BufferedReader; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.Map; - -import org.json.JSONArray; -import org.json.JSONObject; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SimpleServer; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.RpcError; - -/** - * A JSON RPC server that forwards RPC calls to a specified receiver object. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class JsonRpcServer extends SimpleServer { - - private static final String CMD_CLOSE_SESSION = "closeSl4aSession"; - - private final RpcReceiverManagerFactory mRpcReceiverManagerFactory; - - // private final String mHandshake; - - /** - * Construct a {@link JsonRpcServer} connected to the provided {@link RpcReceiverManager}. - * - * @param managerFactory the {@link RpcReceiverManager} to register with the server - * @param handshake the secret handshake required for authorization to use this server - */ - public JsonRpcServer(RpcReceiverManagerFactory managerFactory, String handshake) { - // mHandshake = handshake; - mRpcReceiverManagerFactory = managerFactory; - } - - @Override - public void shutdown() { - super.shutdown(); - // Notify all RPC receiving objects. They may have to clean up some of their state. - for (RpcReceiverManager manager : mRpcReceiverManagerFactory.getRpcReceiverManagers() - .values()) { - manager.shutdown(); - } - } - - @Override - protected void handleRPCConnection(Socket sock, Integer UID, BufferedReader reader, - PrintWriter writer) throws Exception { - RpcReceiverManager receiverManager = null; - Map<Integer, RpcReceiverManager> mgrs = mRpcReceiverManagerFactory.getRpcReceiverManagers(); - synchronized (mgrs) { - Log.d("UID " + UID); - Log.d("manager map keys: " - + mRpcReceiverManagerFactory.getRpcReceiverManagers().keySet()); - if (mgrs.containsKey(UID)) { - Log.d("Look up existing session"); - receiverManager = mgrs.get(UID); - } else { - Log.d("Create a new session"); - receiverManager = mRpcReceiverManagerFactory.create(UID); - } - } - // boolean passedAuthentication = false; - String data; - while ((data = reader.readLine()) != null) { - Log.v("Session " + UID + " Received: " + data); - JSONObject request = new JSONObject(data); - int id = request.getInt("id"); - String method = request.getString("method"); - JSONArray params = request.getJSONArray("params"); - - MethodDescriptor rpc = receiverManager.getMethodDescriptor(method); - if (rpc == null) { - send(writer, JsonRpcResult.error(id, new RpcError("Unknown RPC: " + method)), UID); - continue; - } - try { - send(writer, JsonRpcResult.result(id, rpc.invoke(receiverManager, params)), UID); - } catch (Throwable t) { - Log.e("Invocation error.", t); - send(writer, JsonRpcResult.error(id, t), UID); - } - if (method.equals(CMD_CLOSE_SESSION)) { - Log.d("Got shutdown signal"); - synchronized (writer) { - receiverManager.shutdown(); - reader.close(); - writer.close(); - sock.close(); - shutdown(); - mgrs.remove(UID); - } - return; - } - } - } - - private void send(PrintWriter writer, JSONObject result, int UID) { - writer.write(result + "\n"); - writer.flush(); - Log.v("Session " + UID + " Sent: " + result); - } - - @Override - protected void handleConnection(Socket socket) throws Exception { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonSerializable.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonSerializable.java deleted file mode 100644 index 5f05d40..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/JsonSerializable.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import org.json.JSONException; -import org.json.JSONObject; - -public interface JsonSerializable { - public JSONObject toJSON() throws JSONException; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiver.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiver.java deleted file mode 100644 index e885422..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiver.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -public abstract class RpcReceiver { - - protected final RpcReceiverManager mManager; - - public RpcReceiver(RpcReceiverManager manager) { - // To make reflection easier, we ensures that all the subclasses agree on this common - // constructor. - mManager = manager; - } - - /** Invoked when the receiver is shut down. */ - public abstract void shutdown(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManager.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManager.java deleted file mode 100644 index 3f6b105..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManager.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.rpc.MethodDescriptor; - -public abstract class RpcReceiverManager { - - private final Map<Class<? extends RpcReceiver>, RpcReceiver> mReceivers; - - /** - * A map of strings to known RPCs. - */ - private final Map<String, MethodDescriptor> mKnownRpcs = new HashMap<String, MethodDescriptor>(); - - public RpcReceiverManager(Collection<Class<? extends RpcReceiver>> classList) { - mReceivers = new HashMap<Class<? extends RpcReceiver>, RpcReceiver>(); - for (Class<? extends RpcReceiver> receiverClass : classList) { - mReceivers.put(receiverClass, null); - Collection<MethodDescriptor> methodList = MethodDescriptor.collectFrom(receiverClass); - for (MethodDescriptor m : methodList) { - if (mKnownRpcs.containsKey(m.getName())) { - // We already know an RPC of the same name. We don't catch this anywhere because - // this is a programming error. - throw new RuntimeException("An RPC with the name " + m.getName() - + " is already known."); - } - mKnownRpcs.put(m.getName(), m); - } - } - } - - public Collection<Class<? extends RpcReceiver>> getRpcReceiverClasses() { - return mReceivers.keySet(); - } - - private RpcReceiver get(Class<? extends RpcReceiver> clazz) { - RpcReceiver object = mReceivers.get(clazz); - if (object != null) { - return object; - } - - Constructor<? extends RpcReceiver> constructor; - try { - constructor = clazz.getConstructor(FacadeManager.class); - object = constructor.newInstance(this); - mReceivers.put(clazz, object); - } catch (Exception e) { - Log.e(e); - } - - return object; - } - - public <T extends RpcReceiver> T getReceiver(Class<T> clazz) { - RpcReceiver receiver = get(clazz); - return clazz.cast(receiver); - } - - public MethodDescriptor getMethodDescriptor(String methodName) { - return mKnownRpcs.get(methodName); - } - - public Object invoke(Class<? extends RpcReceiver> clazz, Method method, Object[] args) - throws Exception { - RpcReceiver object = get(clazz); - return method.invoke(object, args); - } - - public void shutdown() { - for (RpcReceiver receiver : mReceivers.values()) { - try { - if (receiver != null) { - receiver.shutdown(); - } - } catch (Exception e) { - Log.e("Failed to shut down an RpcReceiver", e); - } - } - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManagerFactory.java b/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManagerFactory.java deleted file mode 100644 index defec5f..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/jsonrpc/RpcReceiverManagerFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.jsonrpc; - -import java.util.Map; - -public interface RpcReceiverManagerFactory { - public RpcReceiverManager create(Integer UID); - - public Map<Integer, RpcReceiverManager> getRpcReceiverManagers(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/BeanShellLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/BeanShellLanguage.java deleted file mode 100644 index b92d502..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/BeanShellLanguage.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -import com.googlecode.android_scripting.rpc.ParameterDescriptor; - -/** - * Represents the BeanShell programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class BeanShellLanguage extends Language { - - @Override - protected String getImportStatement() { - // FIXME(igor.v.karp): this is interpreter specific - return "source(\"/sdcard/com.googlecode.bshforandroid/extras/bsh/android.bsh\");\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " = Android();\n"; - } - - @Override - protected String getMethodCallText(String receiver, String method, - ParameterDescriptor[] parameters) { - StringBuilder result = - new StringBuilder().append(getApplyReceiverText(receiver)).append(getApplyOperatorText()) - .append(method); - if (parameters.length > 0) { - result.append(getLeftParametersText()); - } else { - result.append(getQuote()); - } - String separator = ""; - for (ParameterDescriptor parameter : parameters) { - result.append(separator).append(getValueText(parameter)); - separator = getParameterSeparator(); - } - result.append(getRightParametersText()); - - return result.toString(); - } - - @Override - protected String getApplyOperatorText() { - return ".call(\""; - } - - @Override - protected String getLeftParametersText() { - return "\", "; - } - - @Override - protected String getRightParametersText() { - return ")"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/HtmlLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/HtmlLanguage.java deleted file mode 100644 index e7abf33..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/HtmlLanguage.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -import com.googlecode.android_scripting.rpc.ParameterDescriptor; - -public class HtmlLanguage extends Language { - - /** Returns the Android package import statement. */ - @Override - protected String getImportStatement() { - return "<html>\n<head>\n<script>"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return String.format("var %s = new Android();\n</script>\n</head>\n<body>\n\n</body>\n</html>", - rpcReceiver); - } - - @Override - protected String getMethodCallText(String receiver, String method, - ParameterDescriptor[] parameters) { - StringBuilder result = - new StringBuilder().append(getApplyReceiverText(receiver)).append(getApplyOperatorText()) - .append(method); - if (parameters.length > 0) { - result.append(getLeftParametersText()); - } else { - result.append(getQuote()); - } - String separator = ""; - for (ParameterDescriptor parameter : parameters) { - result.append(separator).append(getValueText(parameter)); - separator = getParameterSeparator(); - } - result.append(getRightParametersText()); - - return result.toString(); - } - - @Override - protected String getApplyOperatorText() { - return ".call('"; - } - - @Override - protected String getLeftParametersText() { - return "', "; - } - - @Override - protected String getRightParametersText() { - return ")"; - } - - @Override - protected String getQuote() { - return "'"; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/JavaScriptLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/JavaScriptLanguage.java deleted file mode 100644 index 7e88d3c..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/JavaScriptLanguage.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the JavaScript programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class JavaScriptLanguage extends Language { - - @Override - protected String getImportStatement() { - // FIXME(igor.v.karp): this is interpreter specific - return "load(\"/sdcard/com.googlecode.rhinoforandroid/extras/rhino/android.js\");\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return "var " + rpcReceiver + " = Android();\n"; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/Language.java b/sl4a/Common/src/com/googlecode/android_scripting/language/Language.java deleted file mode 100644 index 0a8d487..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/Language.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.ParameterDescriptor; - -import java.util.HashMap; -import java.util.Map; - -/** - * Represents the programming language supported by the SL4A. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class Language { - - private final static Map<Character, String> AUTO_CLOSE_MAP = buildAutoCloseMap('[', "[]", '{', - "{}", '(', "()", '\'', "''", '"', "\"\""); - - /** Returns the initial template for newly created script. */ - public String getContentTemplate() { - StringBuilder content = new StringBuilder(getImportStatement()); - if (content.length() != 0) { - content.append('\n'); - } - content.append(getRpcReceiverDeclaration(getDefaultRpcReceiver())); - return content.toString(); - } - - /** Returns the Android package import statement. */ - protected String getImportStatement() { - return ""; - } - - /** Returns the RPC receiver declaration. */ - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return ""; - } - - /** Returns the default RPC receiver name. */ - protected String getDefaultRpcReceiver() { - return "droid"; - } - - /** - * Returns the string containing opening and closing tokens if the input is an opening token. - * Returns {@code null} otherwise. - */ - public String autoClose(char token) { - return AUTO_CLOSE_MAP.get(token); - } - - /** Returns the RPC call text with given parameter values. */ - public final String getRpcText(String content, MethodDescriptor rpc, String[] values) { - return getMethodCallText(getRpcReceiverName(content), rpc.getName(), - rpc.getParameterValues(values)); - } - - /** Returns the RPC receiver found in the given script. */ - protected String getRpcReceiverName(String content) { - return getDefaultRpcReceiver(); - } - - /** Returns the method call text in the language. */ - protected String getMethodCallText(String receiver, String method, - ParameterDescriptor[] parameters) { - StringBuilder result = - new StringBuilder().append(getApplyReceiverText(receiver)).append(getApplyOperatorText()) - .append(method).append(getLeftParametersText()); - String separator = ""; - for (ParameterDescriptor parameter : parameters) { - result.append(separator).append(getValueText(parameter)); - separator = getParameterSeparator(); - } - result.append(getRightParametersText()); - - return result.toString(); - } - - /** Returns the apply receiver text. */ - protected String getApplyReceiverText(String receiver) { - return receiver; - } - - /** Returns the apply operator text. */ - protected String getApplyOperatorText() { - return "."; - } - - /** Returns the text to the left of the parameters. */ - protected String getLeftParametersText() { - return "("; - } - - /** Returns the text to the right of the parameters. */ - protected String getRightParametersText() { - return ")"; - } - - /** Returns the parameter separator text. */ - protected String getParameterSeparator() { - return ", "; - } - - /** Returns the text of the quotation. */ - protected String getQuote() { - return "\""; - } - - /** Returns the text of the {@code null} value. */ - protected String getNull() { - return "null"; - } - - /** Returns the text of the {{@code true} value. */ - protected String getTrue() { - return "true"; - } - - /** Returns the text of the false value. */ - protected String getFalse() { - return "false"; - } - - /** Returns the parameter value suitable for code generation. */ - protected String getValueText(ParameterDescriptor parameter) { - if (parameter.getValue() == null) { - return getNullValueText(); - } else if (parameter.getType().equals(String.class)) { - return getStringValueText(parameter.getValue()); - } else if (parameter.getType().equals(Boolean.class)) { - return getBooleanValueText(parameter.getValue()); - } else { - return parameter.getValue(); - } - } - - /** Returns the null value suitable for code generation. */ - private String getNullValueText() { - return getNull(); - } - - /** Returns the string parameter value suitable for code generation. */ - protected String getStringValueText(String value) { - // TODO(igorkarp): do not quote expressions once they could be detected. - return getQuote() + value + getQuote(); - } - - /** Returns the boolean parameter value suitable for code generation. */ - protected String getBooleanValueText(String value) { - if (value.equals(Boolean.TRUE.toString())) { - return getTrue(); - } else if (value.equals(Boolean.FALSE.toString())) { - return getFalse(); - } else { - // If it is neither true nor false it is must be an expression. - return value; - } - } - - private static Map<Character, String> buildAutoCloseMap(char c1, String s1, char c2, String s2, - char c3, String s3, char c4, String s4, char c5, String s5) { - Map<Character, String> map = new HashMap<Character, String>(5); - map.put(c1, s1); - map.put(c2, s2); - map.put(c3, s3); - map.put(c4, s4); - map.put(c5, s5); - return map; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/LuaLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/LuaLanguage.java deleted file mode 100644 index a279434..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/LuaLanguage.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Lua programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class LuaLanguage extends Language { - - @Override - protected String getImportStatement() { - return "require \"android\"\n"; - } - - @Override - protected String getDefaultRpcReceiver() { - return "android"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/PerlLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/PerlLanguage.java deleted file mode 100644 index c5cca0b..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/PerlLanguage.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Perl programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class PerlLanguage extends Language { - - @Override - protected String getImportStatement() { - return "use Android;\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return "my " + rpcReceiver + " = Android->new();\n"; - } - - @Override - protected String getDefaultRpcReceiver() { - return "$droid"; - } - - @Override - protected String getApplyOperatorText() { - return "->"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/PhpLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/PhpLanguage.java deleted file mode 100644 index a141a3c..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/PhpLanguage.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the PHP programming language. - * - * @author ivan@irontec.com (Ivan Mosquera Paulo) - */ -public class PhpLanguage extends Language { - - @Override - protected String getImportStatement() { - return "<?php\n\nrequire_once(\"Android.php\");"; - - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " = new Android();\n"; - } - - @Override - protected String getDefaultRpcReceiver() { - return "$droid"; - } - - @Override - protected String getApplyOperatorText() { - return "->"; - } - - @Override - protected String getQuote() { - return "'"; - } - -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/PythonLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/PythonLanguage.java deleted file mode 100644 index beb59ae..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/PythonLanguage.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Python programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class PythonLanguage extends Language { - - @Override - protected String getImportStatement() { - return "import android\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " = android.Android()\n"; - } - - @Override - protected String getQuote() { - return "'"; - } - - @Override - protected String getNull() { - return "None"; - } - - @Override - protected String getTrue() { - return "True"; - } - - @Override - protected String getFalse() { - return "False"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/RubyLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/RubyLanguage.java deleted file mode 100644 index d6cd189..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/RubyLanguage.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Ruby programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class RubyLanguage extends Language { - - @Override - protected String getImportStatement() { - return "require \"android\";\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " = Droid.new\n"; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/ShellLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/ShellLanguage.java deleted file mode 100644 index d7bc5a2..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/ShellLanguage.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Shell programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class ShellLanguage extends Language { -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/SleepLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/SleepLanguage.java deleted file mode 100644 index 1b623ab..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/SleepLanguage.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Sleep programming language. - * - * @author tomcatalbino@gmail.com - */ -public class SleepLanguage extends Language { - - @Override - protected String getImportStatement() { - return "import com.googlecode.rpc.*;\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " = [new Android];\n"; - } - - @Override - protected String getDefaultRpcReceiver() { - return "$droid"; - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/SquirrelLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/SquirrelLanguage.java deleted file mode 100644 index f9b25bf..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/SquirrelLanguage.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Squirrel programming language, by Alberto Demichelis - * this file adapted by Andy Tai, atai@atai.org - * based on the Python version by - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class SquirrelLanguage extends Language { - - @Override - protected String getImportStatement() { - /* initialization code */ - return ""; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return rpcReceiver + " <- Android();\n"; - } - - @Override - protected String getQuote() { - return "\""; - } - - @Override - protected String getNull() { - return "null"; - } - - @Override - protected String getTrue() { - return "true"; - } - - @Override - protected String getFalse() { - return "false"; - } -} - diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/SupportedLanguages.java b/sl4a/Common/src/com/googlecode/android_scripting/language/SupportedLanguages.java deleted file mode 100644 index e496378..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/SupportedLanguages.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -import com.googlecode.android_scripting.Log; - -import java.util.HashMap; -import java.util.Map; - -public class SupportedLanguages { - - private static enum KnownLanguage { - // SHELL(".sh", ShellLanguage.class), // We don't really support Shell language - HTML(".html", HtmlLanguage.class), BEANSHELL(".bsh", BeanShellLanguage.class), JAVASCRIPT( - ".js", JavaScriptLanguage.class), LUA(".lua", LuaLanguage.class), PERL(".pl", - PerlLanguage.class), PYTHON(".py", PythonLanguage.class), RUBY(".rb", RubyLanguage.class), - TCL(".tcl", TclLanguage.class), PHP(".php", PhpLanguage.class), SLEEP(".sl", - SleepLanguage.class), SQUIRREL(".nut", SquirrelLanguage.class); - - private final String mmExtension; - private final Class<? extends Language> mmClass; - - private KnownLanguage(String ext, Class<? extends Language> clazz) { - mmExtension = ext; - mmClass = clazz; - } - - private String getExtension() { - return mmExtension; - } - - private Class<? extends Language> getLanguageClass() { - return mmClass; - } - } - - private static Map<String, Class<? extends Language>> sSupportedLanguages; - - static { - sSupportedLanguages = new HashMap<String, Class<? extends Language>>(); - for (KnownLanguage language : KnownLanguage.values()) { - sSupportedLanguages.put(language.getExtension(), language.getLanguageClass()); - } - } - - public static Language getLanguageByExtension(String extension) { - extension = extension.toLowerCase(); - if (!extension.startsWith(".")) { - throw new RuntimeException("Extension does not start with a dot: " + extension); - } - Language lang = null; - - Class<? extends Language> clazz = sSupportedLanguages.get(extension); - if (clazz == null) { - clazz = Language.class; // revert to default language. - } - if (clazz != null) { - try { - lang = clazz.newInstance(); - } catch (IllegalAccessException e) { - Log.e(e); - } catch (InstantiationException e) { - Log.e(e); - } - } - return lang; - } - - public static boolean checkLanguageSupported(String name) { - String extension = name.toLowerCase(); - int index = extension.lastIndexOf('.'); - if (index < 0) { - extension = "." + extension; - } else if (index > 0) { - extension = extension.substring(index); - } - return sSupportedLanguages.containsKey(extension); - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/language/TclLanguage.java b/sl4a/Common/src/com/googlecode/android_scripting/language/TclLanguage.java deleted file mode 100644 index 52b8532..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/language/TclLanguage.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.language; - -/** - * Represents the Tcl programming language. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class TclLanguage extends Language { - - @Override - protected String getImportStatement() { - return "package require android\n"; - } - - @Override - protected String getRpcReceiverDeclaration(String rpcReceiver) { - return "set " + rpcReceiver + " [android new]\n"; - } - - @Override - protected String getApplyReceiverText(String receiver) { - return "$" + receiver; - } - - @Override - protected String getApplyOperatorText() { - return " "; - } - - @Override - protected String getLeftParametersText() { - return " "; - } - - @Override - protected String getRightParametersText() { - return ""; - } - - @Override - protected String getParameterSeparator() { - return " "; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/Converter.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/Converter.java deleted file mode 100644 index 274d838..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/Converter.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -/** - * A converter can take a String and turn it into an instance of type T (the type parameter to the - * converter). - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public interface Converter<T> { - - /** Convert a string into type T. */ - T convert(String value); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java deleted file mode 100644 index 5c31c34..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/MethodDescriptor.java +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Parcelable; - -import com.googlecode.android_scripting.facade.AndroidFacade; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.util.VisibleForTesting; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * An adapter that wraps {@code Method}. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public final class MethodDescriptor { - private static final Map<Class<?>, Converter<?>> sConverters = populateConverters(); - - private final Method mMethod; - private final Class<? extends RpcReceiver> mClass; - - public MethodDescriptor(Class<? extends RpcReceiver> clazz, Method method) { - mClass = clazz; - mMethod = method; - } - - @Override - public String toString() { - return mMethod.getDeclaringClass().getCanonicalName() + "." + mMethod.getName(); - } - - /** Collects all methods with {@code RPC} annotation from given class. */ - public static Collection<MethodDescriptor> collectFrom(Class<? extends RpcReceiver> clazz) { - List<MethodDescriptor> descriptors = new ArrayList<MethodDescriptor>(); - for (Method method : clazz.getMethods()) { - if (method.isAnnotationPresent(Rpc.class)) { - descriptors.add(new MethodDescriptor(clazz, method)); - } - } - return descriptors; - } - - /** - * Invokes the call that belongs to this object with the given parameters. Wraps the response - * (possibly an exception) in a JSONObject. - * - * @param parameters - * {@code JSONArray} containing the parameters - * @return result - * @throws Throwable - */ - public Object invoke(RpcReceiverManager manager, final JSONArray parameters) throws Throwable { - - final Type[] parameterTypes = getGenericParameterTypes(); - final Object[] args = new Object[parameterTypes.length]; - final Annotation annotations[][] = getParameterAnnotations(); - - if (parameters.length() > args.length) { - throw new RpcError("Too many parameters specified."); - } - - for (int i = 0; i < args.length; i++) { - final Type parameterType = parameterTypes[i]; - if (i < parameters.length()) { - args[i] = convertParameter(parameters, i, parameterType); - } else if (MethodDescriptor.hasDefaultValue(annotations[i])) { - args[i] = MethodDescriptor.getDefaultValue(parameterType, annotations[i]); - } else { - throw new RpcError("Argument " + (i + 1) + " is not present"); - } - } - - return invoke(manager, args); - } - - /** - * Invokes the call that belongs to this object with the given parameters. Wraps the response - * (possibly an exception) in a JSONObject. - * - * @param parameters {@code Bundle} containing the parameters - * @return result - * @throws Throwable - */ - public Object invoke(RpcReceiverManager manager, final Bundle parameters) throws Throwable { - final Annotation annotations[][] = getParameterAnnotations(); - final Class<?>[] parameterTypes = getMethod().getParameterTypes(); - final Object[] args = new Object[parameterTypes.length]; - - for (int i = 0; i < parameterTypes.length; i++) { - Class<?> parameterType = parameterTypes[i]; - String parameterName = getName(annotations[i]); - if (i < parameterTypes.length) { - args[i] = convertParameter(parameters, parameterType, parameterName); - } else if (MethodDescriptor.hasDefaultValue(annotations[i])) { - args[i] = MethodDescriptor.getDefaultValue(parameterType, annotations[i]); - } else { - throw new RpcError("Argument " + (i + 1) + " is not present"); - } - } - return invoke(manager, args); - } - - private Object invoke(RpcReceiverManager manager, Object[] args) throws Throwable{ - Object result = null; - try { - result = manager.invoke(mClass, mMethod, args); - } catch (Throwable t) { - throw t.getCause(); - } - return result; - } - - /** - * Converts a parameter from JSON into a Java Object. - * - * @return TODO - */ - // TODO(damonkohler): This signature is a bit weird (auto-refactored). The obvious alternative - // would be to work on one supplied parameter and return the converted parameter. However, that's - // problematic because you lose the ability to call the getXXX methods on the JSON array. - @VisibleForTesting - static Object convertParameter(final JSONArray parameters, int index, Type type) - throws JSONException, RpcError { - try { - // Log.d("sl4a", parameters.toString()); - // Log.d("sl4a", type.toString()); - // We must handle null and numbers explicitly because we cannot magically cast them. We - // also need to convert implicitly from numbers to bools. - if (parameters.isNull(index)) { - return null; - } else if (type == Boolean.class) { - try { - return parameters.getBoolean(index); - } catch (JSONException e) { - return new Boolean(parameters.getInt(index) != 0); - } - } else if (type == Long.class) { - return parameters.getLong(index); - } else if (type == Double.class) { - return parameters.getDouble(index); - } else if (type == Integer.class) { - return parameters.getInt(index); - } else if (type == Intent.class) { - return buildIntent(parameters.getJSONObject(index)); - } else if (type == Integer[].class) { - JSONArray list = parameters.getJSONArray(index); - Integer[] result = new Integer[list.length()]; - for (int i = 0; i < list.length(); i++) { - result[i] = list.getInt(i); - } - return result; - } else if (type == String[].class) { - JSONArray list = parameters.getJSONArray(index); - String[] result = new String[list.length()]; - for (int i = 0; i < list.length(); i++) { - result[i] = list.getString(i); - } - return result; - } else if (type == JSONObject.class) { - return parameters.getJSONObject(index); - } else { - // Magically cast the parameter to the right Java type. - return ((Class<?>) type).cast(parameters.get(index)); - } - } catch (ClassCastException e) { - throw new RpcError("Argument " + (index + 1) + " should be of type " - + ((Class<?>) type).getSimpleName() + "."); - } - } - - private Object convertParameter(Bundle bundle, Class<?> type, String name) { - Object param = null; - if (type.isAssignableFrom(Boolean.class)) { - param = bundle.getBoolean(name, false); - } - if (type.isAssignableFrom(Boolean[].class)) { - param = bundle.getBooleanArray(name); - } - if (type.isAssignableFrom(String.class)) { - param = bundle.getString(name); - } - if (type.isAssignableFrom(String[].class)) { - param = bundle.getStringArray(name); - } - if (type.isAssignableFrom(Integer.class)) { - param = bundle.getInt(name, 0); - } - if (type.isAssignableFrom(Integer[].class)) { - param = bundle.getIntArray(name); - } - if (type.isAssignableFrom(Bundle.class)) { - param = bundle.getBundle(name); - } - if (type.isAssignableFrom(Parcelable.class)) { - param = bundle.getParcelable(name); - } - if (type.isAssignableFrom(Parcelable[].class)) { - param = bundle.getParcelableArray(name); - } - if (type.isAssignableFrom(Intent.class)) { - param = bundle.getParcelable(name); - } - return param; - } - - public static Object buildIntent(JSONObject jsonObject) throws JSONException { - Intent intent = new Intent(); - if (jsonObject.has("action")) { - intent.setAction(jsonObject.getString("action")); - } - if (jsonObject.has("data") && jsonObject.has("type")) { - intent.setDataAndType(Uri.parse(jsonObject.optString("data", null)), - jsonObject.optString("type", null)); - } else if (jsonObject.has("data")) { - intent.setData(Uri.parse(jsonObject.optString("data", null))); - } else if (jsonObject.has("type")) { - intent.setType(jsonObject.optString("type", null)); - } - if (jsonObject.has("packagename") && jsonObject.has("classname")) { - intent.setClassName(jsonObject.getString("packagename"), jsonObject.getString("classname")); - } - if (jsonObject.has("flags")) { - intent.setFlags(jsonObject.getInt("flags")); - } - if (!jsonObject.isNull("extras")) { - AndroidFacade.putExtrasFromJsonObject(jsonObject.getJSONObject("extras"), intent); - } - if (!jsonObject.isNull("categories")) { - JSONArray categories = jsonObject.getJSONArray("categories"); - for (int i = 0; i < categories.length(); i++) { - intent.addCategory(categories.getString(i)); - } - } - return intent; - } - - public Method getMethod() { - return mMethod; - } - - public Class<? extends RpcReceiver> getDeclaringClass() { - return mClass; - } - - public String getName() { - if (mMethod.isAnnotationPresent(RpcName.class)) { - return mMethod.getAnnotation(RpcName.class).name(); - } - return mMethod.getName(); - } - - public Type[] getGenericParameterTypes() { - return mMethod.getGenericParameterTypes(); - } - - public Annotation[][] getParameterAnnotations() { - return mMethod.getParameterAnnotations(); - } - - /** - * Returns a human-readable help text for this RPC, based on annotations in the source code. - * - * @return derived help string - */ - public String getHelp() { - StringBuilder helpBuilder = new StringBuilder(); - Rpc rpcAnnotation = mMethod.getAnnotation(Rpc.class); - - helpBuilder.append(mMethod.getName()); - helpBuilder.append("("); - final Class<?>[] parameterTypes = mMethod.getParameterTypes(); - final Type[] genericParameterTypes = mMethod.getGenericParameterTypes(); - final Annotation[][] annotations = mMethod.getParameterAnnotations(); - for (int i = 0; i < parameterTypes.length; i++) { - if (i == 0) { - helpBuilder.append("\n "); - } else { - helpBuilder.append(",\n "); - } - - helpBuilder.append(getHelpForParameter(genericParameterTypes[i], annotations[i])); - } - helpBuilder.append(")\n\n"); - helpBuilder.append(rpcAnnotation.description()); - if (!rpcAnnotation.returns().equals("")) { - helpBuilder.append("\n"); - helpBuilder.append("\nReturns:\n "); - helpBuilder.append(rpcAnnotation.returns()); - } - - if (mMethod.isAnnotationPresent(RpcStartEvent.class)) { - String eventName = mMethod.getAnnotation(RpcStartEvent.class).value(); - helpBuilder.append(String.format("\n\nGenerates \"%s\" events.", eventName)); - } - - if (mMethod.isAnnotationPresent(RpcDeprecated.class)) { - String replacedBy = mMethod.getAnnotation(RpcDeprecated.class).value(); - String release = mMethod.getAnnotation(RpcDeprecated.class).release(); - helpBuilder.append(String.format("\n\nDeprecated in %s! Please use %s instead.", release, - replacedBy)); - } - - return helpBuilder.toString(); - } - - /** - * Returns the help string for one particular parameter. This respects optional parameters. - * - * @param parameterType - * (generic) type of the parameter - * @param annotations - * annotations of the parameter, may be null - * @return string describing the parameter based on source code annotations - */ - private static String getHelpForParameter(Type parameterType, Annotation[] annotations) { - StringBuilder result = new StringBuilder(); - - appendTypeName(result, parameterType); - result.append(" "); - result.append(getName(annotations)); - if (hasDefaultValue(annotations)) { - result.append("[optional"); - if (hasExplicitDefaultValue(annotations)) { - result.append(", default " + getDefaultValue(parameterType, annotations)); - } - result.append("]"); - } - - String description = getDescription(annotations); - if (description.length() > 0) { - result.append(": "); - result.append(description); - } - - return result.toString(); - } - - /** - * Appends the name of the given type to the {@link StringBuilder}. - * - * @param builder - * string builder to append to - * @param type - * type whose name to append - */ - private static void appendTypeName(final StringBuilder builder, final Type type) { - if (type instanceof Class<?>) { - builder.append(((Class<?>) type).getSimpleName()); - } else { - ParameterizedType parametrizedType = (ParameterizedType) type; - builder.append(((Class<?>) parametrizedType.getRawType()).getSimpleName()); - builder.append("<"); - - Type[] arguments = parametrizedType.getActualTypeArguments(); - for (int i = 0; i < arguments.length; i++) { - if (i > 0) { - builder.append(", "); - } - appendTypeName(builder, arguments[i]); - } - builder.append(">"); - } - } - - /** - * Returns parameter descriptors suitable for the RPC call text representation. - * - * <p> - * Uses parameter value, default value or name, whatever is available first. - * - * @return an array of parameter descriptors - */ - public ParameterDescriptor[] getParameterValues(String[] values) { - Type[] parameterTypes = mMethod.getGenericParameterTypes(); - Annotation[][] parametersAnnotations = mMethod.getParameterAnnotations(); - ParameterDescriptor[] parameters = new ParameterDescriptor[parametersAnnotations.length]; - for (int index = 0; index < parameters.length; index++) { - String value; - if (index < values.length) { - value = values[index]; - } else if (hasDefaultValue(parametersAnnotations[index])) { - Object defaultValue = getDefaultValue(parameterTypes[index], parametersAnnotations[index]); - if (defaultValue == null) { - value = null; - } else { - value = String.valueOf(defaultValue); - } - } else { - value = getName(parametersAnnotations[index]); - } - parameters[index] = new ParameterDescriptor(value, parameterTypes[index]); - } - return parameters; - } - - /** - * Returns parameter hints. - * - * @return an array of parameter hints - */ - public String[] getParameterHints() { - Annotation[][] parametersAnnotations = mMethod.getParameterAnnotations(); - String[] hints = new String[parametersAnnotations.length]; - for (int index = 0; index < hints.length; index++) { - String name = getName(parametersAnnotations[index]); - String description = getDescription(parametersAnnotations[index]); - String hint = "No paramenter description."; - if (!name.equals("") && !description.equals("")) { - hint = name + ": " + description; - } else if (!name.equals("")) { - hint = name; - } else if (!description.equals("")) { - hint = description; - } - hints[index] = hint; - } - return hints; - } - - /** - * Extracts the formal parameter name from an annotation. - * - * @param annotations - * the annotations of the parameter - * @return the formal name of the parameter - */ - private static String getName(Annotation[] annotations) { - for (Annotation a : annotations) { - if (a instanceof RpcParameter) { - return ((RpcParameter) a).name(); - } - } - throw new IllegalStateException("No parameter name"); - } - - /** - * Extracts the parameter description from its annotations. - * - * @param annotations - * the annotations of the parameter - * @return the description of the parameter - */ - private static String getDescription(Annotation[] annotations) { - for (Annotation a : annotations) { - if (a instanceof RpcParameter) { - return ((RpcParameter) a).description(); - } - } - throw new IllegalStateException("No parameter description"); - } - - /** - * Returns the default value for a specific parameter. - * - * @param parameterType - * parameterType - * @param annotations - * annotations of the parameter - */ - public static Object getDefaultValue(Type parameterType, Annotation[] annotations) { - for (Annotation a : annotations) { - if (a instanceof RpcDefault) { - RpcDefault defaultAnnotation = (RpcDefault) a; - Converter<?> converter = converterFor(parameterType, defaultAnnotation.converter()); - return converter.convert(defaultAnnotation.value()); - } else if (a instanceof RpcOptional) { - return null; - } - } - throw new IllegalStateException("No default value for " + parameterType); - } - - @SuppressWarnings("rawtypes") - private static Converter<?> converterFor(Type parameterType, - Class<? extends Converter> converterClass) { - if (converterClass == Converter.class) { - Converter<?> converter = sConverters.get(parameterType); - if (converter == null) { - throw new IllegalArgumentException("No predefined converter found for " + parameterType); - } - return converter; - } - try { - Constructor<?> constructor = converterClass.getConstructor(new Class<?>[0]); - return (Converter<?>) constructor.newInstance(new Object[0]); - } catch (Exception e) { - throw new IllegalArgumentException("Cannot create converter from " - + converterClass.getCanonicalName()); - } - } - - /** - * Determines whether or not this parameter has default value. - * - * @param annotations - * annotations of the parameter - */ - public static boolean hasDefaultValue(Annotation[] annotations) { - for (Annotation a : annotations) { - if (a instanceof RpcDefault || a instanceof RpcOptional) { - return true; - } - } - return false; - } - - /** - * Returns whether the default value is specified for a specific parameter. - * - * @param annotations - * annotations of the parameter - */ - @VisibleForTesting - static boolean hasExplicitDefaultValue(Annotation[] annotations) { - for (Annotation a : annotations) { - if (a instanceof RpcDefault) { - return true; - } - } - return false; - } - - /** Returns the converters for {@code String}, {@code Integer} and {@code Boolean}. */ - private static Map<Class<?>, Converter<?>> populateConverters() { - Map<Class<?>, Converter<?>> converters = new HashMap<Class<?>, Converter<?>>(); - converters.put(String.class, new Converter<String>() { - @Override - public String convert(String value) { - return value; - } - }); - converters.put(Integer.class, new Converter<Integer>() { - @Override - public Integer convert(String input) { - try { - return Integer.decode(input); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("'" + input + "' is not an integer"); - } - } - }); - converters.put(Boolean.class, new Converter<Boolean>() { - @Override - public Boolean convert(String input) { - if (input == null) { - return null; - } - input = input.toLowerCase(); - if (input.equals("true")) { - return Boolean.TRUE; - } - if (input.equals("false")) { - return Boolean.FALSE; - } - throw new IllegalArgumentException("'" + input + "' is not a boolean"); - } - }); - return converters; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/ParameterDescriptor.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/ParameterDescriptor.java deleted file mode 100644 index 021373c..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/ParameterDescriptor.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.reflect.Type; - -/** - * RPC parameter description. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public final class ParameterDescriptor { - private final String value; - private final Type type; - - public ParameterDescriptor(String value, Type type) { - this.value = value; - this.type = type; - } - - public String getValue() { - return value; - } - - public Type getType() { - return type; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/Rpc.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/Rpc.java deleted file mode 100644 index 8fc932e..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/Rpc.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The {@link Rpc} annotation is used to annotate server-side implementations of RPCs. It describes - * meta-information (currently a brief documentation of the function), and marks a function as the - * implementation of an RPC. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface Rpc { - /** - * Returns brief description of the function. Should be limited to one or two sentences. - */ - String description(); - - /** - * Gives a brief description of the functions return value (and the underlying data structure). - */ - String returns() default ""; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDefault.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDefault.java deleted file mode 100644 index b27bccc..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDefault.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark an RPC parameter that have a default value. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -@Documented -public @interface RpcDefault { - /** The default value of the RPC parameter. */ - public String value(); - - @SuppressWarnings("rawtypes") - public Class<? extends Converter> converter() default Converter.class; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDeprecated.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDeprecated.java deleted file mode 100644 index c717e5d..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcDeprecated.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark RPC method as deprecated. - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface RpcDeprecated { - /** The method that replaced this one. */ - public String value(); - - /** Release of SL4A when deprecation occurred. */ - public String release() default "r4"; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcError.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcError.java deleted file mode 100644 index c4591c7..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcError.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -@SuppressWarnings("serial") -public class RpcError extends Exception { - - public RpcError(String message) { - super(message); - } - -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcMinSdk.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcMinSdk.java deleted file mode 100644 index 00b49ec..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcMinSdk.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Use this annotation to specify minimum SDK level (if higher than 3). - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface RpcMinSdk { - /** Minimum SDK Level. */ - public int value(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcName.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcName.java deleted file mode 100644 index b0992e6..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcName.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark an RPC parameter that have a default value. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface RpcName { - /** The default value of the RPC parameter. */ - public String name(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcOptional.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcOptional.java deleted file mode 100644 index 53ac650..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcOptional.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark RPC parameter as optional. - * - * <p> - * The parameter marked as optional has no explicit default value. {@code null} is used as default - * value. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -@Documented -public @interface RpcOptional { -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcParameter.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcParameter.java deleted file mode 100644 index eb84879..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcParameter.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * An annotation that is used to document the parameters of an RPC. - * - * @author Felix Arends (felix.arends@gmail.com) - * - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -@Documented -public @interface RpcParameter { - /** - * The name of the formal parameter. This should be in agreement with the java code. - */ - public String name(); - - /** - * Description of the RPC. This should be a short descriptive statement without a full stop, such - * as 'disables the WiFi mode'. - */ - public String description() default ""; -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStartEvent.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStartEvent.java deleted file mode 100644 index 68a5af3..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStartEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark an RPC as one that starts generating events. - * - * @author damonkohler@gmail.com (Damon Kohler) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface RpcStartEvent { - /** The name of the event that is generated. */ - public String value(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStopEvent.java b/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStopEvent.java deleted file mode 100644 index fce25f9..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/rpc/RpcStopEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.rpc; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Use this annotation to mark an RPC as one that stops generating events. - * - * @author damonkohler@gmail.com (Damon Kohler) - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface RpcStopEvent { - /** The name of the event that stops being generated. */ - public String value(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/trigger/ScriptTrigger.java b/sl4a/Common/src/com/googlecode/android_scripting/trigger/ScriptTrigger.java deleted file mode 100644 index 76640fe..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/trigger/ScriptTrigger.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.trigger; - -import android.content.Context; -import android.content.Intent; - -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.event.Event; - -import java.io.File; - -/** - * A trigger implementation that launches a given script when the event occurs. - * - * @author Felix Arends (felix.arends@gmail.com) - */ -public class ScriptTrigger implements Trigger { - private static final long serialVersionUID = 1804599219214041409L; - private final File mScript; - private final String mEventName; - - public ScriptTrigger(String eventName, File script) { - mEventName = eventName; - mScript = script; - } - - @Override - public void handleEvent(Event event, Context context) { - Intent intent = IntentBuilders.buildStartInBackgroundIntent(mScript); - // This is required since the script is being started from the TriggerService. - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); - } - - @Override - public String getEventName() { - return mEventName; - } - - public File getScript() { - return mScript; - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/trigger/Trigger.java b/sl4a/Common/src/com/googlecode/android_scripting/trigger/Trigger.java deleted file mode 100644 index e06a973..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/trigger/Trigger.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.trigger; - -import android.content.Context; - -import com.googlecode.android_scripting.event.Event; - -import java.io.Serializable; - -/** - * Interface implemented by objects listening to events on the event queue inside of the - * {@link SerivceManager}. - * - * @author Felix Arends (felix.arends@gmail.com) - */ -public interface Trigger extends Serializable { - /** - * Handles an event from the event queue. - * - * @param event - * Event to handle - * @param context - * TODO - */ - void handleEvent(Event event, Context context); - - /** - * Returns the event name that this {@link Trigger} is interested in. - */ - // TODO(damonkohler): This could be removed by maintaining a reverse mapping from Trigger to event - // name in the TriggerRespository. - String getEventName(); -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/trigger/TriggerRepository.java b/sl4a/Common/src/com/googlecode/android_scripting/trigger/TriggerRepository.java deleted file mode 100644 index 4e42bfc..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/trigger/TriggerRepository.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.trigger; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.Multimaps; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.Log; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Map.Entry; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.apache.commons.codec.binary.Base64Codec; - -/** - * A repository maintaining all currently scheduled triggers. This includes, for example, alarms or - * observers of arriving text messages etc. This class is responsible for serializing the list of - * triggers to the shared preferences store, and retrieving it from there. - * - * @author Felix Arends (felix.arends@gmail.com) - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class TriggerRepository { - /** - * The list of triggers is serialized to the shared preferences entry with this name. - */ - private static final String TRIGGERS_PREF_KEY = "TRIGGERS"; - - private final SharedPreferences mPreferences; - private final Context mContext; - - /** - * An interface for objects that are notified when a trigger is added to the repository. - */ - public interface TriggerRepositoryObserver { - /** - * Invoked just before the trigger is added to the repository. - * - * @param trigger - * The trigger about to be added to the repository. - */ - void onPut(Trigger trigger); - - /** - * Invoked just after the trigger has been removed from the repository. - * - * @param trigger - * The trigger that has just been removed from the repository. - */ - void onRemove(Trigger trigger); - } - - private final Multimap<String, Trigger> mTriggers; - private final CopyOnWriteArrayList<TriggerRepositoryObserver> mTriggerObservers = - new CopyOnWriteArrayList<TriggerRepositoryObserver>(); - - public TriggerRepository(Context context) { - mContext = context; - mPreferences = PreferenceManager.getDefaultSharedPreferences(context); - String triggers = mPreferences.getString(TRIGGERS_PREF_KEY, null); - mTriggers = deserializeTriggersFromString(triggers); - } - - /** Returns a list of all triggers. The list is unmodifiable. */ - public synchronized Multimap<String, Trigger> getAllTriggers() { - return Multimaps.unmodifiableMultimap(mTriggers); - } - - /** - * Adds a new trigger to the repository. - * - * @param trigger - * the {@link Trigger} to add - */ - public synchronized void put(Trigger trigger) { - notifyOnAdd(trigger); - mTriggers.put(trigger.getEventName(), trigger); - storeTriggers(); - ensureTriggerServiceRunning(); - } - - /** Removes a specific {@link Trigger}. */ - public synchronized void remove(final Trigger trigger) { - mTriggers.get(trigger.getEventName()).remove(trigger); - storeTriggers(); - notifyOnRemove(trigger); - } - - /** Ensures that the {@link TriggerService} is running */ - private void ensureTriggerServiceRunning() { - Intent startTriggerServiceIntent = IntentBuilders.buildTriggerServiceIntent(); - mContext.startService(startTriggerServiceIntent); - } - - /** Notify all {@link TriggerRepositoryObserver}s that a {@link Trigger} was added. */ - private void notifyOnAdd(Trigger trigger) { - for (TriggerRepositoryObserver observer : mTriggerObservers) { - observer.onPut(trigger); - } - } - - /** Notify all {@link TriggerRepositoryObserver}s that a {@link Trigger} was removed. */ - private void notifyOnRemove(Trigger trigger) { - for (TriggerRepositoryObserver observer : mTriggerObservers) { - observer.onRemove(trigger); - } - } - - /** Writes the list of triggers to the shared preferences. */ - private synchronized void storeTriggers() { - SharedPreferences.Editor editor = mPreferences.edit(); - final String triggerValue = serializeTriggersToString(mTriggers); - if (triggerValue != null) { - editor.putString(TRIGGERS_PREF_KEY, triggerValue); - } - editor.commit(); - } - - /** Deserializes the {@link Multimap} of {@link Trigger}s from a base 64 encoded string. */ - @SuppressWarnings("unchecked") - private Multimap<String, Trigger> deserializeTriggersFromString(String triggers) { - if (triggers == null) { - return ArrayListMultimap.<String, Trigger> create(); - } - try { - final ByteArrayInputStream inputStream = - new ByteArrayInputStream(Base64Codec.decodeBase64(triggers.getBytes())); - final ObjectInputStream objectInputStream = new ObjectInputStream(inputStream); - return (Multimap<String, Trigger>) objectInputStream.readObject(); - } catch (Exception e) { - Log.e(e); - } - return ArrayListMultimap.<String, Trigger> create(); - } - - /** Serializes the list of triggers to a Base64 encoded string. */ - private String serializeTriggersToString(Multimap<String, Trigger> triggers) { - try { - final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - final ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); - objectOutputStream.writeObject(triggers); - return new String(Base64Codec.encodeBase64(outputStream.toByteArray())); - } catch (IOException e) { - Log.e(e); - return null; - } - } - - /** Returns {@code true} iff the list of triggers is empty. */ - public synchronized boolean isEmpty() { - return mTriggers.isEmpty(); - } - - /** Adds a {@link TriggerRepositoryObserver}. */ - public void addObserver(TriggerRepositoryObserver observer) { - mTriggerObservers.add(observer); - } - - /** - * Adds the given {@link TriggerRepositoryObserver} and invokes - * {@link TriggerRepositoryObserver#onPut} for all existing triggers. - * - * @param observer - * The observer to add. - */ - public synchronized void bootstrapObserver(TriggerRepositoryObserver observer) { - addObserver(observer); - for (Entry<String, Trigger> trigger : mTriggers.entries()) { - observer.onPut(trigger.getValue()); - } - } - - /** - * Removes a {@link TriggerRepositoryObserver}. - */ - public void removeObserver(TriggerRepositoryObserver observer) { - mTriggerObservers.remove(observer); - } -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/util/VisibleForTesting.java b/sl4a/Common/src/com/googlecode/android_scripting/util/VisibleForTesting.java deleted file mode 100644 index cc8f92a..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/util/VisibleForTesting.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.util; - -/** - * An annotation that indicates that the visibility of a type or member has been relaxed from - * private to package to make the code testable. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -// TODO(igor.v.karp): Consider replacing this annotation by one from Guava or GCL -public @interface VisibleForTesting { -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/webcam/JpegProvider.java b/sl4a/Common/src/com/googlecode/android_scripting/webcam/JpegProvider.java deleted file mode 100644 index d258882..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/webcam/JpegProvider.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.webcam; - -interface JpegProvider { - public byte[] getJpeg(); -}
\ No newline at end of file diff --git a/sl4a/Common/src/com/googlecode/android_scripting/webcam/MjpegServer.java b/sl4a/Common/src/com/googlecode/android_scripting/webcam/MjpegServer.java deleted file mode 100644 index c2b3ac5..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/webcam/MjpegServer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.webcam; - -import java.io.BufferedReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.Socket; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SimpleServer; - -class MjpegServer extends SimpleServer { - - private final JpegProvider mProvider; - - public MjpegServer(JpegProvider provider) { - mProvider = provider; - } - - @Override - protected void handleConnection(Socket socket) throws Exception { - Log.d("handle Mjpeg connection"); - byte[] data = mProvider.getJpeg(); - if (data == null) { - return; - } - OutputStream outputStream = socket.getOutputStream(); - outputStream.write(( - "HTTP/1.0 200 OK\r\n" + - "Server: SL4A\r\n" + - "Connection: close\r\n" + - "Max-Age: 0\r\n" + - "Expires: 0\r\n" + - "Cache-Control: no-cache, private\r\n" + - "Pragma: no-cache\r\n" + - "Content-Type: multipart/x-mixed-replace; boundary=--BoundaryString\r\n\r\n").getBytes()); - while (true) { - data = mProvider.getJpeg(); - if (data == null) { - return; - } - outputStream.write("--BoundaryString\r\n".getBytes()); - outputStream.write("Content-type: image/jpg\r\n".getBytes()); - outputStream.write(("Content-Length: " + data.length + "\r\n\r\n").getBytes()); - outputStream.write(data); - outputStream.write("\r\n\r\n".getBytes()); - outputStream.flush(); - } - } - - @Override - protected void handleRPCConnection(Socket sock, Integer UID, BufferedReader reader, PrintWriter writer) - throws Exception { - } -} diff --git a/sl4a/Common/src/com/googlecode/android_scripting/webcam/WebCamFacade.java b/sl4a/Common/src/com/googlecode/android_scripting/webcam/WebCamFacade.java deleted file mode 100644 index b984828..0000000 --- a/sl4a/Common/src/com/googlecode/android_scripting/webcam/WebCamFacade.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.webcam; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; - -import android.app.Service; -import android.graphics.ImageFormat; -import android.graphics.Rect; -import android.graphics.YuvImage; -import android.hardware.Camera; -import android.hardware.Camera.Parameters; -import android.hardware.Camera.PreviewCallback; -import android.hardware.Camera.Size; -import android.util.Base64; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.WindowManager; -import android.view.SurfaceHolder.Callback; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FutureActivityTaskExecutor; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.SingleThreadExecutor; -import com.googlecode.android_scripting.SimpleServer.SimpleServerObserver; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.future.FutureActivityTask; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDefault; -import com.googlecode.android_scripting.rpc.RpcOptional; -import com.googlecode.android_scripting.rpc.RpcParameter; - -/** - * Manages access to camera streaming. - * <br> - * <h3>Usage Notes</h3> - * <br><b>webCamStart</b> and <b>webCamStop</b> are used to start and stop an Mpeg stream on a given port. <b>webcamAdjustQuality</b> is used to ajust the quality of the streaming video. - * <br><b>cameraStartPreview</b> is used to get access to the camera preview screen. It will generate "preview" events as images become available. - * <br>The preview has two modes: data or file. If you pass a non-blank, writable file path to the <b>cameraStartPreview</b> it will store jpg images in that folder. - * It is up to the caller to clean up these files after the fact. If no file element is provided, - * the event will include the image data as a base64 encoded string. - * <h3>Event details</h3> - * <br>The data element of the preview event will be a map, with the following elements defined. - * <ul> - * <li><b>format</b> - currently always "jpeg" - * <li><b>width</b> - image width (in pixels) - * <li><b>height</b> - image height (in pixels) - * <li><b>quality</b> - JPEG quality. Number from 1-100 - * <li><b>filename</b> - Name of file where image was saved. Only relevant if filepath defined. - * <li><b>error</b> - included if there was an IOException saving file, ie, disk full or path write protected. - * <li><b>encoding</b> - Data encoding. If filepath defined, will be "file" otherwise "base64" - * <li><b>data</b> - Base64 encoded image data. - * </ul> - *<br>Note that "filename", "error" and "data" are mutual exclusive. - *<br> - *<br>The webcam and preview modes use the same resources, so you can't use them both at the same time. Stop one mode before starting the other. - * - * @author Damon Kohler (damonkohler@gmail.com) (probably) - * @author Robbie Matthews (rjmatthews62@gmail.com) - * - */ -public class WebCamFacade extends RpcReceiver { - - private final Service mService; - private final Executor mJpegCompressionExecutor = new SingleThreadExecutor(); - private final ByteArrayOutputStream mJpegCompressionBuffer = new ByteArrayOutputStream(); - - private volatile byte[] mJpegData; - - private CountDownLatch mJpegDataReady; - private boolean mStreaming; - private int mPreviewHeight; - private int mPreviewWidth; - private int mJpegQuality; - - private MjpegServer mJpegServer; - private FutureActivityTask<SurfaceHolder> mPreviewTask; - private Camera mCamera; - private Parameters mParameters; - private final EventFacade mEventFacade; - private boolean mPreview; - private File mDest; - - private final PreviewCallback mPreviewCallback = new PreviewCallback() { - @Override - public void onPreviewFrame(final byte[] data, final Camera camera) { - mJpegCompressionExecutor.execute(new Runnable() { - @Override - public void run() { - mJpegData = compressYuvToJpeg(data); - mJpegDataReady.countDown(); - if (mStreaming) { - camera.setOneShotPreviewCallback(mPreviewCallback); - } - } - }); - } - }; - - private final PreviewCallback mPreviewEvent = new PreviewCallback() { - @Override - public void onPreviewFrame(final byte[] data, final Camera camera) { - mJpegCompressionExecutor.execute(new Runnable() { - @Override - public void run() { - mJpegData = compressYuvToJpeg(data); - Map<String,Object> map = new HashMap<String, Object>(); - map.put("format", "jpeg"); - map.put("width", mPreviewWidth); - map.put("height", mPreviewHeight); - map.put("quality", mJpegQuality); - if (mDest!=null) { - try { - File dest=File.createTempFile("prv",".jpg",mDest); - OutputStream output = new FileOutputStream(dest); - output.write(mJpegData); - output.close(); - map.put("encoding","file"); - map.put("filename",dest.toString()); - } catch (IOException e) { - map.put("error", e.toString()); - } - } - else { - map.put("encoding","Base64"); - map.put("data", Base64.encodeToString(mJpegData, Base64.DEFAULT)); - } - mEventFacade.postEvent("preview", map); - if (mPreview) { - camera.setOneShotPreviewCallback(mPreviewEvent); - } - } - }); - } - }; - - public WebCamFacade(FacadeManager manager) { - super(manager); - mService = manager.getService(); - mJpegDataReady = new CountDownLatch(1); - mEventFacade = manager.getReceiver(EventFacade.class); - } - - private byte[] compressYuvToJpeg(final byte[] yuvData) { - mJpegCompressionBuffer.reset(); - YuvImage yuvImage = - new YuvImage(yuvData, ImageFormat.NV21, mPreviewWidth, mPreviewHeight, null); - yuvImage.compressToJpeg(new Rect(0, 0, mPreviewWidth, mPreviewHeight), mJpegQuality, - mJpegCompressionBuffer); - return mJpegCompressionBuffer.toByteArray(); - } - - @Rpc(description = "Starts an MJPEG stream and returns a Tuple of address and port for the stream.") - public InetSocketAddress webcamStart( - @RpcParameter(name = "resolutionLevel", description = "increasing this number provides higher resolution") @RpcDefault("0") Integer resolutionLevel, - @RpcParameter(name = "jpegQuality", description = "a number from 0-100") @RpcDefault("20") Integer jpegQuality, - @RpcParameter(name = "port", description = "If port is specified, the webcam service will bind to port, otherwise it will pick any available port.") @RpcDefault("0") Integer port) - throws Exception { - try { - openCamera(resolutionLevel, jpegQuality); - return startServer(port); - } catch (Exception e) { - webcamStop(); - throw e; - } - } - - private InetSocketAddress startServer(Integer port) { - mJpegServer = new MjpegServer(new JpegProvider() { - @Override - public byte[] getJpeg() { - try { - mJpegDataReady.await(); - } catch (InterruptedException e) { - Log.e(e); - } - return mJpegData; - } - }); - mJpegServer.addObserver(new SimpleServerObserver() { - @Override - public void onDisconnect() { - if (mJpegServer.getNumberOfConnections() == 0 && mStreaming) { - stopStream(); - } - } - - @Override - public void onConnect() { - if (!mStreaming) { - startStream(); - } - } - }); - return mJpegServer.startPublic(port); - } - - private void stopServer() { - if (mJpegServer != null) { - mJpegServer.shutdown(); - mJpegServer = null; - } - } - - @Rpc(description = "Adjusts the quality of the webcam stream while it is running.") - public void webcamAdjustQuality( - @RpcParameter(name = "resolutionLevel", description = "increasing this number provides higher resolution") @RpcDefault("0") Integer resolutionLevel, - @RpcParameter(name = "jpegQuality", description = "a number from 0-100") @RpcDefault("20") Integer jpegQuality) - throws Exception { - if (mStreaming == false) { - throw new IllegalStateException("Webcam not streaming."); - } - stopStream(); - releaseCamera(); - openCamera(resolutionLevel, jpegQuality); - startStream(); - } - - private void openCamera(Integer resolutionLevel, Integer jpegQuality) throws IOException, - InterruptedException { - mCamera = Camera.open(); - mParameters = mCamera.getParameters(); - mParameters.setPictureFormat(ImageFormat.JPEG); - mParameters.setPreviewFormat(ImageFormat.JPEG); - List<Size> supportedPreviewSizes = mParameters.getSupportedPreviewSizes(); - Collections.sort(supportedPreviewSizes, new Comparator<Size>() { - @Override - public int compare(Size o1, Size o2) { - return o1.width - o2.width; - } - }); - Size previewSize = - supportedPreviewSizes.get(Math.min(resolutionLevel, supportedPreviewSizes.size() - 1)); - mPreviewHeight = previewSize.height; - mPreviewWidth = previewSize.width; - mParameters.setPreviewSize(mPreviewWidth, mPreviewHeight); - mJpegQuality = Math.min(Math.max(jpegQuality, 0), 100); - mCamera.setParameters(mParameters); - // TODO(damonkohler): Rotate image based on orientation. - mPreviewTask = createPreviewTask(); - mCamera.startPreview(); - } - - private void startStream() { - mStreaming = true; - mCamera.setOneShotPreviewCallback(mPreviewCallback); - } - - private void stopStream() { - mJpegDataReady = new CountDownLatch(1); - mStreaming = false; - if (mPreviewTask != null) { - mPreviewTask.finish(); - mPreviewTask = null; - } - } - - private void releaseCamera() { - if (mCamera != null) { - mCamera.release(); - mCamera = null; - } - mParameters = null; - } - - @Rpc(description = "Stops the webcam stream.") - public void webcamStop() { - stopServer(); - stopStream(); - releaseCamera(); - } - - private FutureActivityTask<SurfaceHolder> createPreviewTask() throws IOException, - InterruptedException { - FutureActivityTask<SurfaceHolder> task = new FutureActivityTask<SurfaceHolder>() { - @Override - public void onCreate() { - super.onCreate(); - final SurfaceView view = new SurfaceView(getActivity()); - getActivity().setContentView(view); - getActivity().getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - //view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - view.getHolder().addCallback(new Callback() { - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - setResult(view.getHolder()); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - } - }); - } - }; - FutureActivityTaskExecutor taskExecutor = - ((BaseApplication) mService.getApplication()).getTaskExecutor(); - taskExecutor.execute(task); - mCamera.setPreviewDisplay(task.getResult()); - return task; - } - - @Rpc(description = "Start Preview Mode. Throws 'preview' events.",returns="True if successful") - public boolean cameraStartPreview( - @RpcParameter(name = "resolutionLevel", description = "increasing this number provides higher resolution") @RpcDefault("0") Integer resolutionLevel, - @RpcParameter(name = "jpegQuality", description = "a number from 0-100") @RpcDefault("20") Integer jpegQuality, - @RpcParameter(name = "filepath", description = "Path to store jpeg files.") @RpcOptional String filepath) - throws InterruptedException { - mDest=null; - if (filepath!=null && (filepath.length()>0)) { - mDest = new File(filepath); - if (!mDest.exists()) mDest.mkdirs(); - if (!(mDest.isDirectory() && mDest.canWrite())) { - return false; - } - } - - try { - openCamera(resolutionLevel, jpegQuality); - } catch (IOException e) { - Log.e(e); - return false; - } - startPreview(); - return true; - } - - @Rpc(description = "Stop the preview mode.") - public void cameraStopPreview() { - stopPreview(); - } - - private void startPreview() { - mPreview = true; - mCamera.setOneShotPreviewCallback(mPreviewEvent); - } - - private void stopPreview() { - mPreview = false; - if (mPreviewTask!=null) - { - mPreviewTask.finish(); - mPreviewTask=null; - } - releaseCamera(); - } - - @Override - public void shutdown() { - mPreview=false; - webcamStop(); - } -} diff --git a/sl4a/Common/src/org/apache/commons/codec/BinaryDecoder.java b/sl4a/Common/src/org/apache/commons/codec/BinaryDecoder.java deleted file mode 100644 index 07d93fa..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/BinaryDecoder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * Defines common decoding methods for byte array decoders. - * - * @author Apache Software Foundation - * @version $Id: BinaryDecoder.java 651573 2008-04-25 11:11:21Z niallp $ - */ -public interface BinaryDecoder extends Decoder { - - /** - * Decodes a byte array and returns the results as a byte array. - * - * @param pArray A byte array which has been encoded with the - * appropriate encoder - * - * @return a byte array that contains decoded content - * - * @throws DecoderException A decoder exception is thrown - * if a Decoder encounters a failure condition during - * the decode process. - */ - byte[] decode(byte[] pArray) throws DecoderException; -} - diff --git a/sl4a/Common/src/org/apache/commons/codec/BinaryEncoder.java b/sl4a/Common/src/org/apache/commons/codec/BinaryEncoder.java deleted file mode 100644 index 40bd797..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/BinaryEncoder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * Defines common encoding methods for byte array encoders. - * - * @author Apache Software Foundation - * @version $Id: BinaryEncoder.java 651573 2008-04-25 11:11:21Z niallp $ - */ -public interface BinaryEncoder extends Encoder { - - /** - * Encodes a byte array and return the encoded data - * as a byte array. - * - * @param pArray Data to be encoded - * - * @return A byte array containing the encoded data - * - * @throws EncoderException thrown if the Encoder - * encounters a failure condition during the - * encoding process. - */ - byte[] encode(byte[] pArray) throws EncoderException; -} - diff --git a/sl4a/Common/src/org/apache/commons/codec/CharEncoding.java b/sl4a/Common/src/org/apache/commons/codec/CharEncoding.java deleted file mode 100644 index 01af749..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/CharEncoding.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * Character encoding names required of every implementation of the Java platform. - * - * From the Java documentation <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard - * charsets</a>: - * <p> - * <cite>Every implementation of the Java platform is required to support the following character encodings. Consult the - * release documentation for your implementation to see if any other encodings are supported. Consult the release - * documentation for your implementation to see if any other encodings are supported. </cite> - * </p> - * - * <ul> - * <li><code>US-ASCII</code><br/> - * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set.</li> - * <li><code>ISO-8859-1</code><br/> - * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1.</li> - * <li><code>UTF-8</code><br/> - * Eight-bit Unicode Transformation Format.</li> - * <li><code>UTF-16BE</code><br/> - * Sixteen-bit Unicode Transformation Format, big-endian byte order.</li> - * <li><code>UTF-16LE</code><br/> - * Sixteen-bit Unicode Transformation Format, little-endian byte order.</li> - * <li><code>UTF-16</code><br/> - * Sixteen-bit Unicode Transformation Format, byte order specified by a mandatory initial byte-order mark (either order - * accepted on input, big-endian used on output.)</li> - * </ul> - * - * This perhaps would best belong in the [lang] project. Even if a similar interface is defined in [lang], it is not - * forseen that [codec] would be made to depend on [lang]. - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @author Apache Software Foundation - * @since 1.4 - * @version $Id: CharEncoding.java 797857 2009-07-25 23:43:33Z ggregory $ - */ -public class CharEncoding { - /** - * CharEncodingISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1. </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String ISO_8859_1 = "ISO-8859-1"; - - /** - * <p> - * Seven-bit ASCII, also known as ISO646-US, also known as the Basic Latin block of the Unicode character set. - * </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String US_ASCII = "US-ASCII"; - - /** - * <p> - * Sixteen-bit Unicode Transformation Format, The byte order specified by a mandatory initial byte-order mark - * (either order accepted on input, big-endian used on output) - * </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String UTF_16 = "UTF-16"; - - /** - * <p> - * Sixteen-bit Unicode Transformation Format, big-endian byte order. - * </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String UTF_16BE = "UTF-16BE"; - - /** - * <p> - * Sixteen-bit Unicode Transformation Format, little-endian byte order. - * </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String UTF_16LE = "UTF-16LE"; - - /** - * <p> - * Eight-bit Unicode Transformation Format. - * </p> - * <p> - * Every implementation of the Java platform is required to support this character encoding. - * </p> - * - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - */ - public static final String UTF_8 = "UTF-8"; -}
\ No newline at end of file diff --git a/sl4a/Common/src/org/apache/commons/codec/Decoder.java b/sl4a/Common/src/org/apache/commons/codec/Decoder.java deleted file mode 100644 index c4de37a..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/Decoder.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * <p>Provides the highest level of abstraction for Decoders. - * This is the sister interface of {@link Encoder}. All - * Decoders implement this common generic interface.</p> - * - * <p>Allows a user to pass a generic Object to any Decoder - * implementation in the codec package.</p> - * - * <p>One of the two interfaces at the center of the codec package.</p> - * - * @author Apache Software Foundation - * @version $Id: Decoder.java 797690 2009-07-24 23:28:35Z ggregory $ - */ -public interface Decoder { - - /** - * Decodes an "encoded" Object and returns a "decoded" - * Object. Note that the implementation of this - * interface will try to cast the Object parameter - * to the specific type expected by a particular Decoder - * implementation. If a {@link ClassCastException} occurs - * this decode method will throw a DecoderException. - * - * @param pObject an object to "decode" - * - * @return a 'decoded" object - * - * @throws DecoderException a decoder exception can - * be thrown for any number of reasons. Some good - * candidates are that the parameter passed to this - * method is null, a param cannot be cast to the - * appropriate type for a specific encoder. - */ - Object decode(Object pObject) throws DecoderException; -} - diff --git a/sl4a/Common/src/org/apache/commons/codec/DecoderException.java b/sl4a/Common/src/org/apache/commons/codec/DecoderException.java deleted file mode 100644 index c928086..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/DecoderException.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * Thrown when a Decoder has encountered a failure condition during a decode. - * - * @author Apache Software Foundation - * @version $Id: DecoderException.java 797804 2009-07-25 17:27:04Z ggregory $ - */ -public class DecoderException extends Exception { - - /** - * Declares the Serial Version Uid. - * - * @see <a href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always Declare Serial Version Uid</a> - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new exception with <code>null</code> as its detail message. The cause is not initialized, and may - * subsequently be initialized by a call to {@link #initCause}. - * - * @since 1.4 - */ - public DecoderException() { - super(); - } - - /** - * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently - * be initialized by a call to {@link #initCause}. - * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - */ - public DecoderException(String message) { - super(message); - } - - /** - * Constructsa new exception with the specified detail message and cause. - * - * <p> - * Note that the detail message associated with <code>cause</code> is not automatically incorporated into this - * exception's detail message. - * </p> - * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A <code>null</code> - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public DecoderException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new exception with the specified cause and a detail message of <code>(cause==null ? - * null : cause.toString())</code> (which typically contains the class and detail message of <code>cause</code>). - * This constructor is useful for exceptions that are little more than wrappers for other throwables. - * - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A <code>null</code> - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public DecoderException(Throwable cause) { - super(cause); - } -} diff --git a/sl4a/Common/src/org/apache/commons/codec/Encoder.java b/sl4a/Common/src/org/apache/commons/codec/Encoder.java deleted file mode 100644 index a137e39..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/Encoder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * <p>Provides the highest level of abstraction for Encoders. - * This is the sister interface of {@link Decoder}. Every implementation of - * Encoder provides this common generic interface whic allows a user to pass a - * generic Object to any Encoder implementation in the codec package.</p> - * - * @author Apache Software Foundation - * @version $Id: Encoder.java 634915 2008-03-08 09:30:25Z bayard $ - */ -public interface Encoder { - - /** - * Encodes an "Object" and returns the encoded content - * as an Object. The Objects here may just be <code>byte[]</code> - * or <code>String</code>s depending on the implementation used. - * - * @param pObject An object ot encode - * - * @return An "encoded" Object - * - * @throws EncoderException an encoder exception is - * thrown if the encoder experiences a failure - * condition during the encoding process. - */ - Object encode(Object pObject) throws EncoderException; -} - diff --git a/sl4a/Common/src/org/apache/commons/codec/EncoderException.java b/sl4a/Common/src/org/apache/commons/codec/EncoderException.java deleted file mode 100644 index 975bb77..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/EncoderException.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec; - -/** - * Thrown when there is a failure condition during the encoding process. This exception is thrown when an Encoder - * encounters a encoding specific exception such as invalid data, inability to calculate a checksum, characters outside - * of the expected range. - * - * @author Apache Software Foundation - * @version $Id: EncoderException.java 797804 2009-07-25 17:27:04Z ggregory $ - */ -public class EncoderException extends Exception { - - /** - * Declares the Serial Version Uid. - * - * @see <a href="http://c2.com/cgi/wiki?AlwaysDeclareSerialVersionUid">Always Declare Serial Version Uid</a> - */ - private static final long serialVersionUID = 1L; - - /** - * Constructs a new exception with <code>null</code> as its detail message. The cause is not initialized, and may - * subsequently be initialized by a call to {@link #initCause}. - * - * @since 1.4 - */ - public EncoderException() { - super(); - } - - /** - * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently - * be initialized by a call to {@link #initCause}. - * - * @param message - * a useful message relating to the encoder specific error. - */ - public EncoderException(String message) { - super(message); - } - - /** - * Constructs a new exception with the specified detail message and cause. - * - * <p> - * Note that the detail message associated with <code>cause</code> is not automatically incorporated into this - * exception's detail message. - * </p> - * - * @param message - * The detail message which is saved for later retrieval by the {@link #getMessage()} method. - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A <code>null</code> - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public EncoderException(String message, Throwable cause) { - super(message, cause); - } - - /** - * Constructs a new exception with the specified cause and a detail message of <code>(cause==null ? - * null : cause.toString())</code> (which typically contains the class and detail message of <code>cause</code>). - * This constructor is useful for exceptions that are little more than wrappers for other throwables. - * - * @param cause - * The cause which is saved for later retrieval by the {@link #getCause()} method. A <code>null</code> - * value is permitted, and indicates that the cause is nonexistent or unknown. - * @since 1.4 - */ - public EncoderException(Throwable cause) { - super(cause); - } -} diff --git a/sl4a/Common/src/org/apache/commons/codec/binary/Base64Codec.java b/sl4a/Common/src/org/apache/commons/codec/binary/Base64Codec.java deleted file mode 100644 index 20239e2..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/binary/Base64Codec.java +++ /dev/null @@ -1,1055 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec.binary; - -import java.math.BigInteger; - -import org.apache.commons.codec.BinaryDecoder; -import org.apache.commons.codec.BinaryEncoder; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.EncoderException; - -/** - * Provides Base64 encoding and decoding as defined by RFC 2045. - * - * <p> - * This class implements section <cite>6.8. Base64 Content-Transfer-Encoding</cite> from RFC 2045 <cite>Multipurpose - * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies</cite> by Freed and Borenstein. - * </p> - * <p> - * The class can be parameterized in the following manner with various constructors: - * <ul> - * <li>URL-safe mode: Default off.</li> - * <li>Line length: Default 76. Line length that aren't multiples of 4 will still essentially end up being multiples of - * 4 in the encoded data. - * <li>Line separator: Default is CRLF ("\r\n")</li> - * </ul> - * </p> - * <p> - * Since this class operates directly on byte streams, and not character streams, it is hard-coded to only encode/decode - * character encodings which are compatible with the lower 127 ASCII chart (ISO-8859-1, Windows-1252, UTF-8, etc). - * </p> - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a> - * @author Apache Software Foundation - * @since 1.0 - * @version $Id: Base64.java 801706 2009-08-06 16:27:06Z niallp $ - */ -public class Base64Codec implements BinaryEncoder, BinaryDecoder { - private static final int DEFAULT_BUFFER_RESIZE_FACTOR = 2; - - private static final int DEFAULT_BUFFER_SIZE = 8192; - - /** - * Chunk size per RFC 2045 section 6.8. - * - * <p> - * The {@value} character limit does not count the trailing CRLF, but counts all other characters, including any - * equal signs. - * </p> - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 6.8</a> - */ - static final int CHUNK_SIZE = 76; - - /** - * Chunk separator per RFC 2045 section 2.1. - * - * <p> - * N.B. The next major release may break compatibility and make this field private. - * </p> - * - * @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045 section 2.1</a> - */ - static final byte[] CHUNK_SEPARATOR = {'\r', '\n'}; - - /** - * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet" - * equivalents as specified in Table 1 of RFC 2045. - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] STANDARD_ENCODE_TABLE = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - /** - * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and / - * changed to - and _ to make the encoded Base64 results more URL-SAFE. - * This table is only used when the Base64's mode is set to URL-SAFE. - */ - private static final byte[] URL_SAFE_ENCODE_TABLE = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' - }; - - /** - * Byte used to pad output. - */ - private static final byte PAD = '='; - - /** - * This array is a lookup table that translates Unicode characters drawn from the "Base64 Alphabet" (as specified in - * Table 1 of RFC 2045) into their 6-bit positive integer equivalents. Characters that are not in the Base64 - * alphabet but fall within the bounds of the array are translated to -1. - * - * Note: '+' and '-' both decode to 62. '/' and '_' both decode to 63. This means decoder seamlessly handles both - * URL_SAFE and STANDARD base64. (The encoder, on the other hand, needs to know ahead of time what to emit). - * - * Thanks to "commons" project in ws.apache.org for this code. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - */ - private static final byte[] DECODE_TABLE = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, -1, -1, -1, -1, 63, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 - }; - - /** Mask used to extract 6 bits, used when encoding */ - private static final int MASK_6BITS = 0x3f; - - /** Mask used to extract 8 bits, used in decoding base64 bytes */ - private static final int MASK_8BITS = 0xff; - - // The static final fields above are used for the original static byte[] methods on Base64. - // The private member fields below are used with the new streaming approach, which requires - // some state be preserved between calls of encode() and decode(). - - /** - * Encode table to use: either STANDARD or URL_SAFE. Note: the DECODE_TABLE above remains static because it is able - * to decode both STANDARD and URL_SAFE streams, but the encodeTable must be a member variable so we can switch - * between the two modes. - */ - private final byte[] encodeTable; - - /** - * Line length for encoding. Not used when decoding. A value of zero or less implies no chunking of the base64 - * encoded data. - */ - private final int lineLength; - - /** - * Line separator for encoding. Not used when decoding. Only used if lineLength > 0. - */ - private final byte[] lineSeparator; - - /** - * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. - * <code>decodeSize = 3 + lineSeparator.length;</code> - */ - private final int decodeSize; - - /** - * Convenience variable to help us determine when our buffer is going to run out of room and needs resizing. - * <code>encodeSize = 4 + lineSeparator.length;</code> - */ - private final int encodeSize; - - /** - * Buffer for streaming. - */ - private byte[] buffer; - - /** - * Position where next character should be written in the buffer. - */ - private int pos; - - /** - * Position where next character should be read from the buffer. - */ - private int readPos; - - /** - * Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to - * make sure each encoded line never goes beyond lineLength (if lineLength > 0). - */ - private int currentLinePos; - - /** - * Writes to the buffer only occur after every 3 reads when encoding, an every 4 reads when decoding. This variable - * helps track that. - */ - private int modulus; - - /** - * Boolean flag to indicate the EOF has been reached. Once EOF has been reached, this Base64 object becomes useless, - * and must be thrown away. - */ - private boolean eof; - - /** - * Place holder for the 3 bytes we're dealing with for our base64 logic. Bitwise operations store and extract the - * base64 encoding or decoding from this variable. - */ - private int x; - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - * <p> - * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. - * </p> - * - * <p> - * When decoding all variants are supported. - * </p> - */ - public Base64Codec() { - this(false); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in the given URL-safe mode. - * <p> - * When encoding the line length is 76, the line separator is CRLF, and the encoding table is STANDARD_ENCODE_TABLE. - * </p> - * - * <p> - * When decoding all variants are supported. - * </p> - * - * @param urlSafe - * if <code>true</code>, URL-safe encoding is used. In most cases this should be set to - * <code>false</code>. - * @since 1.4 - */ - public Base64Codec(boolean urlSafe) { - this(CHUNK_SIZE, CHUNK_SEPARATOR, urlSafe); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - * <p> - * When encoding the line length is given in the constructor, the line separator is CRLF, and the encoding table is - * STANDARD_ENCODE_TABLE. - * </p> - * <p> - * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - * </p> - * <p> - * When decoding all variants are supported. - * </p> - * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). - * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. - * @since 1.4 - */ - public Base64Codec(int lineLength) { - this(lineLength, CHUNK_SEPARATOR); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - * <p> - * When encoding the line length and line separator are given in the constructor, and the encoding table is - * STANDARD_ENCODE_TABLE. - * </p> - * <p> - * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - * </p> - * <p> - * When decoding all variants are supported. - * </p> - * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). - * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. - * @param lineSeparator - * Each line of encoded data will end with this sequence of bytes. - * @throws IllegalArgumentException - * Thrown when the provided lineSeparator included some base64 characters. - * @since 1.4 - */ - public Base64Codec(int lineLength, byte[] lineSeparator) { - this(lineLength, lineSeparator, false); - } - - /** - * Creates a Base64 codec used for decoding (all modes) and encoding in URL-unsafe mode. - * <p> - * When encoding the line length and line separator are given in the constructor, and the encoding table is - * STANDARD_ENCODE_TABLE. - * </p> - * <p> - * Line lengths that aren't multiples of 4 will still essentially end up being multiples of 4 in the encoded data. - * </p> - * <p> - * When decoding all variants are supported. - * </p> - * - * @param lineLength - * Each line of encoded data will be at most of the given length (rounded down to nearest multiple of 4). - * If lineLength <= 0, then the output will not be divided into lines (chunks). Ignored when decoding. - * @param lineSeparator - * Each line of encoded data will end with this sequence of bytes. - * @param urlSafe - * Instead of emitting '+' and '/' we emit '-' and '_' respectively. urlSafe is only applied to encode - * operations. Decoding seamlessly handles both modes. - * @throws IllegalArgumentException - * The provided lineSeparator included some base64 characters. That's not going to work! - * @since 1.4 - */ - public Base64Codec(int lineLength, byte[] lineSeparator, boolean urlSafe) { - if (lineSeparator == null) { - lineLength = 0; // disable chunk-separating - lineSeparator = CHUNK_SEPARATOR; // this just gets ignored - } - this.lineLength = lineLength > 0 ? (lineLength / 4) * 4 : 0; - this.lineSeparator = new byte[lineSeparator.length]; - System.arraycopy(lineSeparator, 0, this.lineSeparator, 0, lineSeparator.length); - if (lineLength > 0) { - this.encodeSize = 4 + lineSeparator.length; - } else { - this.encodeSize = 4; - } - this.decodeSize = this.encodeSize - 1; - if (containsBase64Byte(lineSeparator)) { - String sep = StringUtils.newStringUtf8(lineSeparator); - throw new IllegalArgumentException("lineSeperator must not contain base64 characters: [" + sep + "]"); - } - this.encodeTable = urlSafe ? URL_SAFE_ENCODE_TABLE : STANDARD_ENCODE_TABLE; - } - - /** - * Returns our current encode mode. True if we're URL-SAFE, false otherwise. - * - * @return true if we're in URL-SAFE mode, false otherwise. - * @since 1.4 - */ - public boolean isUrlSafe() { - return this.encodeTable == URL_SAFE_ENCODE_TABLE; - } - - /** - * Returns true if this Base64 object has buffered data for reading. - * - * @return true if there is Base64 object still available for reading. - */ - boolean hasData() { - return this.buffer != null; - } - - /** - * Returns the amount of buffered data available for reading. - * - * @return The amount of buffered data available for reading. - */ - int avail() { - return buffer != null ? pos - readPos : 0; - } - - /** Doubles our buffer. */ - private void resizeBuffer() { - if (buffer == null) { - buffer = new byte[DEFAULT_BUFFER_SIZE]; - pos = 0; - readPos = 0; - } else { - byte[] b = new byte[buffer.length * DEFAULT_BUFFER_RESIZE_FACTOR]; - System.arraycopy(buffer, 0, b, 0, buffer.length); - buffer = b; - } - } - - /** - * Extracts buffered data into the provided byte[] array, starting at position bPos, up to a maximum of bAvail - * bytes. Returns how many bytes were actually extracted. - * - * @param b - * byte[] array to extract the buffered data into. - * @param bPos - * position in byte[] array to start extraction at. - * @param bAvail - * amount of bytes we're allowed to extract. We may extract fewer (if fewer are available). - * @return The number of bytes successfully extracted into the provided byte[] array. - */ - int readResults(byte[] b, int bPos, int bAvail) { - if (buffer != null) { - int len = Math.min(avail(), bAvail); - if (buffer != b) { - System.arraycopy(buffer, readPos, b, bPos, len); - readPos += len; - if (readPos >= pos) { - buffer = null; - } - } else { - // Re-using the original consumer's output array is only - // allowed for one round. - buffer = null; - } - return len; - } - return eof ? -1 : 0; - } - - /** - * Sets the streaming buffer. This is a small optimization where we try to buffer directly to the consumer's output - * array for one round (if the consumer calls this method first) instead of starting our own buffer. - * - * @param out - * byte[] array to buffer directly to. - * @param outPos - * Position to start buffering into. - * @param outAvail - * Amount of bytes available for direct buffering. - */ - void setInitialBuffer(byte[] out, int outPos, int outAvail) { - // We can re-use consumer's original output array under - // special circumstances, saving on some System.arraycopy(). - if (out != null && out.length == outAvail) { - buffer = out; - pos = outPos; - readPos = outPos; - } - } - - /** - * <p> - * Encodes all of the provided data, starting at inPos, for inAvail bytes. Must be called at least twice: once with - * the data to encode, and once with inAvail set to "-1" to alert encoder that EOF has been reached, so flush last - * remaining bytes (if not multiple of 3). - * </p> - * <p> - * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - * </p> - * - * @param in - * byte[] array of binary data to base64 encode. - * @param inPos - * Position to start reading data from. - * @param inAvail - * Amount of bytes available from input for encoding. - */ - void encode(byte[] in, int inPos, int inAvail) { - if (eof) { - return; - } - // inAvail < 0 is how we're informed of EOF in the underlying data we're - // encoding. - if (inAvail < 0) { - eof = true; - if (buffer == null || buffer.length - pos < encodeSize) { - resizeBuffer(); - } - switch (modulus) { - case 1 : - buffer[pos++] = encodeTable[(x >> 2) & MASK_6BITS]; - buffer[pos++] = encodeTable[(x << 4) & MASK_6BITS]; - // URL-SAFE skips the padding to further reduce size. - if (encodeTable == STANDARD_ENCODE_TABLE) { - buffer[pos++] = PAD; - buffer[pos++] = PAD; - } - break; - - case 2 : - buffer[pos++] = encodeTable[(x >> 10) & MASK_6BITS]; - buffer[pos++] = encodeTable[(x >> 4) & MASK_6BITS]; - buffer[pos++] = encodeTable[(x << 2) & MASK_6BITS]; - // URL-SAFE skips the padding to further reduce size. - if (encodeTable == STANDARD_ENCODE_TABLE) { - buffer[pos++] = PAD; - } - break; - } - if (lineLength > 0 && pos > 0) { - System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); - pos += lineSeparator.length; - } - } else { - for (int i = 0; i < inAvail; i++) { - if (buffer == null || buffer.length - pos < encodeSize) { - resizeBuffer(); - } - modulus = (++modulus) % 3; - int b = in[inPos++]; - if (b < 0) { - b += 256; - } - x = (x << 8) + b; - if (0 == modulus) { - buffer[pos++] = encodeTable[(x >> 18) & MASK_6BITS]; - buffer[pos++] = encodeTable[(x >> 12) & MASK_6BITS]; - buffer[pos++] = encodeTable[(x >> 6) & MASK_6BITS]; - buffer[pos++] = encodeTable[x & MASK_6BITS]; - currentLinePos += 4; - if (lineLength > 0 && lineLength <= currentLinePos) { - System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length); - pos += lineSeparator.length; - currentLinePos = 0; - } - } - } - } - } - - /** - * <p> - * Decodes all of the provided data, starting at inPos, for inAvail bytes. Should be called at least twice: once - * with the data to decode, and once with inAvail set to "-1" to alert decoder that EOF has been reached. The "-1" - * call is not necessary when decoding, but it doesn't hurt, either. - * </p> - * <p> - * Ignores all non-base64 characters. This is how chunked (e.g. 76 character) data is handled, since CR and LF are - * silently ignored, but has implications for other bytes, too. This method subscribes to the garbage-in, - * garbage-out philosophy: it will not check the provided data for validity. - * </p> - * <p> - * Thanks to "commons" project in ws.apache.org for the bitwise operations, and general approach. - * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/ - * </p> - * - * @param in - * byte[] array of ascii data to base64 decode. - * @param inPos - * Position to start reading data from. - * @param inAvail - * Amount of bytes available from input for encoding. - */ - void decode(byte[] in, int inPos, int inAvail) { - if (eof) { - return; - } - if (inAvail < 0) { - eof = true; - } - for (int i = 0; i < inAvail; i++) { - if (buffer == null || buffer.length - pos < decodeSize) { - resizeBuffer(); - } - byte b = in[inPos++]; - if (b == PAD) { - // We're done. - eof = true; - break; - } else { - if (b >= 0 && b < DECODE_TABLE.length) { - int result = DECODE_TABLE[b]; - if (result >= 0) { - modulus = (++modulus) % 4; - x = (x << 6) + result; - if (modulus == 0) { - buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); - buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS); - buffer[pos++] = (byte) (x & MASK_8BITS); - } - } - } - } - } - - // Two forms of EOF as far as base64 decoder is concerned: actual - // EOF (-1) and first time '=' character is encountered in stream. - // This approach makes the '=' padding characters completely optional. - if (eof && modulus != 0) { - x = x << 6; - switch (modulus) { - case 2 : - x = x << 6; - buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); - break; - case 3 : - buffer[pos++] = (byte) ((x >> 16) & MASK_8BITS); - buffer[pos++] = (byte) ((x >> 8) & MASK_8BITS); - break; - } - } - } - - /** - * Returns whether or not the <code>octet</code> is in the base 64 alphabet. - * - * @param octet - * The value to test - * @return <code>true</code> if the value is defined in the the base 64 alphabet, <code>false</code> otherwise. - * @since 1.4 - */ - public static boolean isBase64(byte octet) { - return octet == PAD || (octet >= 0 && octet < DECODE_TABLE.length && DECODE_TABLE[octet] != -1); - } - - /** - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the - * method treats whitespace as valid. - * - * @param arrayOctet - * byte array to test - * @return <code>true</code> if all bytes are valid characters in the Base64 alphabet or if the byte array is empty; - * false, otherwise - */ - public static boolean isArrayByteBase64(byte[] arrayOctet) { - for (int i = 0; i < arrayOctet.length; i++) { - if (!isBase64(arrayOctet[i]) && !isWhiteSpace(arrayOctet[i])) { - return false; - } - } - return true; - } - - /** - * Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. - * - * @param arrayOctet - * byte array to test - * @return <code>true</code> if any byte is a valid character in the Base64 alphabet; false herwise - */ - private static boolean containsBase64Byte(byte[] arrayOctet) { - for (int i = 0; i < arrayOctet.length; i++) { - if (isBase64(arrayOctet[i])) { - return true; - } - } - return false; - } - - /** - * Encodes binary data using the base64 algorithm but does not chunk the output. - * - * @param binaryData - * binary data to encode - * @return byte[] containing Base64 characters in their UTF-8 representation. - */ - public static byte[] encodeBase64(byte[] binaryData) { - return encodeBase64(binaryData, false); - } - - /** - * Encodes binary data using the base64 algorithm into 76 character blocks separated by CRLF. - * - * @param binaryData - * binary data to encode - * @return String containing Base64 characters. - * @since 1.4 - */ - public static String encodeBase64String(byte[] binaryData) { - return StringUtils.newStringUtf8(encodeBase64(binaryData, true)); - } - - /** - * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The - * url-safe variation emits - and _ instead of + and / characters. - * - * @param binaryData - * binary data to encode - * @return byte[] containing Base64 characters in their UTF-8 representation. - * @since 1.4 - */ - public static byte[] encodeBase64URLSafe(byte[] binaryData) { - return encodeBase64(binaryData, false, true); - } - - /** - * Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The - * url-safe variation emits - and _ instead of + and / characters. - * - * @param binaryData - * binary data to encode - * @return String containing Base64 characters - * @since 1.4 - */ - public static String encodeBase64URLSafeString(byte[] binaryData) { - return StringUtils.newStringUtf8(encodeBase64(binaryData, false, true)); - } - - /** - * Encodes binary data using the base64 algorithm and chunks the encoded output into 76 character blocks - * - * @param binaryData - * binary data to encode - * @return Base64 characters chunked in 76 character blocks - */ - public static byte[] encodeBase64Chunked(byte[] binaryData) { - return encodeBase64(binaryData, true); - } - - /** - * Decodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the - * Decoder interface, and will throw a DecoderException if the supplied object is not of type byte[] or String. - * - * @param pObject - * Object to decode - * @return An object (of type byte[]) containing the binary data which corresponds to the byte[] or String supplied. - * @throws DecoderException - * if the parameter supplied is not of type byte[] - */ - public Object decode(Object pObject) throws DecoderException { - if (pObject instanceof byte[]) { - return decode((byte[]) pObject); - } else if (pObject instanceof String) { - return decode((String) pObject); - } else { - throw new DecoderException("Parameter supplied to Base64 decode is not a byte[] or a String"); - } - } - - /** - * Decodes a String containing containing characters in the Base64 alphabet. - * - * @param pArray - * A String containing Base64 character data - * @return a byte array containing binary data - * @since 1.4 - */ - public byte[] decode(String pArray) { - return decode(StringUtils.getBytesUtf8(pArray)); - } - - /** - * Decodes a byte[] containing containing characters in the Base64 alphabet. - * - * @param pArray - * A byte array containing Base64 character data - * @return a byte array containing binary data - */ - public byte[] decode(byte[] pArray) { - reset(); - if (pArray == null || pArray.length == 0) { - return pArray; - } - long len = (pArray.length * 3) / 4; - byte[] buf = new byte[(int) len]; - setInitialBuffer(buf, 0, buf.length); - decode(pArray, 0, pArray.length); - decode(pArray, 0, -1); // Notify decoder of EOF. - - // Would be nice to just return buf (like we sometimes do in the encode - // logic), but we have no idea what the line-length was (could even be - // variable). So we cannot determine ahead of time exactly how big an - // array is necessary. Hence the need to construct a 2nd byte array to - // hold the final result: - - byte[] result = new byte[pos]; - readResults(result, 0, result.length); - return result; - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if <code>true</code> this encoder will chunk the base64 output into 76 character blocks - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} - */ - public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) { - return encodeBase64(binaryData, isChunked, false); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if <code>true</code> this encoder will chunk the base64 output into 76 character blocks - * @param urlSafe - * if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters. - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than {@link Integer#MAX_VALUE} - * @since 1.4 - */ - public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe) { - return encodeBase64(binaryData, isChunked, urlSafe, Integer.MAX_VALUE); - } - - /** - * Encodes binary data using the base64 algorithm, optionally chunking the output into 76 character blocks. - * - * @param binaryData - * Array containing binary data to encode. - * @param isChunked - * if <code>true</code> this encoder will chunk the base64 output into 76 character blocks - * @param urlSafe - * if <code>true</code> this encoder will emit - and _ instead of the usual + and / characters. - * @param maxResultSize - * The maximum result size to accept. - * @return Base64-encoded data. - * @throws IllegalArgumentException - * Thrown when the input array needs an output array bigger than maxResultSize - * @since 1.4 - */ - public static byte[] encodeBase64(byte[] binaryData, boolean isChunked, boolean urlSafe, int maxResultSize) { - if (binaryData == null || binaryData.length == 0) { - return binaryData; - } - - long len = getEncodeLength(binaryData, CHUNK_SIZE, CHUNK_SEPARATOR); - if (len > maxResultSize) { - throw new IllegalArgumentException("Input array too big, the output array would be bigger (" + - len + - ") than the specified maxium size of " + - maxResultSize); - } - - Base64Codec b64 = isChunked ? new Base64Codec(urlSafe) : new Base64Codec(0, CHUNK_SEPARATOR, urlSafe); - return b64.encode(binaryData); - } - - /** - * Decodes a Base64 String into octets - * - * @param base64String - * String containing Base64 data - * @return Array containing decoded data. - * @since 1.4 - */ - public static byte[] decodeBase64(String base64String) { - return new Base64Codec().decode(base64String); - } - - /** - * Decodes Base64 data into octets - * - * @param base64Data - * Byte array containing Base64 data - * @return Array containing decoded data. - */ - public static byte[] decodeBase64(byte[] base64Data) { - return new Base64Codec().decode(base64Data); - } - - /** - * Discards any whitespace from a base-64 encoded block. - * - * @param data - * The base-64 encoded data to discard the whitespace from. - * @return The data, less whitespace (see RFC 2045). - * @deprecated This method is no longer needed - */ - static byte[] discardWhitespace(byte[] data) { - byte groomedData[] = new byte[data.length]; - int bytesCopied = 0; - for (int i = 0; i < data.length; i++) { - switch (data[i]) { - case ' ' : - case '\n' : - case '\r' : - case '\t' : - break; - default : - groomedData[bytesCopied++] = data[i]; - } - } - byte packedData[] = new byte[bytesCopied]; - System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); - return packedData; - } - - /** - * Checks if a byte value is whitespace or not. - * - * @param byteToCheck - * the byte to check - * @return true if byte is whitespace, false otherwise - */ - private static boolean isWhiteSpace(byte byteToCheck) { - switch (byteToCheck) { - case ' ' : - case '\n' : - case '\r' : - case '\t' : - return true; - default : - return false; - } - } - - // Implementation of the Encoder Interface - - /** - * Encodes an Object using the base64 algorithm. This method is provided in order to satisfy the requirements of the - * Encoder interface, and will throw an EncoderException if the supplied object is not of type byte[]. - * - * @param pObject - * Object to encode - * @return An object (of type byte[]) containing the base64 encoded data which corresponds to the byte[] supplied. - * @throws EncoderException - * if the parameter supplied is not of type byte[] - */ - public Object encode(Object pObject) throws EncoderException { - if (!(pObject instanceof byte[])) { - throw new EncoderException("Parameter supplied to Base64 encode is not a byte[]"); - } - return encode((byte[]) pObject); - } - - /** - * Encodes a byte[] containing binary data, into a String containing characters in the Base64 alphabet. - * - * @param pArray - * a byte array containing binary data - * @return A String containing only Base64 character data - * @since 1.4 - */ - public String encodeToString(byte[] pArray) { - return StringUtils.newStringUtf8(encode(pArray)); - } - - /** - * Encodes a byte[] containing binary data, into a byte[] containing characters in the Base64 alphabet. - * - * @param pArray - * a byte array containing binary data - * @return A byte array containing only Base64 character data - */ - public byte[] encode(byte[] pArray) { - reset(); - if (pArray == null || pArray.length == 0) { - return pArray; - } - long len = getEncodeLength(pArray, lineLength, lineSeparator); - byte[] buf = new byte[(int) len]; - setInitialBuffer(buf, 0, buf.length); - encode(pArray, 0, pArray.length); - encode(pArray, 0, -1); // Notify encoder of EOF. - // Encoder might have resized, even though it was unnecessary. - if (buffer != buf) { - readResults(buf, 0, buf.length); - } - // In URL-SAFE mode we skip the padding characters, so sometimes our - // final length is a bit smaller. - if (isUrlSafe() && pos < buf.length) { - byte[] smallerBuf = new byte[pos]; - System.arraycopy(buf, 0, smallerBuf, 0, pos); - buf = smallerBuf; - } - return buf; - } - - /** - * Pre-calculates the amount of space needed to base64-encode the supplied array. - * - * @param pArray byte[] array which will later be encoded - * @param chunkSize line-length of the output (<= 0 means no chunking) between each - * chunkSeparator (e.g. CRLF). - * @param chunkSeparator the sequence of bytes used to separate chunks of output (e.g. CRLF). - * - * @return amount of space needed to encoded the supplied array. Returns - * a long since a max-len array will require Integer.MAX_VALUE + 33%. - */ - private static long getEncodeLength(byte[] pArray, int chunkSize, byte[] chunkSeparator) { - // base64 always encodes to multiples of 4. - chunkSize = (chunkSize / 4) * 4; - - long len = (pArray.length * 4) / 3; - long mod = len % 4; - if (mod != 0) { - len += 4 - mod; - } - if (chunkSize > 0) { - boolean lenChunksPerfectly = len % chunkSize == 0; - len += (len / chunkSize) * chunkSeparator.length; - if (!lenChunksPerfectly) { - len += chunkSeparator.length; - } - } - return len; - } - - // Implementation of integer encoding used for crypto - /** - * Decodes a byte64-encoded integer according to crypto standards such as W3C's XML-Signature - * - * @param pArray - * a byte array containing base64 character data - * @return A BigInteger - * @since 1.4 - */ - public static BigInteger decodeInteger(byte[] pArray) { - return new BigInteger(1, decodeBase64(pArray)); - } - - /** - * Encodes to a byte64-encoded integer according to crypto standards such as W3C's XML-Signature - * - * @param bigInt - * a BigInteger - * @return A byte array containing base64 character data - * @throws NullPointerException - * if null is passed in - * @since 1.4 - */ - public static byte[] encodeInteger(BigInteger bigInt) { - if (bigInt == null) { - throw new NullPointerException("encodeInteger called with null parameter"); - } - return encodeBase64(toIntegerBytes(bigInt), false); - } - - /** - * Returns a byte-array representation of a <code>BigInteger</code> without sign bit. - * - * @param bigInt - * <code>BigInteger</code> to be converted - * @return a byte array representation of the BigInteger parameter - */ - static byte[] toIntegerBytes(BigInteger bigInt) { - int bitlen = bigInt.bitLength(); - // round bitlen - bitlen = ((bitlen + 7) >> 3) << 3; - byte[] bigBytes = bigInt.toByteArray(); - - if (((bigInt.bitLength() % 8) != 0) && (((bigInt.bitLength() / 8) + 1) == (bitlen / 8))) { - return bigBytes; - } - // set up params for copying everything but sign bit - int startSrc = 0; - int len = bigBytes.length; - - // if bigInt is exactly byte-aligned, just skip signbit in copy - if ((bigInt.bitLength() % 8) == 0) { - startSrc = 1; - len--; - } - int startDst = bitlen / 8 - len; // to pad w/ nulls as per spec - byte[] resizedBytes = new byte[bitlen / 8]; - System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, len); - return resizedBytes; - } - - /** - * Resets this Base64 object to its initial newly constructed state. - */ - private void reset() { - buffer = null; - pos = 0; - readPos = 0; - currentLinePos = 0; - modulus = 0; - eof = false; - } - -} diff --git a/sl4a/Common/src/org/apache/commons/codec/binary/StringUtils.java b/sl4a/Common/src/org/apache/commons/codec/binary/StringUtils.java deleted file mode 100644 index e3af657..0000000 --- a/sl4a/Common/src/org/apache/commons/codec/binary/StringUtils.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.commons.codec.binary; - -import java.io.UnsupportedEncodingException; - -import org.apache.commons.codec.CharEncoding; - -/** - * Converts String to and from bytes using the encodings required by the Java specification. These encodings are specified in <a - * href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * - * @see CharEncoding - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a> - * @version $Id: StringUtils.java 801391 2009-08-05 19:55:54Z ggregory $ - * @since 1.4 - */ -public class StringUtils { - - /** - * Encodes the given string into a sequence of bytes using the ISO-8859-1 charset, storing the result into a new - * byte array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesIso8859_1(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.ISO_8859_1); - } - - /** - * Encodes the given string into a sequence of bytes using the US-ASCII charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesUsAscii(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.US_ASCII); - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-16 charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesUtf16(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16); - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-16BE charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesUtf16Be(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16BE); - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-16LE charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesUtf16Le(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_16LE); - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte - * array. - * - * @param string - * the String to encode - * @return encoded bytes - * @throws IllegalStateException - * Thrown when the charset is missing, which should be never according the the Java specification. - * @see <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/nio/charset/Charset.html">Standard charsets</a> - * @see #getBytesUnchecked(String, String) - */ - public static byte[] getBytesUtf8(String string) { - return StringUtils.getBytesUnchecked(string, CharEncoding.UTF_8); - } - - /** - * Encodes the given string into a sequence of bytes using the named charset, storing the result into a new byte - * array. - * <p> - * This method catches {@link UnsupportedEncodingException} and rethrows it as {@link IllegalStateException}, which - * should never happen for a required charset name. Use this method when the encoding is required to be in the JRE. - * </p> - * - * @param string - * the String to encode - * @param charsetName - * The name of a required {@link java.nio.charset.Charset} - * @return encoded bytes - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen for a - * required charset name. - * @see CharEncoding - * @see String#getBytes(String) - */ - public static byte[] getBytesUnchecked(String string, String charsetName) { - if (string == null) { - return null; - } - try { - return string.getBytes(charsetName); - } catch (UnsupportedEncodingException e) { - throw StringUtils.newIllegalStateException(charsetName, e); - } - } - - private static IllegalStateException newIllegalStateException(String charsetName, UnsupportedEncodingException e) { - return new IllegalStateException(charsetName + ": " + e); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the given charset. - * <p> - * This method catches {@link UnsupportedEncodingException} and re-throws it as {@link IllegalStateException}, which - * should never happen for a required charset name. Use this method when the encoding is required to be in the JRE. - * </p> - * - * @param bytes - * The bytes to be decoded into characters - * @param charsetName - * The name of a required {@link java.nio.charset.Charset} - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen for a - * required charset name. - * @see CharEncoding - * @see String#String(byte[], String) - */ - public static String newString(byte[] bytes, String charsetName) { - if (bytes == null) { - return null; - } - try { - return new String(bytes, charsetName); - } catch (UnsupportedEncodingException e) { - throw StringUtils.newIllegalStateException(charsetName, e); - } - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the ISO-8859-1 charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringIso8859_1(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.ISO_8859_1); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the US-ASCII charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringUsAscii(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.US_ASCII); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the UTF-16 charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringUtf16(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.UTF_16); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the UTF-16BE charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringUtf16Be(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.UTF_16BE); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the UTF-16LE charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringUtf16Le(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.UTF_16LE); - } - - /** - * Constructs a new <code>String</code> by decoding the specified array of bytes using the UTF-8 charset. - * - * @param bytes - * The bytes to be decoded into characters - * @return A new <code>String</code> decoded from the specified array of bytes using the given charset. - * @throws IllegalStateException - * Thrown when a {@link UnsupportedEncodingException} is caught, which should never happen since the - * charset is required. - */ - public static String newStringUtf8(byte[] bytes) { - return StringUtils.newString(bytes, CharEncoding.UTF_8); - } - -} diff --git a/sl4a/Docs/generate_api_reference_md.pl b/sl4a/Docs/generate_api_reference_md.pl deleted file mode 100755 index 546fe28..0000000 --- a/sl4a/Docs/generate_api_reference_md.pl +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (C) 2015 Google, Inc. -# -# 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. -# - -use strict; -use warnings; -use Cwd 'abs_path'; -use JSON; -use File::Find; - -my $sl4a_path = $ARGV[0]; -my $md = ""; -my $md_end = ""; - -if (not defined $sl4a_path) { - $sl4a_path = abs_path($0); - $sl4a_path =~ s/\/Docs\/generate_api_reference_md\.pl//g; -} - -sub eachFile { - my $filename = $_; - my $fullpath = $File::Find::name; - if (-e $filename && $filename =~ m/Facade\.java/) { - open(FILE, $filename); - my @lines = <FILE>; - close(FILE); - - my $title = $filename; - $title =~ s/\.java//; - $title = '**' . $title . '**' . "\n"; - $md = $md . "\n$title"; - my $description = ""; - for (my $i = 0; $i < scalar(@lines); $i++) { - my $line = $lines[$i]; - $line =~ s/\n//; - $line =~ s/^\s+|\s+$//g; - - if ($line =~ m /^\@Rpc\(description/) { - $description = ""; - for (my $j = $i; $j < scalar(@lines); $j++) { - my $l = $lines[$j]; - $l =~ s/^\s+|\s+$//g; - $description = $description . $l; - if ($l =~ m/\)$/) { - $i = $j; - last; - } - } - $description = _format_description($description); - - } - if ($line =~ m /^public/ && $description ne "") { - my @words = split(/\s/, $line); - my $func_name = $words[2]; - my $func_names_and_params = ""; - if ($func_name =~ /void/) { - $func_name = $words[3]; - if ($func_name =~ /void/) { - $description = ""; - $func_names_and_params = ""; - next; - } - } - if ($func_name =~ /\(/) { - $func_name =~ s/\(.*//; - } - $func_name =~ s/\(//g; - $func_name =~ s/\)//g; - for (my $j = $i; $j < scalar(@lines); $j++) { - $func_names_and_params = $func_names_and_params . $lines[$j]; - if ($lines[$j] =~ m/{$/) { - last; - } - } - $func_names_and_params = _format_func_names_and_params($func_names_and_params); - if ($func_names_and_params eq "") { - $func_names_and_params = ")\n"; - } else { - $func_names_and_params = "\n" . $func_names_and_params; - } - $md_end = $md_end . "# $func_name\n```\n" . - "$func_name(" . $func_names_and_params . "\n$description\n```\n\n" ; - $description = ""; - $func_names_and_params = ""; - my $lc_name = lc $func_name; - $md = $md . " * [$func_name](\#$lc_name)\n"; - } - } - - } -} - -sub _format_func_names_and_params { - my $fn = shift; - $fn =~ s/^\s+|\s+$//g; - my @words = split(/\n/,$fn); - my $format = ""; - my $description = ""; - my $name = ""; - my $params = ""; - for my $w (@words) { - if ($w =~ /\@RpcParameter\(name = "(.+?)", description = "(.+?)"/) { - $name = $1; - $description = $2; - } - elsif ($w =~ /\@RpcParameter\(name = "(.+?)"/) { - $name = $1; - } - if ($w =~ m/,$/) { - my @split = split(/\s/, $w); - $params = "$split[$#split-1] $split[$#split]"; - if ($description eq "") { - $format = $params; - } elsif ($description ne "") { - $params =~ s/,//; - $format = $format . " $params: $description,\n" - } - $description = ""; - $name = ""; - $params = ""; - } - } - $format =~ s/,$/)/; - return $format; -} - -sub _format_description { - my $description = shift; - $description =~ s/\@Rpc\(//; - $description =~ s/^\s+|\s+$//g; - $description =~ s/\n//g; - $description =~ s/description = \"//g; - $description =~ s/\"\)//g; - if ($description =~ m/returns(\s*)=/) { - $description =~ s/\",//; - my @words = split(/returns(\s*)=/, $description); - my $des = $words[0]; - my $ret = $words[1]; - $ret =~ s/^\s+|\s+$//g; - $ret =~ s/^"//; - $description = $des . "\n\n" . "Returns:\n" . " $ret"; - } - return $description; -} - -find (\&eachFile, $sl4a_path); -open(FILE, ">$sl4a_path/Docs/ApiReference.md"); -print FILE $md . "\n"; -print FILE $md_end . "\n"; -close(FILE); diff --git a/sl4a/InterpreterForAndroid/Android.mk b/sl4a/InterpreterForAndroid/Android.mk deleted file mode 100644 index 7f222f6..0000000 --- a/sl4a/InterpreterForAndroid/Android.mk +++ /dev/null @@ -1,28 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - - -LOCAL_MODULE := sl4a.InterpreterForAndroid -LOCAL_MODULE_OWNER := google -LOCAL_STATIC_JAVA_LIBRARIES := guava android-common sl4a.Utils -#LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4 -LOCAL_SRC_FILES := $(call all-java-files-under, src/com/googlecode/android_scripting) - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/AsyncTaskListener.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/AsyncTaskListener.java deleted file mode 100644 index 38bb34b..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/AsyncTaskListener.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -/** - * This listener asynchronously receives a task result whenever it finishes. Should be implemented - * to avoid blocking on task's get() method. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public interface AsyncTaskListener<T> { - public void onTaskFinished(T result, String message); -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterInstaller.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterInstaller.java deleted file mode 100644 index 53a1d6c..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterInstaller.java +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; -import android.preference.PreferenceManager; - -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; -import com.googlecode.android_scripting.interpreter.InterpreterDescriptor; -import com.googlecode.android_scripting.interpreter.InterpreterUtils; - -import java.io.File; -import java.net.MalformedURLException; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -/** - * AsyncTask for installing interpreters. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public abstract class InterpreterInstaller extends AsyncTask<Void, Void, Boolean> { - - protected final InterpreterDescriptor mDescriptor; - protected final AsyncTaskListener<Boolean> mTaskListener; - protected final Queue<RequestCode> mTaskQueue; - protected final Context mContext; - - protected final Handler mainThreadHandler; - protected Handler mBackgroundHandler; - - protected volatile AsyncTask<Void, Integer, Long> mTaskHolder; - - protected final String mInterpreterRoot; - - protected static enum RequestCode { - DOWNLOAD_INTERPRETER, DOWNLOAD_INTERPRETER_EXTRAS, DOWNLOAD_SCRIPTS, EXTRACT_INTERPRETER, - EXTRACT_INTERPRETER_EXTRAS, EXTRACT_SCRIPTS - } - - // Executed in the UI thread. - private final Runnable mTaskStarter = new Runnable() { - @Override - public void run() { - RequestCode task = mTaskQueue.peek(); - try { - AsyncTask<Void, Integer, Long> newTask = null; - switch (task) { - case DOWNLOAD_INTERPRETER: - newTask = downloadInterpreter(); - break; - case DOWNLOAD_INTERPRETER_EXTRAS: - newTask = downloadInterpreterExtras(); - break; - case DOWNLOAD_SCRIPTS: - newTask = downloadScripts(); - break; - case EXTRACT_INTERPRETER: - newTask = extractInterpreter(); - break; - case EXTRACT_INTERPRETER_EXTRAS: - newTask = extractInterpreterExtras(); - break; - case EXTRACT_SCRIPTS: - newTask = extractScripts(); - break; - } - mTaskHolder = newTask.execute(); - } catch (Exception e) { - Log.v(e.getMessage(), e); - } - - if (mBackgroundHandler != null) { - mBackgroundHandler.post(mTaskWorker); - } - } - }; - - // Executed in the background. - private final Runnable mTaskWorker = new Runnable() { - @Override - public void run() { - RequestCode request = mTaskQueue.peek(); - try { - if (mTaskHolder != null && mTaskHolder.get() != null) { - mTaskQueue.remove(); - mTaskHolder = null; - // Post processing. - if (request == RequestCode.EXTRACT_INTERPRETER && !chmodIntepreter()) { - // Chmod returned false. - Looper.myLooper().quit(); - } else if (mTaskQueue.size() == 0) { - // We're done here. - Looper.myLooper().quit(); - return; - } else if (mainThreadHandler != null) { - // There's still some work to do. - mainThreadHandler.post(mTaskStarter); - return; - } - } - } catch (Exception e) { - Log.e(e); - } - // Something went wrong... - switch (request) { - case DOWNLOAD_INTERPRETER: - Log.e("Downloading interpreter failed."); - break; - case DOWNLOAD_INTERPRETER_EXTRAS: - Log.e("Downloading interpreter extras failed."); - break; - case DOWNLOAD_SCRIPTS: - Log.e("Downloading scripts failed."); - break; - case EXTRACT_INTERPRETER: - Log.e("Extracting interpreter failed."); - break; - case EXTRACT_INTERPRETER_EXTRAS: - Log.e("Extracting interpreter extras failed."); - break; - case EXTRACT_SCRIPTS: - Log.e("Extracting scripts failed."); - break; - } - Looper.myLooper().quit(); - } - }; - - // TODO(Alexey): Add Javadoc. - public InterpreterInstaller(InterpreterDescriptor descriptor, Context context, - AsyncTaskListener<Boolean> taskListener) throws Sl4aException { - super(); - mDescriptor = descriptor; - mContext = context; - mTaskListener = taskListener; - mainThreadHandler = new Handler(); - mTaskQueue = new LinkedList<RequestCode>(); - - String packageName = mDescriptor.getClass().getPackage().getName(); - - if (packageName.length() == 0) { - throw new Sl4aException("Interpreter package name is empty."); - } - - mInterpreterRoot = InterpreterConstants.SDCARD_ROOT + packageName; - - if (mDescriptor == null) { - throw new Sl4aException("Interpreter description not provided."); - } - if (mDescriptor.getName() == null) { - throw new Sl4aException("Interpreter not specified."); - } - if (isInstalled()) { - throw new Sl4aException("Interpreter is installed."); - } - - if (mDescriptor.hasInterpreterArchive()) { - mTaskQueue.offer(RequestCode.DOWNLOAD_INTERPRETER); - mTaskQueue.offer(RequestCode.EXTRACT_INTERPRETER); - } - if (mDescriptor.hasExtrasArchive()) { - mTaskQueue.offer(RequestCode.DOWNLOAD_INTERPRETER_EXTRAS); - mTaskQueue.offer(RequestCode.EXTRACT_INTERPRETER_EXTRAS); - } - if (mDescriptor.hasScriptsArchive()) { - mTaskQueue.offer(RequestCode.DOWNLOAD_SCRIPTS); - mTaskQueue.offer(RequestCode.EXTRACT_SCRIPTS); - } - } - - @Override - protected Boolean doInBackground(Void... params) { - new Thread(new Runnable() { - @Override - public void run() { - executeInBackground(); - final boolean result = (mTaskQueue.size() == 0); - mainThreadHandler.post(new Runnable() { - @Override - public void run() { - finish(result); - } - }); - } - }).start(); - return true; - } - - private boolean executeInBackground() { - - File root = new File(mInterpreterRoot); - if (root.exists()) { - FileUtils.delete(root); - } - if (!root.mkdirs()) { - Log.e("Failed to make directories: " + root.getAbsolutePath()); - return false; - } - - if (Looper.myLooper() == null) { - Looper.prepare(); - } - mBackgroundHandler = new Handler(Looper.myLooper()); - mainThreadHandler.post(mTaskStarter); - Looper.loop(); - // Have we executed all the tasks? - return (mTaskQueue.size() == 0); - } - - protected void finish(boolean result) { - if (result && setup()) { - mTaskListener.onTaskFinished(true, "Installation successful."); - } else { - if (mTaskHolder != null) { - mTaskHolder.cancel(true); - } - cleanup(); - mTaskListener.onTaskFinished(false, "Installation failed."); - } - } - - protected AsyncTask<Void, Integer, Long> download(String in) throws MalformedURLException { - String out = mInterpreterRoot; - return new UrlDownloaderTask(in, out, mContext); - } - - protected AsyncTask<Void, Integer, Long> downloadInterpreter() throws MalformedURLException { - return download(mDescriptor.getInterpreterArchiveUrl()); - } - - protected AsyncTask<Void, Integer, Long> downloadInterpreterExtras() throws MalformedURLException { - return download(mDescriptor.getExtrasArchiveUrl()); - } - - protected AsyncTask<Void, Integer, Long> downloadScripts() throws MalformedURLException { - return download(mDescriptor.getScriptsArchiveUrl()); - } - - protected AsyncTask<Void, Integer, Long> extract(String in, String out, boolean replaceAll) - throws Sl4aException { - return new ZipExtractorTask(in, out, mContext, replaceAll); - } - - protected AsyncTask<Void, Integer, Long> extractInterpreter() throws Sl4aException { - String in = - new File(mInterpreterRoot, mDescriptor.getInterpreterArchiveName()).getAbsolutePath(); - String out = InterpreterUtils.getInterpreterRoot(mContext).getAbsolutePath(); - return extract(in, out, true); - } - - protected AsyncTask<Void, Integer, Long> extractInterpreterExtras() throws Sl4aException { - String in = new File(mInterpreterRoot, mDescriptor.getExtrasArchiveName()).getAbsolutePath(); - String out = mInterpreterRoot + InterpreterConstants.INTERPRETER_EXTRAS_ROOT; - return extract(in, out, true); - } - - protected AsyncTask<Void, Integer, Long> extractScripts() throws Sl4aException { - String in = new File(mInterpreterRoot, mDescriptor.getScriptsArchiveName()).getAbsolutePath(); - String out = InterpreterConstants.SCRIPTS_ROOT; - return extract(in, out, false); - } - - protected boolean chmodIntepreter() { - int dataChmodErrno; - boolean interpreterChmodSuccess; - try { - dataChmodErrno = FileUtils.chmod(InterpreterUtils.getInterpreterRoot(mContext), 0755); - interpreterChmodSuccess = - FileUtils.recursiveChmod(InterpreterUtils.getInterpreterRoot(mContext, mDescriptor - .getName()), 0755); - } catch (Exception e) { - Log.e(e); - return false; - } - return dataChmodErrno == 0 && interpreterChmodSuccess; - } - - protected boolean isInstalled() { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); - return preferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); - } - - private void cleanup() { - List<File> directories = new ArrayList<File>(); - - directories.add(new File(mInterpreterRoot)); - - if (mDescriptor.hasInterpreterArchive()) { - if (!mTaskQueue.contains(RequestCode.EXTRACT_INTERPRETER)) { - directories.add(InterpreterUtils.getInterpreterRoot(mContext, mDescriptor.getName())); - } - } - - for (File directory : directories) { - FileUtils.delete(directory); - } - } - - protected abstract boolean setup(); -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterUninstaller.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterUninstaller.java deleted file mode 100644 index 5d0c17f..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/InterpreterUninstaller.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.SharedPreferences; -import android.content.DialogInterface.OnCancelListener; -import android.os.AsyncTask; -import android.preference.PreferenceManager; - -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; -import com.googlecode.android_scripting.interpreter.InterpreterDescriptor; -import com.googlecode.android_scripting.interpreter.InterpreterUtils; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * AsyncTask for uninstalling interpreters. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public abstract class InterpreterUninstaller extends AsyncTask<Void, Void, Boolean> { - - protected final InterpreterDescriptor mDescriptor; - protected final Context mContext; - protected final ProgressDialog mDialog; - protected final AsyncTaskListener<Boolean> mListener; - - protected final String mInterpreterRoot; - - public InterpreterUninstaller(InterpreterDescriptor descriptor, Context context, - AsyncTaskListener<Boolean> listener) throws Sl4aException { - - super(); - - mDescriptor = descriptor; - mContext = context; - mListener = listener; - - String packageName = mDescriptor.getClass().getPackage().getName(); - - if (packageName.length() == 0) { - throw new Sl4aException("Interpreter package name is empty."); - } - - mInterpreterRoot = InterpreterConstants.SDCARD_ROOT + packageName; - - if (mDescriptor == null) { - throw new Sl4aException("Interpreter description not provided."); - } - if (mDescriptor.getName() == null) { - throw new Sl4aException("Interpreter not specified."); - } - if (!isInstalled()) { - throw new Sl4aException("Interpreter not installed."); - } - - if (context != null) { - mDialog = new ProgressDialog(context); - } else { - mDialog = null; - } - } - - public final void execute() { - execute(null, null, null); - } - - @Override - protected void onPreExecute() { - if (mDialog != null) { - mDialog.setMessage("Uninstalling " + mDescriptor.getNiceName()); - mDialog.setIndeterminate(true); - mDialog.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - cancel(true); - } - }); - mDialog.show(); - } - } - - @Override - protected void onPostExecute(Boolean result) { - if (mDialog != null && mDialog.isShowing()) { - mDialog.dismiss(); - } - if (result) { - mListener.onTaskFinished(result, "Uninstallation successful."); - } else { - mListener.onTaskFinished(result, "Uninstallation failed."); - } - } - - @Override - protected Boolean doInBackground(Void... params) { - List<File> directories = new ArrayList<File>(); - - directories.add(new File(mInterpreterRoot)); - - if (mDescriptor.hasInterpreterArchive()) { - directories.add(InterpreterUtils.getInterpreterRoot(mContext, mDescriptor.getName())); - } - - for (File directory : directories) { - FileUtils.delete(directory); - } - - return cleanup(); - } - - protected boolean isInstalled() { - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); - return preferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); - } - - protected abstract boolean cleanup(); -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/UrlDownloaderTask.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/UrlDownloaderTask.java deleted file mode 100644 index f9ba053..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/UrlDownloaderTask.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.AsyncTask; - - -import com.googlecode.android_scripting.IoUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.exception.Sl4aException; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; - -/** - * AsyncTask for extracting ZIP files. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class UrlDownloaderTask extends AsyncTask<Void, Integer, Long> { - - private final URL mUrl; - private final File mFile; - private final ProgressDialog mDialog; - - private Throwable mException; - private OutputStream mProgressReportingOutputStream; - - private final class ProgressReportingOutputStream extends FileOutputStream { - private int mProgress = 0; - - private ProgressReportingOutputStream(File f) throws FileNotFoundException { - super(f); - } - - @Override - public void write(byte[] buffer, int offset, int count) throws IOException { - super.write(buffer, offset, count); - mProgress += count; - publishProgress(mProgress); - } - } - - public UrlDownloaderTask(String url, String out, Context context) throws MalformedURLException { - super(); - if (context != null) { - mDialog = new ProgressDialog(context); - } else { - mDialog = null; - } - mUrl = new URL(url); - String fileName = new File(mUrl.getFile()).getName(); - mFile = new File(out, fileName); - } - - @Override - protected void onPreExecute() { - Log.v("Downloading " + mUrl); - if (mDialog != null) { - mDialog.setTitle("Downloading"); - mDialog.setMessage(mFile.getName()); - // mDialog.setIndeterminate(true); - mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - cancel(true); - } - }); - mDialog.show(); - } - } - - @Override - protected Long doInBackground(Void... params) { - try { - return download(); - } catch (Exception e) { - if (mFile.exists()) { - // Clean up bad downloads. - mFile.delete(); - } - mException = e; - return null; - } - } - - @Override - protected void onProgressUpdate(Integer... progress) { - if (mDialog == null) { - return; - } - if (progress.length > 1) { - int contentLength = progress[1]; - if (contentLength == -1) { - mDialog.setIndeterminate(true); - } else { - mDialog.setMax(contentLength); - } - } else { - mDialog.setProgress(progress[0].intValue()); - } - } - - @Override - protected void onPostExecute(Long result) { - if (mDialog != null && mDialog.isShowing()) { - mDialog.dismiss(); - } - if (isCancelled()) { - return; - } - if (mException != null) { - Log.e("Download failed.", mException); - } - } - - @Override - protected void onCancelled() { - if (mDialog != null) { - mDialog.setTitle("Download cancelled."); - } - } - - private long download() throws Exception { - URLConnection connection = null; - try { - connection = mUrl.openConnection(); - } catch (IOException e) { - throw new Sl4aException("Cannot open URL: " + mUrl, e); - } - - int contentLength = connection.getContentLength(); - - if (mFile.exists() && contentLength == mFile.length()) { - Log.v("Output file already exists. Skipping download."); - return 0l; - } - - try { - mProgressReportingOutputStream = new ProgressReportingOutputStream(mFile); - } catch (FileNotFoundException e) { - throw new Sl4aException(e); - } - - publishProgress(0, contentLength); - - int bytesCopied = IoUtils.copy(connection.getInputStream(), mProgressReportingOutputStream); - if (bytesCopied != contentLength && contentLength != -1) { - throw new IOException("Download incomplete: " + bytesCopied + " != " + contentLength); - } - mProgressReportingOutputStream.close(); - Log.v("Download completed successfully."); - return bytesCopied; - } -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/ZipExtractorTask.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/ZipExtractorTask.java deleted file mode 100644 index 3d7eb01..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/ZipExtractorTask.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.AlertDialog; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnCancelListener; -import android.os.AsyncTask; - -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.future.FutureResult; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * AsyncTask for extracting ZIP files. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class ZipExtractorTask extends AsyncTask<Void, Integer, Long> { - - private static enum Replace { - YES, NO, YESTOALL, SKIPALL - } - - private final File mInput; - private final File mOutput; - private final ProgressDialog mDialog; - private Throwable mException; - private int mProgress = 0; - private final Context mContext; - private boolean mReplaceAll; - - private final class ProgressReportingOutputStream extends FileOutputStream { - private ProgressReportingOutputStream(File f) throws FileNotFoundException { - super(f); - } - - @Override - public void write(byte[] buffer, int offset, int count) throws IOException { - super.write(buffer, offset, count); - mProgress += count; - publishProgress(mProgress); - } - } - - public ZipExtractorTask(String in, String out, Context context, boolean replaceAll) - throws Sl4aException { - super(); - mInput = new File(in); - mOutput = new File(out); - if (!mOutput.exists()) { - if (!mOutput.mkdirs()) { - throw new Sl4aException("Failed to make directories: " + mOutput.getAbsolutePath()); - } - } - if (context != null) { - mDialog = new ProgressDialog(context); - } else { - mDialog = null; - } - - mContext = context; - mReplaceAll = replaceAll; - - } - - @Override - protected void onPreExecute() { - Log.v("Extracting " + mInput.getAbsolutePath() + " to " + mOutput.getAbsolutePath()); - if (mDialog != null) { - mDialog.setTitle("Extracting"); - mDialog.setMessage(mInput.getName()); - mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - mDialog.setOnCancelListener(new OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - cancel(true); - } - }); - mDialog.show(); - } - } - - @Override - protected Long doInBackground(Void... params) { - try { - return unzip(); - } catch (Exception e) { - if (mInput.exists()) { - // Clean up bad zip file. - mInput.delete(); - } - mException = e; - return null; - } - } - - @Override - protected void onProgressUpdate(Integer... progress) { - if (mDialog == null) { - return; - } - if (progress.length > 1) { - int max = progress[1]; - mDialog.setMax(max); - } else { - mDialog.setProgress(progress[0].intValue()); - } - } - - @Override - protected void onPostExecute(Long result) { - if (mDialog != null && mDialog.isShowing()) { - mDialog.dismiss(); - } - if (isCancelled()) { - return; - } - if (mException != null) { - Log.e("Zip extraction failed.", mException); - } - } - - @Override - protected void onCancelled() { - if (mDialog != null) { - mDialog.setTitle("Extraction cancelled."); - } - } - - private long unzip() throws Exception { - long extractedSize = 0l; - Enumeration<? extends ZipEntry> entries; - ZipFile zip = new ZipFile(mInput); - long uncompressedSize = getOriginalSize(zip); - - publishProgress(0, (int) uncompressedSize); - - entries = zip.entries(); - - try { - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (entry.isDirectory()) { - // Not all zip files actually include separate directory entries. - // We'll just ignore them - // and create them as necessary for each actual entry. - continue; - } - File destination = new File(mOutput, entry.getName()); - if (!destination.getParentFile().exists()) { - destination.getParentFile().mkdirs(); - } - if (destination.exists() && mContext != null && !mReplaceAll) { - Replace answer = showDialog(entry.getName()); - switch (answer) { - case YES: - break; - case NO: - continue; - case YESTOALL: - mReplaceAll = true; - break; - default: - return extractedSize; - } - } - ProgressReportingOutputStream outStream = new ProgressReportingOutputStream(destination); - extractedSize += IoUtils.copy(zip.getInputStream(entry), outStream); - outStream.close(); - } - } finally { - try { - zip.close(); - } catch (Exception e) { - // swallow this exception, we are only interested in the original one - } - } - Log.v("Extraction is complete."); - return extractedSize; - } - - private long getOriginalSize(ZipFile file) { - Enumeration<? extends ZipEntry> entries = file.entries(); - long originalSize = 0l; - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (entry.getSize() >= 0) { - originalSize += entry.getSize(); - } - } - return originalSize; - } - - private Replace showDialog(final String name) { - final FutureResult<Replace> mResult = new FutureResult<Replace>(); - - MainThread.run(mContext, new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(mContext); - builder.setTitle(String.format("Script \"%s\" already exist.", name)); - builder.setMessage(String.format("Do you want to replace script \"%s\" ?", name)); - - DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Replace result = Replace.SKIPALL; - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - result = Replace.YES; - break; - case DialogInterface.BUTTON_NEGATIVE: - result = Replace.NO; - break; - case DialogInterface.BUTTON_NEUTRAL: - result = Replace.YESTOALL; - break; - } - mResult.set(result); - dialog.dismiss(); - } - }; - builder.setNegativeButton("Skip", buttonListener); - builder.setPositiveButton("Replace", buttonListener); - builder.setNeutralButton("Replace All", buttonListener); - - builder.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - mResult.set(Replace.SKIPALL); - dialog.dismiss(); - } - }); - builder.show(); - } - }); - - try { - return mResult.get(); - } catch (InterruptedException e) { - Log.e(e); - } - return null; - } -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/activity/Main.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/activity/Main.java deleted file mode 100644 index 2af4d17..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/activity/Main.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.Gravity; -import android.view.View; -import android.view.Window; -import android.view.View.OnClickListener; -import android.view.ViewGroup.LayoutParams; -import android.view.ViewGroup.MarginLayoutParams; -import android.widget.Button; -import android.widget.LinearLayout; - -import com.googlecode.android_scripting.AsyncTaskListener; -import com.googlecode.android_scripting.InterpreterInstaller; -import com.googlecode.android_scripting.InterpreterUninstaller; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; -import com.googlecode.android_scripting.interpreter.InterpreterDescriptor; - -/** - * Base activity for distributing interpreters as APK's. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public abstract class Main extends Activity { - - protected final static float MARGIN_DIP = 3.0f; - - protected final String mId = getClass().getPackage().getName(); - - protected SharedPreferences mPreferences; - protected InterpreterDescriptor mDescriptor; - protected Button mButton; - protected LinearLayout mLayout; - - protected abstract InterpreterDescriptor getDescriptor(); - - protected abstract InterpreterInstaller getInterpreterInstaller(InterpreterDescriptor descriptor, - Context context, AsyncTaskListener<Boolean> listener) throws Sl4aException; - - protected abstract InterpreterUninstaller getInterpreterUninstaller( - InterpreterDescriptor descriptor, Context context, AsyncTaskListener<Boolean> listener) - throws Sl4aException; - - protected enum RunningTask { - INSTALL, UNINSTALL - } - - protected volatile RunningTask mCurrentTask = null; - - protected final AsyncTaskListener<Boolean> mTaskListener = new AsyncTaskListener<Boolean>() { - @Override - public void onTaskFinished(Boolean result, String message) { - getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, - Window.PROGRESS_VISIBILITY_OFF); - if (result) { - switch (mCurrentTask) { - case INSTALL: - setInstalled(true); - prepareUninstallButton(); - break; - case UNINSTALL: - setInstalled(false); - prepareInstallButton(); - break; - } - } - Log.v(Main.this, message); - mCurrentTask = null; - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - mDescriptor = getDescriptor(); - - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - initializeViews(); - if (checkInstalled()) { - prepareUninstallButton(); - } else { - prepareInstallButton(); - } - } - - @Override - protected void onStop() { - super.onStop(); - finish(); - } - - // TODO(alexey): Pull out to a layout XML? - protected void initializeViews() { - mLayout = new LinearLayout(this); - mLayout.setOrientation(LinearLayout.VERTICAL); - mLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - mLayout.setGravity(Gravity.CENTER_HORIZONTAL); - - mButton = new Button(this); - MarginLayoutParams marginParams = - new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - final float scale = getResources().getDisplayMetrics().density; - int marginPixels = (int) (MARGIN_DIP * scale + 0.5f); - marginParams.setMargins(marginPixels, marginPixels, marginPixels, marginPixels); - mButton.setLayoutParams(marginParams); - mLayout.addView(mButton); - setContentView(mLayout); - } - - protected void prepareInstallButton() { - mButton.setText("Install"); - mButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - install(); - } - }); - } - - protected void prepareUninstallButton() { - mButton.setText("Uninstall"); - mButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - uninstall(); - } - }); - } - - protected void broadcastInstallationStateChange(boolean isInterpreterInstalled) { - Intent intent = new Intent(); - intent.setData(Uri.parse("package:" + mId)); - if (isInterpreterInstalled) { - intent.setAction(InterpreterConstants.ACTION_INTERPRETER_ADDED); - } else { - intent.setAction(InterpreterConstants.ACTION_INTERPRETER_REMOVED); - } - sendBroadcast(intent); - } - - protected synchronized void install() { - if (mCurrentTask != null) { - return; - } - getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, Window.PROGRESS_VISIBILITY_ON); - mCurrentTask = RunningTask.INSTALL; - InterpreterInstaller installTask; - try { - installTask = getInterpreterInstaller(mDescriptor, Main.this, mTaskListener); - } catch (Sl4aException e) { - Log.e(this, e.getMessage(), e); - return; - } - installTask.execute(); - } - - protected synchronized void uninstall() { - if (mCurrentTask != null) { - return; - } - getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, Window.PROGRESS_VISIBILITY_ON); - mCurrentTask = RunningTask.UNINSTALL; - InterpreterUninstaller uninstallTask; - try { - uninstallTask = getInterpreterUninstaller(mDescriptor, Main.this, mTaskListener); - } catch (Sl4aException e) { - Log.e(this, e.getMessage(), e); - return; - } - uninstallTask.execute(); - } - - protected void setInstalled(boolean isInstalled) { - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, isInstalled); - editor.commit(); - broadcastInstallationStateChange(isInstalled); - } - - protected boolean checkInstalled() { - boolean isInstalled = - mPreferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); - broadcastInstallationStateChange(isInstalled); - return isInstalled; - } - - public LinearLayout getLayout() { - return mLayout; - } - -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/InterpreterProvider.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/InterpreterProvider.java deleted file mode 100644 index 500c5d4..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/InterpreterProvider.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.UriMatcher; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.preference.PreferenceManager; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * A provider that can be queried to obtain execution-related interpreter info. - * - * <p> - * To create an interpreter APK, please extend this content provider and implement getDescriptor() - * and getEnvironmentSettings().<br> - * Please declare the provider in the android manifest xml (the authority values has to be set to - * your_package_name.provider_name). - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public abstract class InterpreterProvider extends ContentProvider { - - private static final int PROPERTIES = 1; - private static final int ENVIRONMENT_VARIABLES = 2; - private static final int ARGUMENTS = 3; - - private UriMatcher mUriMatcher; - private SharedPreferences mPreferences; - - private InterpreterDescriptor mDescriptor; - private Context mContext; - - public static final String MIME = "vnd.android.cursor.item/vnd.googlecode.interpreter"; - - public InterpreterProvider() { - mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - String auth = this.getClass().getName().toLowerCase(); - mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_PROPERTIES, PROPERTIES); - mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ENVIRONMENT_VARIABLES, - ENVIRONMENT_VARIABLES); - mUriMatcher.addURI(auth, InterpreterConstants.PROVIDER_ARGUMENTS, ARGUMENTS); - } - - /** - * Returns an instance of the class that implements the desired {@link InterpreterDescriptor}. - */ - protected abstract InterpreterDescriptor getDescriptor(); - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - return 0; - } - - @Override - public String getType(Uri uri) { - return MIME; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - return null; - } - - @Override - public boolean onCreate() { - mDescriptor = getDescriptor(); - mContext = getContext(); - mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); - return false; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - if (!isInterpreterInstalled()) { - return null; - } - Map<String, String> map; - switch (mUriMatcher.match(uri)) { - case PROPERTIES: - map = getProperties(); - break; - case ENVIRONMENT_VARIABLES: - map = getEnvironmentVariables(); - break; - case ARGUMENTS: - map = getArguments(); - break; - default: - map = null; - } - return buildCursorFromMap(map); - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - return 0; - } - - private boolean isInterpreterInstalled() { - return mPreferences.getBoolean(InterpreterConstants.INSTALLED_PREFERENCE_KEY, false); - } - - private Cursor buildCursorFromMap(Map<String, String> map) { - if (map == null) { - return null; - } - MatrixCursor cursor = new MatrixCursor(map.keySet().toArray(new String[map.size()])); - cursor.addRow(map.values()); - return cursor; - } - - private Map<String, String> getProperties() { - Map<String, String> values = new HashMap<String, String>(); - values.put(InterpreterPropertyNames.NAME, mDescriptor.getName()); - values.put(InterpreterPropertyNames.NICE_NAME, mDescriptor.getNiceName()); - values.put(InterpreterPropertyNames.EXTENSION, mDescriptor.getExtension()); - values.put(InterpreterPropertyNames.BINARY, mDescriptor.getBinary(mContext).getAbsolutePath()); - values.put(InterpreterPropertyNames.INTERACTIVE_COMMAND, mDescriptor - .getInteractiveCommand(mContext)); - values.put(InterpreterPropertyNames.SCRIPT_COMMAND, mDescriptor.getScriptCommand(mContext)); - values.put(InterpreterPropertyNames.HAS_INTERACTIVE_MODE, Boolean.toString(mDescriptor - .hasInteractiveMode())); - return values; - } - - private Map<String, String> getEnvironmentVariables() { - Map<String, String> values = new HashMap<String, String>(); - values.putAll(mDescriptor.getEnvironmentVariables(mContext)); - return values; - } - - private Map<String, String> getArguments() { - Map<String, String> values = new LinkedHashMap<String, String>(); - int column = 0; - for (String argument : mDescriptor.getArguments(mContext)) { - values.put(Integer.toString(column), argument); - column++; - } - return values; - } -} diff --git a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/Sl4aHostedInterpreter.java b/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/Sl4aHostedInterpreter.java deleted file mode 100644 index e6ca41c..0000000 --- a/sl4a/InterpreterForAndroid/src/com/googlecode/android_scripting/interpreter/Sl4aHostedInterpreter.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.content.Context; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * A description of the interpreters hosted by the SL4A project. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public abstract class Sl4aHostedInterpreter implements InterpreterDescriptor { - - public static final String BASE_INSTALL_URL = "http://android-scripting.googlecode.com/files/"; - public static final String DALVIKVM = "/system/bin/dalvikvm"; - - // TODO(damonkohler): Remove getVersion() and pull these three version methods up in to the base - // class. - - public String getBaseInstallUrl() { - return BASE_INSTALL_URL; - } - - public int getInterpreterVersion() { - return getVersion(); - } - - public int getExtrasVersion() { - return getVersion(); - } - - public int getScriptsVersion() { - return getVersion(); - } - - @Override - public String getInterpreterArchiveName() { - return String.format("%s_r%s.zip", getName(), getInterpreterVersion()); - } - - @Override - public String getExtrasArchiveName() { - return String.format("%s_extras_r%s.zip", getName(), getExtrasVersion()); - } - - @Override - public String getScriptsArchiveName() { - return String.format("%s_scripts_r%s.zip", getName(), getScriptsVersion()); - } - - @Override - public String getInterpreterArchiveUrl() { - return getBaseInstallUrl() + getInterpreterArchiveName(); - } - - @Override - public String getExtrasArchiveUrl() { - return getBaseInstallUrl() + getExtrasArchiveName(); - } - - @Override - public String getScriptsArchiveUrl() { - return getBaseInstallUrl() + getScriptsArchiveName(); - } - - @Override - public String getInteractiveCommand(Context context) { - return ""; - } - - @Override - public boolean hasInteractiveMode() { - return true; - } - - @Override - public String getScriptCommand(Context context) { - return "%s"; - } - - @Override - public List<String> getArguments(Context context) { - return new ArrayList<String>(); - } - - @Override - public Map<String, String> getEnvironmentVariables(Context context) { - return new HashMap<String, String>(); - } - - // TODO(damonkohler): This shouldn't be public. - public File getExtrasPath(Context context) { - if (!hasInterpreterArchive() && hasExtrasArchive()) { - return new File(InterpreterConstants.SDCARD_ROOT + this.getClass().getPackage().getName() - + InterpreterConstants.INTERPRETER_EXTRAS_ROOT, getName()); - } - return InterpreterUtils.getInterpreterRoot(context, getName()); - } -} diff --git a/sl4a/README b/sl4a/README deleted file mode 100644 index cf7b58b..0000000 --- a/sl4a/README +++ /dev/null @@ -1,61 +0,0 @@ -============================= -Project Info -============================= -Scripting Layer For Android - -Originally authored by Damon Kohler, Scripting Layer for Android, SL4A, is an automation toolset -for calling Android APIs in a platform-independent manner. It supports both remote automation via -ADB as well as execution of scripts from on-device via a series of lightweight translation layers. - -============================= -Build Instructions -============================= - -Due to its inclusion in AOSP as a privileged app, building SL4A requires a system build. - -For the initial build of Android: - -1) cd <ANDROID_SOURCE_ROOT> -2) source build/envsetup.sh -3) lunch <TARGET> -4) make [-j15] - -Then Build SL4A: - -1) cd <ANDROID_SOURCE_ROOT>/packages/apps/Test/connectivity/sl4a -2) mm [-j15] - -=========================== -Install Instructions -=========================== - -1) adb install -r <ANDROID_SOURCE_ROOT>/out/target/product/<TARGET>/data/app/sl4a/sl4a.apk - -=========================== -Run Instructions -=========================== - -1) SL4A may be launched from Android as a normal App. - -or; - -2) To enable RPC access from the command prompt: - - 1) adb forward tcp:<HOST_PORT_NUM> tcp:<DEVICE_PORT_NUM> - 2) adb shell "am start -a com.googlecode.android_scripting.action.LAUNCH_SERVER \ - --ei com.googlecode.android_scripting.extra.USE_SERVICE_PORT <DEVICE_PORT_NUM> \ - com.googlecode.android_scripting/.activity.ScriptingLayerServiceLauncher" - - where <HOST_PORT_NUM> and <DEVICE_PORT_NUM> are the tcp ports on the host computer and device. - - -=========================== -Doc Generation Instructions -=========================== - -From SL4A source directory run this command: - 1)"perl Docs/generate_api_reference_md.pl" - -In the Docs direcotry there should now be an ApiReference.md file that -contains which RPC functions are available in SL4A as well as documentation -for the RPC functions. diff --git a/sl4a/ScriptingLayer/Android.mk b/sl4a/ScriptingLayer/Android.mk deleted file mode 100644 index 2871eff..0000000 --- a/sl4a/ScriptingLayer/Android.mk +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - - -LOCAL_MODULE := sl4a.ScriptingLayer -LOCAL_MODULE_OWNER := google - -LOCAL_STATIC_JAVA_LIBRARIES := guava android-common -LOCAL_STATIC_JAVA_LIBRARIES += sl4a.Utils sl4a.Common - -LOCAL_SRC_FILES := $(call all-java-files-under, src/com/googlecode/android_scripting) - - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/AndroidProxy.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/AndroidProxy.java deleted file mode 100644 index 997582c..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/AndroidProxy.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.Service; -import android.content.Intent; - -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.facade.FacadeManagerFactory; -import com.googlecode.android_scripting.jsonrpc.JsonRpcServer; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; - -import java.net.InetSocketAddress; -import java.util.UUID; - -public class AndroidProxy { - - private InetSocketAddress mAddress; - private final JsonRpcServer mJsonRpcServer; - private final UUID mSecret; - private final RpcReceiverManagerFactory mFacadeManagerFactory; - - /** - * - * @param service - * Android service (required to build facades). - * @param intent - * the intent that launched the proxy/script. - * @param requiresHandshake - * indicates whether RPC security protocol should be enabled. - */ - public AndroidProxy(Service service, Intent intent, boolean requiresHandshake) { - if (requiresHandshake) { - mSecret = UUID.randomUUID(); - } else { - mSecret = null; - } - mFacadeManagerFactory = - new FacadeManagerFactory(FacadeConfiguration.getSdkLevel(), service, intent, - FacadeConfiguration.getFacadeClasses()); - mJsonRpcServer = new JsonRpcServer(mFacadeManagerFactory, getSecret()); - } - - public InetSocketAddress getAddress() { - return mAddress; - } - - public InetSocketAddress startLocal() { - return startLocal(0); - } - - public InetSocketAddress startLocal(int port) { - mAddress = mJsonRpcServer.startLocal(port); - return mAddress; - } - - public InetSocketAddress startPublic() { - return startPublic(0); - } - - public InetSocketAddress startPublic(int port) { - mAddress = mJsonRpcServer.startPublic(port); - return mAddress; - } - - public void shutdown() { - mJsonRpcServer.shutdown(); - } - - public String getSecret() { - if (mSecret == null) { - return null; - } - return mSecret.toString(); - } - - public RpcReceiverManagerFactory getRpcReceiverManagerFactory() { - return mFacadeManagerFactory; - } -} diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptLauncher.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptLauncher.java deleted file mode 100644 index a0f3eb8..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptLauncher.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.Service; -import android.content.Intent; - -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; - -import java.io.File; - -public class ScriptLauncher { - - private ScriptLauncher() { - // Utility class. - } - - public static InterpreterProcess launchInterpreter(final AndroidProxy proxy, Intent intent, - InterpreterConfiguration config, Runnable shutdownHook) { - Interpreter interpreter; - String interpreterName; - interpreterName = intent.getStringExtra(Constants.EXTRA_INTERPRETER_NAME); - interpreter = config.getInterpreterByName(interpreterName); - InterpreterProcess process = new InterpreterProcess(interpreter, proxy); - if (shutdownHook == null) { - process.start(new Runnable() { - @Override - public void run() { - proxy.shutdown(); - } - }); - } else { - process.start(shutdownHook); - } - return process; - } - - public static ScriptProcess launchScript(File script, InterpreterConfiguration configuration, - final AndroidProxy proxy, Runnable shutdownHook) { - if (!script.exists()) { - throw new RuntimeException("No such script to launch."); - } - ScriptProcess process = new ScriptProcess(script, configuration, proxy); - if (shutdownHook == null) { - process.start(new Runnable() { - @Override - public void run() { - proxy.shutdown(); - } - }); - } else { - process.start(shutdownHook); - } - return process; - } -} diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptProcess.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptProcess.java deleted file mode 100644 index 607bb64..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptProcess.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; - -import java.io.File; - -public class ScriptProcess extends InterpreterProcess { - - private final File mScript; - - public ScriptProcess(File script, InterpreterConfiguration configuration, AndroidProxy proxy) { - super(configuration.getInterpreterForScript(script.getName()), proxy); - mScript = script; - String scriptName = script.getName(); - setName(scriptName); - Interpreter interpreter = configuration.getInterpreterForScript(scriptName); - setCommand(String.format(interpreter.getScriptCommand(), script.getAbsolutePath())); - } - - public String getPath() { - return mScript.getPath(); - } - -} diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptStorageAdapter.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptStorageAdapter.java deleted file mode 100644 index 96608c1..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/ScriptStorageAdapter.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * Manages storage and retrieval of scripts on the file system. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ScriptStorageAdapter { - - private ScriptStorageAdapter() { - // Utility class. - } - - /** - * Writes data to the script by name and overwrites any existing data. - */ - public static void writeScript(File script, String data) { - if (script.getParent() == null) { - script = new File(InterpreterConstants.SCRIPTS_ROOT, script.getPath()); - } - try { - FileWriter stream = new FileWriter(script, false /* overwrite */); - BufferedWriter out = new BufferedWriter(stream); - out.write(data); - out.close(); - } catch (IOException e) { - Log.e("Failed to write script.", e); - } - } - - /** - * Returns a list of all available script {@link File}s. - */ - public static List<File> listAllScripts(File dir) { - if (dir == null) { - dir = new File(InterpreterConstants.SCRIPTS_ROOT); - } - if (dir.exists()) { - List<File> scripts = Arrays.asList(dir.listFiles()); - Collections.sort(scripts, new Comparator<File>() { - @Override - public int compare(File file1, File file2) { - if (file1.isDirectory() && !file2.isDirectory()) { - return -1; - } else if (!file1.isDirectory() && file2.isDirectory()) { - return 1; - } - return file1.compareTo(file2); - } - }); - return scripts; - } - return new ArrayList<File>(); - } - - /** - * Returns a list of script {@link File}s from the given folder for which there is an interpreter - * installed. - */ - public static List<File> listExecutableScripts(File directory, InterpreterConfiguration config) { - // NOTE(damonkohler): Creating a LinkedList here is necessary in order to be able to filter it - // later. - List<File> scripts = new LinkedList<File>(listAllScripts(directory)); - // Filter out any files that don't have interpreters installed. - for (Iterator<File> it = scripts.iterator(); it.hasNext();) { - File script = it.next(); - if (script.isDirectory()) { - continue; - } - Interpreter interpreter = config.getInterpreterForScript(script.getName()); - if (interpreter == null || !interpreter.isInstalled()) { - it.remove(); - } - } - return scripts; - } - - /** - * Returns a list of all (including subfolders) script {@link File}s for which there is an - * interpreter installed. - */ - public static List<File> listExecutableScriptsRecursively(File directory, - InterpreterConfiguration config) { - // NOTE(damonkohler): Creating a LinkedList here is necessary in order to be able to filter it - // later. - List<File> scripts = new LinkedList<File>(); - List<File> files = listAllScripts(directory); - - // Filter out any files that don't have interpreters installed. - for (Iterator<File> it = files.iterator(); it.hasNext();) { - File file = it.next(); - if (file.isDirectory()) { - scripts.addAll(listExecutableScriptsRecursively(file, config)); - } - Interpreter interpreter = config.getInterpreterForScript(file.getName()); - if (interpreter != null && interpreter.isInstalled()) { - scripts.add(file); - } - } - Collections.sort(scripts); - return scripts; - } -}
\ No newline at end of file diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java deleted file mode 100644 index b297580..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/facade/FacadeConfiguration.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.facade; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import com.google.common.collect.Maps; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothA2dpFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothAvrcpFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothConnectionFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothHidFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothHspFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeAdvertiseFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothLeScanFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothMapFacade; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothRfcommFacade; -import com.googlecode.android_scripting.facade.bluetooth.GattClientFacade; -import com.googlecode.android_scripting.facade.bluetooth.GattServerFacade; -import com.googlecode.android_scripting.facade.media.AudioManagerFacade; -import com.googlecode.android_scripting.facade.media.MediaPlayerFacade; -import com.googlecode.android_scripting.facade.media.MediaRecorderFacade; -import com.googlecode.android_scripting.facade.media.MediaScannerFacade; -import com.googlecode.android_scripting.facade.media.MediaSessionFacade; -import com.googlecode.android_scripting.facade.telephony.CarrierConfigFacade; -import com.googlecode.android_scripting.facade.telephony.ImsManagerFacade; -import com.googlecode.android_scripting.facade.telephony.SmsFacade; -import com.googlecode.android_scripting.facade.telephony.SubscriptionManagerFacade; -import com.googlecode.android_scripting.facade.telephony.TelecomCallFacade; -import com.googlecode.android_scripting.facade.telephony.TelecomManagerFacade; -import com.googlecode.android_scripting.facade.telephony.TelephonyManagerFacade; -import com.googlecode.android_scripting.facade.ui.UiFacade; -import com.googlecode.android_scripting.facade.wifi.HttpFacade; -import com.googlecode.android_scripting.facade.wifi.WifiManagerFacade; -import com.googlecode.android_scripting.facade.wifi.WifiNanManagerFacade; -import com.googlecode.android_scripting.facade.wifi.WifiP2pManagerFacade; -import com.googlecode.android_scripting.facade.wifi.WifiRttManagerFacade; -import com.googlecode.android_scripting.facade.wifi.WifiScannerFacade; -import com.googlecode.android_scripting.jsonrpc.RpcReceiver; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcMinSdk; -import com.googlecode.android_scripting.rpc.RpcStartEvent; -import com.googlecode.android_scripting.rpc.RpcStopEvent; -import com.googlecode.android_scripting.webcam.WebCamFacade; - -/** - * Encapsulates the list of supported facades and their construction. - */ -public class FacadeConfiguration { - private final static Set<Class<? extends RpcReceiver>> sFacadeClassList; - private final static SortedMap<String, MethodDescriptor> sRpcs = - new TreeMap<String, MethodDescriptor>(); - - private static int sSdkLevel; - - static { - sSdkLevel = android.os.Build.VERSION.SDK_INT; - - sFacadeClassList = new HashSet<Class<? extends RpcReceiver>>(); - sFacadeClassList.add(ActivityResultFacade.class); - sFacadeClassList.add(AndroidFacade.class); - sFacadeClassList.add(ApplicationManagerFacade.class); - sFacadeClassList.add(AudioManagerFacade.class); - sFacadeClassList.add(BatteryManagerFacade.class); - sFacadeClassList.add(CameraFacade.class); - sFacadeClassList.add(CommonIntentsFacade.class); - sFacadeClassList.add(ContactsFacade.class); - sFacadeClassList.add(EventFacade.class); - sFacadeClassList.add(ImsManagerFacade.class); - sFacadeClassList.add(LocationFacade.class); - sFacadeClassList.add(TelephonyManagerFacade.class); - sFacadeClassList.add(PreferencesFacade.class); - sFacadeClassList.add(MediaPlayerFacade.class); - sFacadeClassList.add(MediaRecorderFacade.class); - sFacadeClassList.add(MediaScannerFacade.class); - sFacadeClassList.add(MediaSessionFacade.class); - sFacadeClassList.add(SensorManagerFacade.class); - sFacadeClassList.add(SettingsFacade.class); - sFacadeClassList.add(SmsFacade.class); - sFacadeClassList.add(SpeechRecognitionFacade.class); - sFacadeClassList.add(ToneGeneratorFacade.class); - sFacadeClassList.add(WakeLockFacade.class); - sFacadeClassList.add(HttpFacade.class); - sFacadeClassList.add(WifiManagerFacade.class); - sFacadeClassList.add(UiFacade.class); - sFacadeClassList.add(TextToSpeechFacade.class); - sFacadeClassList.add(BluetoothFacade.class); - sFacadeClassList.add(BluetoothA2dpFacade.class); - sFacadeClassList.add(BluetoothAvrcpFacade.class); - sFacadeClassList.add(BluetoothConnectionFacade.class); - sFacadeClassList.add(BluetoothHspFacade.class); - sFacadeClassList.add(BluetoothHidFacade.class); - sFacadeClassList.add(BluetoothMapFacade.class); - sFacadeClassList.add(BluetoothRfcommFacade.class); - sFacadeClassList.add(WebCamFacade.class); - sFacadeClassList.add(WifiP2pManagerFacade.class); - sFacadeClassList.add(BluetoothLeScanFacade.class); - sFacadeClassList.add(BluetoothLeAdvertiseFacade.class); - sFacadeClassList.add(GattClientFacade.class); - sFacadeClassList.add(GattServerFacade.class); - sFacadeClassList.add(ConnectivityManagerFacade.class); - sFacadeClassList.add(DisplayFacade.class); - sFacadeClassList.add(TelecomManagerFacade.class); - sFacadeClassList.add(WifiRttManagerFacade.class); - sFacadeClassList.add(WifiScannerFacade.class); - sFacadeClassList.add(SubscriptionManagerFacade.class); - sFacadeClassList.add(TelecomCallFacade.class); - sFacadeClassList.add(CarrierConfigFacade.class); - - /*Compatibility reset to >= Marshmallow */ - if( sSdkLevel >= 23 ) { - //add new facades here - sFacadeClassList.add(WifiNanManagerFacade.class); - } - - for (Class<? extends RpcReceiver> recieverClass : sFacadeClassList) { - for (MethodDescriptor rpcMethod : MethodDescriptor.collectFrom(recieverClass)) { - sRpcs.put(rpcMethod.getName(), rpcMethod); - } - } - } - - private FacadeConfiguration() { - // Utility class. - } - - public static int getSdkLevel() { - return sSdkLevel; - } - - /** Returns a list of {@link MethodDescriptor} objects for all facades. */ - public static List<MethodDescriptor> collectMethodDescriptors() { - return new ArrayList<MethodDescriptor>(sRpcs.values()); - } - - /** - * Returns a list of not deprecated {@link MethodDescriptor} objects for facades supported by - * the current SDK version. - */ - public static List<MethodDescriptor> collectSupportedMethodDescriptors() { - List<MethodDescriptor> list = new ArrayList<MethodDescriptor>(); - for (MethodDescriptor descriptor : sRpcs.values()) { - Method method = descriptor.getMethod(); - if (method.isAnnotationPresent(RpcDeprecated.class)) { - continue; - } else if (method.isAnnotationPresent(RpcMinSdk.class)) { - int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value(); - if (sSdkLevel < requiredSdkLevel) { - continue; - } - } - list.add(descriptor); - } - return list; - } - - public static Map<String, MethodDescriptor> collectStartEventMethodDescriptors() { - Map<String, MethodDescriptor> map = Maps.newHashMap(); - for (MethodDescriptor descriptor : sRpcs.values()) { - Method method = descriptor.getMethod(); - if (method.isAnnotationPresent(RpcStartEvent.class)) { - String eventName = method.getAnnotation(RpcStartEvent.class).value(); - if (map.containsKey(eventName)) { - Log.d("Duplicate eventName " + eventName); - throw new RuntimeException("Duplicate start event method descriptor found."); - } - map.put(eventName, descriptor); - } - } - return map; - } - - public static Map<String, MethodDescriptor> collectStopEventMethodDescriptors() { - Map<String, MethodDescriptor> map = Maps.newHashMap(); - for (MethodDescriptor descriptor : sRpcs.values()) { - Method method = descriptor.getMethod(); - if (method.isAnnotationPresent(RpcStopEvent.class)) { - String eventName = method.getAnnotation(RpcStopEvent.class).value(); - if (map.containsKey(eventName)) { - throw new RuntimeException("Duplicate stop event method descriptor found."); - } - map.put(eventName, descriptor); - } - } - return map; - } - - /** Returns a method by name. */ - public static MethodDescriptor getMethodDescriptor(String name) { - return sRpcs.get(name); - } - - public static Collection<Class<? extends RpcReceiver>> getFacadeClasses() { - return sFacadeClassList; - } -} diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/interpreter/InterpreterProcess.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/interpreter/InterpreterProcess.java deleted file mode 100644 index 52a12c0..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/interpreter/InterpreterProcess.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import com.googlecode.android_scripting.AndroidProxy; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.Process; -import com.googlecode.android_scripting.SimpleServer; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; - -import java.net.InetSocketAddress; -import java.net.SocketException; -import java.net.UnknownHostException; - -/** - * This is a skeletal implementation of an interpreter process. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class InterpreterProcess extends Process { - - private final AndroidProxy mProxy; - private final Interpreter mInterpreter; - private String mCommand; - - /** - * Creates a new {@link InterpreterProcess}. - * - * @param launchScript - * the absolute path to a script that should be launched with the interpreter - * @param port - * the port that the AndroidProxy is listening on - */ - public InterpreterProcess(Interpreter interpreter, AndroidProxy proxy) { - mProxy = proxy; - mInterpreter = interpreter; - - setBinary(interpreter.getBinary()); - setName(interpreter.getNiceName()); - setCommand(interpreter.getInteractiveCommand()); - addAllArguments(interpreter.getArguments()); - putAllEnvironmentVariables(System.getenv()); - putEnvironmentVariable("AP_HOST", getHost()); - putEnvironmentVariable("AP_PORT", Integer.toString(getPort())); - if (proxy.getSecret() != null) { - putEnvironmentVariable("AP_HANDSHAKE", getSecret()); - } - putAllEnvironmentVariables(interpreter.getEnvironmentVariables()); - } - - protected void setCommand(String command) { - mCommand = command; - } - - public Interpreter getInterpreter() { - return mInterpreter; - } - - public String getHost() { - String result = mProxy.getAddress().getHostName(); - if (result.equals("0.0.0.0")) { // Wildcard. - try { - return SimpleServer.getPublicInetAddress().getHostName(); - } catch (UnknownHostException e) { - Log.i("public address", e); - e.printStackTrace(); - } catch (SocketException e) { - Log.i("public address", e); - } - } - return result; - } - - public int getPort() { - return mProxy.getAddress().getPort(); - } - - public InetSocketAddress getAddress() { - return mProxy.getAddress(); - } - - public String getSecret() { - return mProxy.getSecret(); - } - - public RpcReceiverManagerFactory getRpcReceiverManagerFactory() { - return mProxy.getRpcReceiverManagerFactory(); - } - - @Override - public void start(final Runnable shutdownHook) { - if (!mCommand.isEmpty()) { - addArgument(mCommand); - } - super.start(shutdownHook); - } - - @Override - public void kill() { - super.kill(); - mProxy.shutdown(); - } - - @Override - public String getWorkingDirectory() { - return InterpreterConstants.SDCARD_SL4A_ROOT; - } -} diff --git a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/trigger/EventGenerationControllingObserver.java b/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/trigger/EventGenerationControllingObserver.java deleted file mode 100644 index 0c38a0f..0000000 --- a/sl4a/ScriptingLayer/src/com/googlecode/android_scripting/trigger/EventGenerationControllingObserver.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.trigger; - -import com.google.common.collect.Maps; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.trigger.TriggerRepository.TriggerRepositoryObserver; - -import java.util.Map; - -import org.json.JSONArray; - -/** - * A {@link TriggerRepositoryObserver} that starts and stops the monitoring of events depending on - * whether or not triggers for the event exist. - * - * @author Felix Arends (felix.arends@gmail.com) - */ -public class EventGenerationControllingObserver implements TriggerRepositoryObserver { - private final FacadeManager mFacadeManager; - private final Map<String, MethodDescriptor> mStartEventGeneratingMethodDescriptors; - private final Map<String, MethodDescriptor> mStopEventGeneratingMethodDescriptors; - private final Map<String, Integer> mEventTriggerRefCounts = Maps.newHashMap(); - - /** - * Creates a new StartEventMonitoringObserver for the given trigger repository. - * - * @param facadeManager - * @param triggerRepository - */ - public EventGenerationControllingObserver(FacadeManager facadeManager) { - mFacadeManager = facadeManager; - mStartEventGeneratingMethodDescriptors = - FacadeConfiguration.collectStartEventMethodDescriptors(); - mStopEventGeneratingMethodDescriptors = FacadeConfiguration.collectStopEventMethodDescriptors(); - } - - private synchronized int incrementAndGetRefCount(String eventName) { - int refCount = - (mEventTriggerRefCounts.containsKey(eventName)) ? mEventTriggerRefCounts.get(eventName) : 0; - refCount++; - mEventTriggerRefCounts.put(eventName, refCount); - return refCount; - } - - private synchronized int decrementAndGetRefCount(String eventName) { - int refCount = - (mEventTriggerRefCounts.containsKey(eventName)) ? mEventTriggerRefCounts.get(eventName) : 0; - refCount--; - mEventTriggerRefCounts.put(eventName, refCount); - return refCount; - } - - @Override - public synchronized void onPut(Trigger trigger) { - // If we're not already monitoring the events corresponding to this trigger, do so. - if (incrementAndGetRefCount(trigger.getEventName()) == 1) { - startMonitoring(trigger.getEventName()); - } - } - - @Override - public synchronized void onRemove(Trigger trigger) { - // If there are no more triggers listening to this event, then we need to stop monitoring. - if (decrementAndGetRefCount(trigger.getEventName()) == 1) { - stopMonitoring(trigger.getEventName()); - } - } - - private void startMonitoring(String eventName) { - MethodDescriptor startEventGeneratingMethod = - mStartEventGeneratingMethodDescriptors.get(eventName); - try { - startEventGeneratingMethod.invoke(mFacadeManager, new JSONArray()); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } - - private void stopMonitoring(String eventName) { - MethodDescriptor stopEventGeneratingMethod = - mStopEventGeneratingMethodDescriptors.get(eventName); - try { - stopEventGeneratingMethod.invoke(mFacadeManager, new JSONArray()); - } catch (Throwable t) { - throw new RuntimeException(t); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/Android.mk b/sl4a/ScriptingLayerForAndroid/Android.mk deleted file mode 100644 index 79f66c3..0000000 --- a/sl4a/ScriptingLayerForAndroid/Android.mk +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_PACKAGE_NAME := sl4a -LOCAL_MODULE_OWNER := google -LOCAL_DEX_PREOPT := false - -LOCAL_CERTIFICATE := platform - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res - -LOCAL_AAPT_FLAGS := --auto-add-overlay - -LOCAL_MULTILIB := both - -# Builds on the Data Partition -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_STATIC_JAVA_LIBRARIES := guava android-common locale_platform android-support-v4 -LOCAL_STATIC_JAVA_LIBRARIES += sl4a.Utils sl4a.Common -LOCAL_STATIC_JAVA_LIBRARIES += sl4a.InterpreterForAndroid sl4a.ScriptingLayer - -LOCAL_PRIVILEGED_MODULE := true -LOCAL_PROGUARD_ENABLED := disabled - - -LOCAL_JNI_SHARED_LIBRARIES := libcom_googlecode_android_scripting_Exec - -include $(PREBUILT_SHARED_LIBRARY) - -include $(BUILD_PACKAGE) - -include $(CLEAR_VARS) -LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := locale_platform:libs/locale_platform.jar -include $(BUILD_MULTI_PREBUILT) - -include $(call all-makefiles-under,$(LOCAL_PATH)) - diff --git a/sl4a/ScriptingLayerForAndroid/AndroidManifest.xml b/sl4a/ScriptingLayerForAndroid/AndroidManifest.xml deleted file mode 100644 index cc9f2b8..0000000 --- a/sl4a/ScriptingLayerForAndroid/AndroidManifest.xml +++ /dev/null @@ -1,220 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.googlecode.android_scripting" - android:sharedUserId="android.uid.system"> - - <uses-permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" - android:protectionLevel="signature" /> - <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" - android:protectionLevel="signature" /> - <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> - <uses-permission android:name="android.permission.INTERNET" /> - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> - <uses-permission android:name="android.permission.BIND_INCALL_SERVICE" /> - <uses-permission android:name="android.permission.CALL_PHONE" /> - <uses-permission android:name="android.permission.CALL_PRIVILEGED" /> - <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" /> - <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" /> - <uses-permission android:name="android.permission.LOCATION_HARDWARE" /> - <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> - <uses-permission android:name="android.permission.RECEIVE_SMS" /> - <uses-permission android:name="android.permission.SEND_SMS" /> - <uses-permission android:name="android.permission.READ_SMS" /> - <uses-permission android:name="android.permission.WRITE_SMS" /> - <uses-permission android:name="android.permission.RECEIVE_MMS" /> - <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH" /> - <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" /> - <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" /> - <uses-permission android:name="android.permission.VIBRATE" /> - <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> - <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> - <uses-permission android:name="android.permission.READ_PHONE_STATE" /> - <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> - <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" /> - <uses-permission android:name="android.permission.RESTART_PACKAGES" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.RECORD_AUDIO" /> - <uses-permission android:name="android.permission.READ_LOGS" /> - <uses-permission android:name="android.permission.REAL_GET_TASKS" /> - <uses-permission android:name="android.permission.WRITE_SETTINGS" /> - <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" /> - <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> - <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> - <uses-permission android:name="android.permission.BLUETOOTH_MAP" /> - <uses-permission android:name="android.permission.BLUETOOTH_STACK" /> - <uses-permission android:name="android.permission.NET_ADMIN" /> - <uses-permission android:name="android.permission.CAMERA" /> - <uses-permission android:name="android.permission.WAKE_LOCK" /> - <uses-permission android:name="android.permission.READ_CONTACTS" /> - <uses-permission android:name="android.permission.DEVICE_POWER" /> - <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> - <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> - <uses-permission android:name="android.permission.NFC" /> - <uses-permission android:name="android.permission.HARDWARE_TEST" /> - <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> - <uses-permission android:name="android.permission.MASTER_CLEAR" /> - <uses-permission android:name="android.permission.USE_CREDENTIALS" /> - <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" /> - <uses-permission android:name="android.permission.WRITE_CONTACTS" /> - <uses-permission android:name="android.permission.ACCESS_WIMAX_STATE" /> - <uses-permission android:name="android.permission.CHANGE_WIMAX_STATE" /> - <uses-permission android:name="com.android.certinstaller.INSTALL_AS_USER" /> - <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" /> - <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> - <uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" /> - <uses-permission android:name="android.permission.READ_USER_DICTIONARY" /> - <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" /> - <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" /> - <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> - <uses-permission android:name="android.permission.BATTERY_STATS" /> - <uses-permission android:name="android.permission.MOVE_PACKAGE" /> - <uses-permission android:name="android.permission.BACKUP" /> - <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" /> - <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" /> - <uses-permission android:name="android.permission.READ_SYNC_STATS" /> - <uses-permission android:name="android.permission.STATUS_BAR" /> - <uses-permission android:name="android.permission.MANAGE_USB" /> - <uses-permission android:name="android.permission.SET_POINTER_SPEED" /> - <uses-permission android:name="android.permission.SET_KEYBOARD_LAYOUT" /> - <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> - <uses-permission android:name="android.permission.COPY_PROTECTED_DATA" /> - <uses-permission android:name="android.permission.MANAGE_USERS" /> - <uses-permission android:name="android.permission.READ_PROFILE" /> - <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" /> - <uses-permission android:name="android.permission.SET_TIME" /> - <uses-permission android:name="android.permission.SET_TIME_ZONE" /> - <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" /> - <uses-permission android:name="android.permission.REBOOT" /> - <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" /> - <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> - <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" /> - <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> - <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" /> - <uses-permission android:name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/> - <application android:icon="@drawable/sl4a_logo_48" android:label="@string/application_title" android:name=".Sl4aApplication" - android:theme="@android:style/Theme.DeviceDefault"> - <activity android:name=".activity.ScriptManager" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="adjustResize" android:launchMode="singleTop"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.SEARCH" /> - </intent-filter> - <meta-data android:name="android.app.searchable" android:resource="@xml/searchable_scripts" /> - </activity> - <activity android:name=".activity.ScriptPicker" android:configChanges="keyboardHidden|orientation" android:label="Scripts"> - <intent-filter> - <action android:name="android.intent.action.CREATE_SHORTCUT" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - <intent-filter> - <action android:name="android.intent.action.PICK" /> - <data android:scheme="content" android:path="sl4a/scripts" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity android:name=".activity.InterpreterPicker" android:configChanges="keyboardHidden|orientation" android:label="Interpreters"> - <intent-filter> - <action android:name="android.intent.action.CREATE_SHORTCUT" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity-alias android:name="LocalePlugin" android:targetActivity=".activity.ScriptPicker" android:label="@string/application_title" android:icon="@drawable/sl4a_logo_32"> - <intent-filter> - <action android:name="com.twofortyfouram.locale.intent.action.EDIT_SETTING" /> - </intent-filter> - </activity-alias> - <receiver android:name=".locale.LocaleReceiver"> - <intent-filter> - <action android:name="com.twofortyfouram.locale.intent.action.FIRE_SETTING" /> - </intent-filter> - </receiver> - <activity android:name=".activity.Preferences" android:theme="@android:style/Theme.DeviceDefault.Settings" /> - <activity android:name="org.connectbot.ConsoleActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysVisible|adjustResize" android:finishOnTaskLaunch="true" android:launchMode="singleTask" /> - <activity android:name=".activity.ScriptEditor" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" android:windowSoftInputMode="stateAlwaysVisible|adjustResize"> - <intent-filter> - <action android:name="com.googlecode.android_scripting.action.EDIT_SCRIPT" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity android:name=".activity.ApiBrowser" android:configChanges="keyboardHidden|orientation" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize"> - <intent-filter> - <action android:name="android.intent.action.SEARCH" /> - </intent-filter> - <meta-data android:name="android.app.searchable" android:resource="@xml/searchable_apis" /> - </activity> - <activity android:name=".activity.ApiPrompt" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:configChanges="keyboardHidden|orientation" /> - <activity android:name=".activity.TriggerManager" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" /> - <activity android:name=".activity.BluetoothDeviceList" android:configChanges="keyboardHidden|orientation" /> - <activity android:name=".activity.ScriptingLayerServiceLauncher" android:taskAffinity="" android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor"> - <intent-filter> - <action android:name="android.intent.action.VIEW" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <activity android:name=".activity.FutureActivity" android:configChanges="keyboardHidden|orientation" android:theme="@android:style/Theme.DeviceDefault.NoActionBar.TranslucentDecor" /> - <activity android:name="org.connectbot.HelpActivity" android:configChanges="keyboardHidden|orientation" /> - <activity android:name="org.connectbot.HelpTopicActivity" android:configChanges="keyboardHidden|orientation" /> - <service android:name=".activity.ScriptingLayerService" /> - <service android:name=".activity.TriggerService" /> - <service android:name="com.googlecode.android_scripting.facade.telephony.InCallServiceImpl" - android:permission="android.permission.BIND_INCALL_SERVICE" > - <intent-filter> - <action android:name="android.telecom.InCallService"/> - </intent-filter> - </service> - <service android:name=".service.FacadeService" android:enabled="true" android:exported="true" > - <intent-filter> - <action android:name="com.googlecode.android_scripting.service.FacadeService.ACTION_BIND" /> - </intent-filter> - </service> - <activity android:name=".activity.InterpreterManager" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" /> - <activity android:name=".activity.LogcatViewer" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation" /> - <activity android:name=".activity.ScriptsLiveFolder" android:label="Scripts" android:icon="@drawable/live_folder" android:configChanges="keyboardHidden|orientation"> - <intent-filter> - <action android:name="android.intent.action.CREATE_LIVE_FOLDER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <provider android:name=".provider.ScriptProvider" android:authorities="com.googlecode.android_scripting.provider.scriptprovider" /> - <provider android:name=".provider.ApiProvider" android:authorities="com.googlecode.android_scripting.provider.apiprovider" /> - <provider - android:name="android.support.v4.content.FileProvider" - android:authorities="com.googlecode.android_scripting.provider.telephonytestprovider" - android:grantUriPermissions="true" - android:exported="false"> - <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/paths" /> - </provider> - <uses-library android:name="android.test.runner" /> - <activity android:name=".activity.ScriptProcessMonitor" android:launchMode="singleTask" android:finishOnTaskLaunch="true" /> - <activity android:configChanges="keyboardHidden|orientation" android:name="org.connectbot.util.ColorsActivity" android:theme="@android:style/Theme.DeviceDefault.Dialog"> - <intent-filter> - <action android:name="com.googlecode.android_scripting.PICK_TERMINAL_COLORS" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - </application> -</manifest> diff --git a/sl4a/ScriptingLayerForAndroid/jni/Android.mk b/sl4a/ScriptingLayerForAndroid/jni/Android.mk deleted file mode 100644 index 541aafb..0000000 --- a/sl4a/ScriptingLayerForAndroid/jni/Android.mk +++ /dev/null @@ -1,37 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := com_googlecode_android_scripting_Exec.cpp - -LOCAL_CFLAGS += -Wno-unused-parameter - -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ - -LOCAL_SHARED_LIBRARIES := \ - libandroid_runtime \ - libnativehelper \ - libcutils \ - libutils \ - liblog - -LOCAL_MODULE := libcom_googlecode_android_scripting_Exec - -include $(BUILD_SHARED_LIBRARY) diff --git a/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.cpp b/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.cpp deleted file mode 100644 index 495f27a..0000000 --- a/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// -// Copyright (C) 2016 Google, Inc. -// -// 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. -// - -#include "com_googlecode_android_scripting_Exec.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <termios.h> -#include <unistd.h> -#include <stdio.h> -#include <string.h> - -#include "android/log.h" - -#define LOG_TAG "Exec" -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) - -int CreateSubprocess(const char* cmd, char* args[], char* vars[], char *wkdir, pid_t* pid) { - char* devname; - int ptm = open("/dev/ptmx", O_RDWR); - if(ptm < 0){ - LOGE("Cannot open /dev/ptmx: %s\n", strerror(errno)); - return -1; - } - fcntl(ptm, F_SETFD, FD_CLOEXEC); - - if (grantpt(ptm) || unlockpt(ptm) || - ((devname = (char*) ptsname(ptm)) == 0)) { - LOGE("Trouble with /dev/ptmx: %s\n", strerror(errno)); - return -1; - } - - *pid = fork(); - if(*pid < 0) { - LOGE("Fork failed: %s\n", strerror(errno)); - return -1; - } - - if(*pid == 0){ - int pts; - setsid(); - pts = open(devname, O_RDWR); - if(pts < 0) { - exit(-1); - } - dup2(pts, 0); - dup2(pts, 1); - dup2(pts, 2); - close(ptm); - if (wkdir) chdir(wkdir); - execve(cmd, args, vars); - exit(-1); - } else { - return ptm; - } -} - -void JNU_ThrowByName(JNIEnv* env, const char* name, const char* msg) { - jclass clazz = env->FindClass(name); - if (clazz != NULL) { - env->ThrowNew(clazz, msg); - } - env->DeleteLocalRef(clazz); -} - -char* JNU_GetStringNativeChars(JNIEnv* env, jstring jstr) { - if (jstr == NULL) { - return NULL; - } - jbyteArray bytes = 0; - jthrowable exc; - char* result = 0; - if (env->EnsureLocalCapacity(2) < 0) { - return 0; /* out of memory error */ - } - jclass Class_java_lang_String = env->FindClass("java/lang/String"); - jmethodID MID_String_getBytes = env->GetMethodID( - Class_java_lang_String, "getBytes", "()[B"); - bytes = (jbyteArray) env->CallObjectMethod(jstr, MID_String_getBytes); - exc = env->ExceptionOccurred(); - if (!exc) { - jint len = env->GetArrayLength(bytes); - result = (char*) malloc(len + 1); - if (result == 0) { - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0); - env->DeleteLocalRef(bytes); - return 0; - } - env->GetByteArrayRegion(bytes, 0, len, (jbyte*) result); - result[len] = 0; /* NULL-terminate */ - } else { - env->DeleteLocalRef(exc); - } - env->DeleteLocalRef(bytes); - return result; -} - -int JNU_GetFdFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) { - jclass Class_java_io_FileDescriptor = env->FindClass("java/io/FileDescriptor"); - jfieldID descriptor = env->GetFieldID(Class_java_io_FileDescriptor, "descriptor", "I"); - return env->GetIntField(fileDescriptor, descriptor); -} - -JNIEXPORT jobject JNICALL Java_com_googlecode_android_1scripting_Exec_createSubprocess( - JNIEnv* env, jclass clazz, jstring cmd, jobjectArray argArray, jobjectArray varArray, - jstring workingDirectory, - jintArray processIdArray) { - char* cmd_native = JNU_GetStringNativeChars(env, cmd); - char* wkdir_native = JNU_GetStringNativeChars(env, workingDirectory); - pid_t pid; - jsize len = 0; - if (argArray) { - len = env->GetArrayLength(argArray); - } - char* args[len + 2]; - args[0] = cmd_native; - for (int i = 0; i < len; i++) { - jstring arg = (jstring) env->GetObjectArrayElement(argArray, i); - char* arg_native = JNU_GetStringNativeChars(env, arg); - args[i + 1] = arg_native; - } - args[len + 1] = NULL; - - len = 0; - if (varArray) { - len = env->GetArrayLength(varArray); - } - char* vars[len + 1]; - for (int i = 0; i < len; i++) { - jstring var = (jstring) env->GetObjectArrayElement(varArray, i); - char* var_native = JNU_GetStringNativeChars(env, var); - vars[i] = var_native; - } - vars[len] = NULL; - - int ptm = CreateSubprocess(cmd_native, args, vars, wkdir_native, &pid); - if (processIdArray) { - if (env->GetArrayLength(processIdArray) > 0) { - jboolean isCopy; - int* proccessId = (int*) env->GetPrimitiveArrayCritical(processIdArray, &isCopy); - if (proccessId) { - *proccessId = (int) pid; - env->ReleasePrimitiveArrayCritical(processIdArray, proccessId, 0); - } - } - } - - jclass Class_java_io_FileDescriptor = - env->FindClass("java/io/FileDescriptor"); - jmethodID init = env->GetMethodID(Class_java_io_FileDescriptor, "<init>", "()V"); - jobject result = env->NewObject(Class_java_io_FileDescriptor, init); - - if (!result) { - LOGE("Couldn't create a FileDescriptor."); - } else { - jfieldID descriptor = env->GetFieldID(Class_java_io_FileDescriptor, "descriptor", "I"); - env->SetIntField(result, descriptor, ptm); - } - return result; -} - -JNIEXPORT void JNICALL Java_com_googlecode_android_1scripting_Exec_setPtyWindowSize( - JNIEnv* env, jclass clazz, jobject fileDescriptor, jint row, jint col, jint xpixel, - jint ypixel) { - struct winsize sz; - int fd = JNU_GetFdFromFileDescriptor(env, fileDescriptor); - if (env->ExceptionOccurred() != NULL) { - return; - } - sz.ws_row = row; - sz.ws_col = col; - sz.ws_xpixel = xpixel; - sz.ws_ypixel = ypixel; - ioctl(fd, TIOCSWINSZ, &sz); -} - -JNIEXPORT jint JNICALL Java_com_googlecode_android_1scripting_Exec_waitFor(JNIEnv* env, jclass clazz, jint procId) { - int status; - waitpid(procId, &status, 0); - int result = 0; - if (WIFEXITED(status)) { - result = WEXITSTATUS(status); - } - return result; -} diff --git a/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.h b/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.h deleted file mode 100644 index 6f6d422..0000000 --- a/sl4a/ScriptingLayerForAndroid/jni/com_googlecode_android_scripting_Exec.h +++ /dev/null @@ -1,37 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include <jni.h> -/* Header for class com_googlecode_android_scripting_Exec */ - -#ifndef _Included_com_googlecode_android_scripting_Exec -#define _Included_com_googlecode_android_scripting_Exec -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: com_googlecode_android_scripting_Exec - * Method: createSubprocess - * Signature: (Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;[I)Ljava/io/FileDescriptor; - */ -JNIEXPORT jobject JNICALL Java_com_googlecode_android_1scripting_Exec_createSubprocess - (JNIEnv *, jclass, jstring, jobjectArray, jobjectArray, jstring, jintArray); - -/* - * Class: com_googlecode_android_scripting_Exec - * Method: setPtyWindowSize - * Signature: (Ljava/io/FileDescriptor;IIII)V - */ -JNIEXPORT void JNICALL Java_com_googlecode_android_1scripting_Exec_setPtyWindowSize - (JNIEnv *, jclass, jobject, jint, jint, jint, jint); - -/* - * Class: com_googlecode_android_scripting_Exec - * Method: waitFor - * Signature: (I)I - */ -JNIEXPORT jint JNICALL Java_com_googlecode_android_1scripting_Exec_waitFor - (JNIEnv *, jclass, jint); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/sl4a/ScriptingLayerForAndroid/libs/locale_platform.jar b/sl4a/ScriptingLayerForAndroid/libs/locale_platform.jar Binary files differdeleted file mode 100644 index 4697825..0000000 --- a/sl4a/ScriptingLayerForAndroid/libs/locale_platform.jar +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/proguard.flags b/sl4a/ScriptingLayerForAndroid/proguard.flags deleted file mode 100644 index 93a2728..0000000 --- a/sl4a/ScriptingLayerForAndroid/proguard.flags +++ /dev/null @@ -1,5 +0,0 @@ - --libraryjars libs - --keep class net.londatiga.android.**{*;} - diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/fade_out_delayed.xml b/sl4a/ScriptingLayerForAndroid/res/anim/fade_out_delayed.xml deleted file mode 100644 index 20ca839..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/fade_out_delayed.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:duration="500" - android:startOffset="1000" - android:fillAfter="true" - /> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/fade_stay_hidden.xml b/sl4a/ScriptingLayerForAndroid/res/anim/fade_stay_hidden.xml deleted file mode 100644 index e62ca8b..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/fade_stay_hidden.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:fromAlpha="0.0" - android:toAlpha="0.0" - android:duration="500" - android:fillAfter="true" - /> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_in.xml b/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_in.xml deleted file mode 100644 index edd5b94..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_in.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/accelerate_interpolator" - android:fromAlpha="0.0" - android:toAlpha="1.0" - android:duration="100" /> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_out.xml b/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_out.xml deleted file mode 100644 index 1f37d32..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/keyboard_fade_out.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<alpha xmlns:android="http://schemas.android.com/apk/res/android" - android:interpolator="@android:anim/accelerate_interpolator" - android:fromAlpha="1.0" - android:toAlpha="0.0" - android:duration="100" /> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_in.xml b/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_in.xml deleted file mode 100644 index 29a0048..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_in.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android"> - <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/> - <!-- <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> --> -</set> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_out.xml b/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_out.xml deleted file mode 100644 index 9c46442..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/slide_left_out.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android"> - <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="300"/> - <!-- <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> --> -</set> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_in.xml b/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_in.xml deleted file mode 100644 index 0d52c9f..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_in.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android"> - <translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="300"/> - <!-- <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> --> -</set> diff --git a/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_out.xml b/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_out.xml deleted file mode 100644 index ace4e9d..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/anim/slide_right_out.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<set xmlns:android="http://schemas.android.com/apk/res/android"> - <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="300"/> - <!-- <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" /> --> -</set> diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small.png b/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small.png Binary files differdeleted file mode 100644 index 535e295..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small_notice.txt b/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small_notice.txt deleted file mode 100644 index afa8539..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/atari_small_notice.txt +++ /dev/null @@ -1,11 +0,0 @@ -COMMENT Copyright (c) 1999, Thomas A. Fine -COMMENT -COMMENT License to copy, modify, and distribute for both commercial and -COMMENT non-commercial use is herby granted, provided this notice -COMMENT is preserved. -COMMENT -COMMENT Email to my last name at head.cfa.harvard.edu -COMMENT http://hea-www.harvard.edu/~fine/ -COMMENT -COMMENT Produced with bdfedit, a tcl/tk font editing program -COMMENT written by Thomas A. Fine
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/background.png b/sl4a/ScriptingLayerForAndroid/res/drawable/background.png Binary files differdeleted file mode 100644 index d0fc14f..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/background.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/bsh_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/bsh_icon.png Binary files differdeleted file mode 100644 index 1d73eb5..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/bsh_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/file_bg.png b/sl4a/ScriptingLayerForAndroid/res/drawable/file_bg.png Binary files differdeleted file mode 100644 index 949613c..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/file_bg.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/folder.png b/sl4a/ScriptingLayerForAndroid/res/drawable/folder.png Binary files differdeleted file mode 100644 index 6333914..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/folder.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/html_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/html_icon.png Binary files differdeleted file mode 100644 index c86bee0..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/html_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_dialog_time.png b/sl4a/ScriptingLayerForAndroid/res/drawable/ic_dialog_time.png Binary files differdeleted file mode 100644 index 3ce2751..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_dialog_time.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_close_clear_cancel.png b/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_close_clear_cancel.png Binary files differdeleted file mode 100644 index 619858c..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_close_clear_cancel.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_refresh.png b/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_refresh.png Binary files differdeleted file mode 100644 index 77d70dd..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_refresh.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_search.png b/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_search.png Binary files differdeleted file mode 100644 index 94446db..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/ic_menu_search.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/js_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/js_icon.png Binary files differdeleted file mode 100644 index 86d2504..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/js_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/keyboard_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/keyboard_icon.png Binary files differdeleted file mode 100644 index 9205d8b..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/keyboard_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/live_folder.png b/sl4a/ScriptingLayerForAndroid/res/drawable/live_folder.png Binary files differdeleted file mode 100644 index 3dac86a..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/live_folder.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/lua_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/lua_icon.png Binary files differdeleted file mode 100644 index 0a7a2f3..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/lua_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/nut_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/nut_icon.png Binary files differdeleted file mode 100644 index 06ef267..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/nut_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/pl_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/pl_icon.png Binary files differdeleted file mode 100644 index 7265f46..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/pl_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/py_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/py_icon.png Binary files differdeleted file mode 100644 index 0dcbc64..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/py_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/rb_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/rb_icon.png Binary files differdeleted file mode 100644 index 8c33c29..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/rb_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/script_logo_48.png b/sl4a/ScriptingLayerForAndroid/res/drawable/script_logo_48.png Binary files differdeleted file mode 100644 index 488ed82..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/script_logo_48.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sh_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sh_icon.png Binary files differdeleted file mode 100644 index 6469c34..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sh_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_32.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_32.png Binary files differdeleted file mode 100644 index 8fb9e6d..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_32.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48.png Binary files differdeleted file mode 100644 index 488ed82..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_10.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_10.png Binary files differdeleted file mode 100644 index feac584..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_10.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_2.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_2.png Binary files differdeleted file mode 100644 index 400d3b4..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_2.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_3.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_3.png Binary files differdeleted file mode 100644 index f666771..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_3.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_4.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_4.png Binary files differdeleted file mode 100644 index 9021173..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_4.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_5.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_5.png Binary files differdeleted file mode 100644 index c40a9ae..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_5.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_6.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_6.png Binary files differdeleted file mode 100644 index a428da4..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_6.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_7.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_7.png Binary files differdeleted file mode 100644 index b515c3a..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_7.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_8.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_8.png Binary files differdeleted file mode 100644 index 6474542..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_8.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_9.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_9.png Binary files differdeleted file mode 100644 index 6c6ffd5..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_logo_48_9.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_notification_logo.xml b/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_notification_logo.xml deleted file mode 100644 index cea5465..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl4a_notification_logo.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<level-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:maxLevel="1" android:drawable="@drawable/sl4a_logo_48" /> - <item android:maxLevel="2" android:drawable="@drawable/sl4a_logo_48_2" /> - <item android:maxLevel="3" android:drawable="@drawable/sl4a_logo_48_3" /> - <item android:maxLevel="4" android:drawable="@drawable/sl4a_logo_48_4" /> - <item android:maxLevel="5" android:drawable="@drawable/sl4a_logo_48_5" /> - <item android:maxLevel="6" android:drawable="@drawable/sl4a_logo_48_6" /> - <item android:maxLevel="7" android:drawable="@drawable/sl4a_logo_48_7" /> - <item android:maxLevel="8" android:drawable="@drawable/sl4a_logo_48_8" /> - <item android:maxLevel="9" android:drawable="@drawable/sl4a_logo_48_9" /> - <item android:maxLevel="2147483647" android:drawable="@drawable/sl4a_logo_48_10" /> -</level-list> diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/sl_icon.png b/sl4a/ScriptingLayerForAndroid/res/drawable/sl_icon.png Binary files differdeleted file mode 100644 index a85ef87..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/sl_icon.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/stat_sys_warning.png b/sl4a/ScriptingLayerForAndroid/res/drawable/stat_sys_warning.png Binary files differdeleted file mode 100644 index be00f47..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/stat_sys_warning.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/terminal.png b/sl4a/ScriptingLayerForAndroid/res/drawable/terminal.png Binary files differdeleted file mode 100644 index 9e25569..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/terminal.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_btn.xml b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_btn.xml deleted file mode 100644 index a0a566b..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_btn.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - 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. ---> -<selector - xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="false" - android:drawable="@drawable/timepicker_down_normal" /> - <item - android:state_pressed="true" - android:state_enabled="true" - android:drawable="@drawable/timepicker_down_pressed" /> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="true" - android:drawable="@drawable/timepicker_down_selected" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="false" - android:drawable="@drawable/timepicker_down_disabled" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="true" - android:drawable="@drawable/timepicker_down_disabled_focused" /> -</selector>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled.png Binary files differdeleted file mode 100644 index af72d22..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled_focused.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled_focused.png Binary files differdeleted file mode 100644 index 2d80424..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_disabled_focused.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_normal.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_normal.png Binary files differdeleted file mode 100644 index c427fc3..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_normal.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_pressed.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_pressed.png Binary files differdeleted file mode 100644 index ac6ac53..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_pressed.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_selected.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_selected.png Binary files differdeleted file mode 100644 index f710b57..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_down_selected.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input.xml b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input.xml deleted file mode 100644 index df73ab2..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - 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. ---> -<selector - xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="false" - android:drawable="@drawable/timepicker_input_normal" /> - <item - android:state_pressed="true" - android:state_enabled="true" - android:drawable="@drawable/timepicker_input_pressed" /> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="true" - android:drawable="@drawable/timepicker_input_selected" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="false" - android:drawable="@drawable/timepicker_input_disabled" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="true" - android:drawable="@drawable/timepicker_input_normal" /> -</selector>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_disabled.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_disabled.png Binary files differdeleted file mode 100644 index 97da87a..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_disabled.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_normal.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_normal.png Binary files differdeleted file mode 100644 index eb101c5..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_normal.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_pressed.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_pressed.png Binary files differdeleted file mode 100644 index c83b1eb..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_pressed.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_selected.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_selected.png Binary files differdeleted file mode 100644 index e152848..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_input_selected.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_btn.xml b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_btn.xml deleted file mode 100644 index 5be8d82..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_btn.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - 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. ---> -<selector - xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="false" - android:drawable="@drawable/timepicker_up_normal" /> - <item - android:state_pressed="true" - android:state_enabled="true" - android:drawable="@drawable/timepicker_up_pressed" /> - <item - android:state_pressed="false" - android:state_enabled="true" - android:state_focused="true" - android:drawable="@drawable/timepicker_up_selected" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="false" - android:drawable="@drawable/timepicker_up_disabled" /> - <item - android:state_pressed="false" - android:state_enabled="false" - android:state_focused="true" - android:drawable="@drawable/timepicker_up_disabled_focused" /> -</selector> diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled.png Binary files differdeleted file mode 100644 index 1814bb4..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled_focused.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled_focused.png Binary files differdeleted file mode 100644 index 9ad5b85..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_disabled_focused.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_normal.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_normal.png Binary files differdeleted file mode 100644 index 35fc221..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_normal.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_pressed.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_pressed.png Binary files differdeleted file mode 100644 index c910777..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_pressed.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_selected.png b/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_selected.png Binary files differdeleted file mode 100644 index 549a7e5..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/drawable/timepicker_up_selected.png +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/act_colors.xml b/sl4a/ScriptingLayerForAndroid/res/layout/act_colors.xml deleted file mode 100644 index b40c2f1..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/act_colors.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - - <LinearLayout - android:id="@+id/color_layout" - android:layout_height="wrap_content" - android:layout_width="210dp" - android:layout_centerInParent="true" - android:gravity="center"> - - <GridView - android:id="@+id/color_grid" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:gravity="center" - android:padding="20dp" - android:verticalSpacing="20dp" - android:horizontalSpacing="20dp" - android:columnWidth="160dp" - android:numColumns="1" - android:stretchMode="none"/> - - </LinearLayout> -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/act_console.xml b/sl4a/ScriptingLayerForAndroid/res/layout/act_console.xml deleted file mode 100644 index 8993db3..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/act_console.xml +++ /dev/null @@ -1,93 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:background="#ff000000" - > - - <ViewFlipper - android:id="@+id/console_flip" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - /> - - <RelativeLayout - android:id="@+id/console_boolean_group" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:padding="5dip" - android:background="#80000000" - android:fadingEdge="horizontal" - android:fadingEdgeLength="25dip" - android:visibility="gone" - > - - <TextView - android:id="@+id/console_prompt" - android:layout_height="wrap_content" - android:layout_width="fill_parent" - android:textAppearance="?android:attr/textAppearanceMedium" - /> - - <Button - android:id="@+id/console_prompt_no" - android:text="@string/prompt_no" - android:paddingTop="5dip" - android:paddingBottom="10dip" - android:paddingLeft="40dip" - android:paddingRight="40dip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentRight="true" - android:layout_below="@+id/console_prompt" - android:clickable="false" - /> - - <Button - android:id="@+id/console_prompt_yes" - android:text="@string/prompt_yes" - android:paddingTop="5dip" - android:paddingBottom="10dip" - android:paddingLeft="40dip" - android:paddingRight="40dip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toLeftOf="@+id/console_prompt_no" - android:layout_below="@+id/console_prompt" - /> - - </RelativeLayout> - - <ImageView - android:id="@+id/keyboard_button" - android:paddingRight="15dip" - android:paddingBottom="15dip" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentBottom="true" - android:layout_alignParentRight="true" - android:visibility="gone" - android:src="@+drawable/keyboard_icon" - /> - -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/act_help.xml b/sl4a/ScriptingLayerForAndroid/res/layout/act_help.xml deleted file mode 100644 index 2afe9e4..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/act_help.xml +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<ScrollView - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - > - - <LinearLayout - android:id="@+id/topics" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:gravity="center_horizontal" - > - - <TextView - android:id="@+id/version" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:paddingTop="2dip" - android:textAppearance="?android:attr/textAppearanceSmall" - android:gravity="right" - android:paddingRight="2dip" - /> - - <TextView - android:id="@+id/help_acks_text" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/help_acks" - android:paddingTop="2dip" - android:linksClickable="true" - android:textAppearance="?android:attr/textAppearanceMedium" - android:gravity="center_horizontal" - /> - - <TextView - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/help_intro" - android:paddingTop="2dip" - android:textAppearance="?android:attr/textAppearanceMedium" - android:gravity="center_horizontal" - /> - - </LinearLayout> -</ScrollView> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/act_help_topic.xml b/sl4a/ScriptingLayerForAndroid/res/layout/act_help_topic.xml deleted file mode 100644 index 7123d63..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/act_help_topic.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - > - - <org.connectbot.util.HelpTopicView - android:id="@+id/topic_text" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - /> - -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/api_browser.xml b/sl4a/ScriptingLayerForAndroid/res/layout/api_browser.xml deleted file mode 100644 index 4c4f8a4..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/api_browser.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_apis_message" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt.xml b/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt.xml deleted file mode 100644 index 7a65663..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:padding="2dip"> - <ListView - android:id="@+id/list" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:divider="#00000000" /> - <Button - android:id="@+id/done" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:text="@string/prompt_finish" - android:layout_alignParentBottom="true" /> -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt_item.xml b/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt_item.xml deleted file mode 100644 index a529139..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/api_prompt_item.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <TextView - android:id="@+id/api_prompt_item_description" - android:layout_width="fill_parent" - android:layout_height="wrap_content" /> - <EditText - android:id="@+id/api_prompt_item_value" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/bluetooth_device_list.xml b/sl4a/ScriptingLayerForAndroid/res/layout/bluetooth_device_list.xml deleted file mode 100644 index bec4c53..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/bluetooth_device_list.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_bluetooth_devices_message" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/dia_resize.xml b/sl4a/ScriptingLayerForAndroid/res/layout/dia_resize.xml deleted file mode 100644 index 32253fb..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/dia_resize.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="10dip" - android:paddingRight="10dip" - > - - <EditText - android:id="@+id/width" - android:layout_width="100dip" - android:layout_height="wrap_content" - android:singleLine="true" - android:numeric="integer" - android:text="@string/default_width"/> - - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="10dip" - android:paddingRight="10dip" - android:gravity="right|bottom" - android:textAppearance="?android:attr/textAppearanceLarge" - /> - - - <EditText - android:id="@+id/height" - android:layout_width="100dip" - android:layout_height="wrap_content" - android:singleLine="true" - android:numeric="integer" - android:text="@string/default_height"/> -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/duration_picker.xml b/sl4a/ScriptingLayerForAndroid/res/layout/duration_picker.xml deleted file mode 100644 index 29e524d..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/duration_picker.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (C) 2008 OpenIntents.org - * - * 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. - --> -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="wrap_content" - android:layout_height="wrap_content"> - <com.googlecode.android_scripting.widget.NumberPicker - android:id="@+id/day" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:focusable="true" - android:focusableInTouchMode="true" /> - <TextView - android:text="@string/display_days" - android:gravity="center_horizontal" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_below="@+id/day" - android:layout_alignLeft="@+id/day" /> - <com.googlecode.android_scripting.widget.NumberPicker - android:id="@+id/hour" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_marginLeft="2dip" - android:focusable="true" - android:focusableInTouchMode="true" - android:layout_toRightOf="@+id/day" /> - <TextView - android:text="@string/display_hours" - android:gravity="center_horizontal" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_below="@+id/hour" - android:layout_alignLeft="@+id/hour" /> - <com.googlecode.android_scripting.widget.NumberPicker - android:id="@+id/minute" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_marginLeft="2dip" - android:focusable="true" - android:focusableInTouchMode="true" - android:layout_toRightOf="@+id/hour" /> - <TextView - android:text="@string/display_minutes" - android:gravity="center_horizontal" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_below="@+id/minute" - android:layout_alignLeft="@+id/minute" /> - <com.googlecode.android_scripting.widget.NumberPicker - android:id="@+id/second" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_marginLeft="2dip" - android:focusable="true" - android:focusableInTouchMode="true" - android:layout_toRightOf="@+id/minute" /> - <TextView - android:text="@string/display_seconds" - android:gravity="center_horizontal" - android:layout_width="70dip" - android:layout_height="wrap_content" - android:layout_below="@+id/second" - android:layout_alignLeft="@+id/second" /> -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/findreplace.xml b/sl4a/ScriptingLayerForAndroid/res/layout/findreplace.xml deleted file mode 100644 index 64ec004..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/findreplace.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/display_find"></TextView> - <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/searchFind"> - <requestFocus></requestFocus> - </EditText> - <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/display_replace"></TextView> - <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/searchReplace"></EditText> - <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content"> - </LinearLayout> - <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content"> - </LinearLayout> - <TableLayout android:id="@+id/tableLayout1" android:layout_width="match_parent" android:layout_height="wrap_content"> - <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content"> - <CheckBox android:text="@string/display_whole_words" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/searchWord"></CheckBox> - <CheckBox android:text="@string/display_case_sensitive" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/searchCase"></CheckBox> - </TableRow> - <TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content" android:layout_height="wrap_content"> - <CheckBox android:text="@string/display_replace_all" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/searchAll"></CheckBox> - <CheckBox android:text="@string/display_from_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/searchStart"></CheckBox> - </TableRow> - </TableLayout> - <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textView3" android:typeface="normal" android:text="@string/findreplace_undo_reminder"></TextView> -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/interpreter_manager.xml b/sl4a/ScriptingLayerForAndroid/res/layout/interpreter_manager.xml deleted file mode 100644 index 6b2afb9..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/interpreter_manager.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_interpreters" /> -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/item_terminal.xml b/sl4a/ScriptingLayerForAndroid/res/layout/item_terminal.xml deleted file mode 100644 index 9a8ff19..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/item_terminal.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* - * 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. - */ ---> - -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - > - - <TextView - android:id="@+id/terminal_overlay" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="?android:attr/textAppearanceLarge" - android:background="#aa000000" - android:padding="10dip" - android:layout_centerInParent="true" - /> - -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/list_item.xml b/sl4a/ScriptingLayerForAndroid/res/layout/list_item.xml deleted file mode 100644 index e9f2814..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/list_item.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="horizontal" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:padding="4dip" - android:gravity="center_vertical"> - <ImageView - android:id="@+id/list_item_icon" - android:layout_width="32dip" - android:layout_height="32dip" - android:fadingEdgeLength="0dip" /> - <TextView - android:id="@+id/list_item_title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingLeft="5dip" - android:textSize="22dip" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/logcat_viewer.xml b/sl4a/ScriptingLayerForAndroid/res/layout/logcat_viewer.xml deleted file mode 100644 index 2517432..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/logcat_viewer.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_logcat_msg" /> -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/notification.xml b/sl4a/ScriptingLayerForAndroid/res/layout/notification.xml deleted file mode 100644 index a450fbe..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/notification.xml +++ /dev/null @@ -1,33 +0,0 @@ -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:padding="3dip"> - <RelativeLayout - android:orientation="horizontal" - android:layout_width="fill_parent" - android:layout_height="wrap_content" > - <TextView - android:id="@+id/notification_title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:textColor="#000" - android:textStyle="bold" - android:textSize="12dip" - android:layout_alignParentLeft="true" /> - <TextView - android:id="@+id/notification_action" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColor="#000" - android:textSize="12dip" - android:layout_alignParentRight="true" /> - </RelativeLayout> - <TextView - android:id="@+id/notification_message" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:textColor="#000" - android:textSize="12dip" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/number_picker.xml b/sl4a/ScriptingLayerForAndroid/res/layout/number_picker.xml deleted file mode 100644 index 8b1a433..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/number_picker.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2008, The Android Open Source Project -** -** 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. -*/ ---> -<merge - xmlns:android="http://schemas.android.com/apk/res/android"> - <com.googlecode.android_scripting.widget.NumberPickerButton - android:id="@+id/increment" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:background="@drawable/timepicker_up_btn" /> - <EditText - android:id="@+id/timepicker_input" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:gravity="center" - android:singleLine="true" - style="?android:attr/textAppearanceLargeInverse" - android:textSize="30sp" - android:background="@drawable/timepicker_input" - android:numeric="integer" />
- <com.googlecode.android_scripting.widget.NumberPickerButton - android:id="@+id/decrement" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:background="@drawable/timepicker_down_btn" /> -</merge>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/number_picker_edit.xml b/sl4a/ScriptingLayerForAndroid/res/layout/number_picker_edit.xml deleted file mode 100644 index ebf34da..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/number_picker_edit.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -** -** Copyright 2008, The Android Open Source Project -** -** 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. -*/ ---> -<EditText - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:gravity="center_horizontal" - android:singleLine="true" - style="?android:attr/textAppearanceLargeInverse" - android:textSize="30sp" - android:background="@drawable/timepicker_input" />
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/script_editor.xml b/sl4a/ScriptingLayerForAndroid/res/layout/script_editor.xml deleted file mode 100644 index be9c22e..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/script_editor.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:paddingTop="4dip"> - <EditText - android:id="@+id/script_editor_title" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:hint="Script Name" - android:singleLine="true" /> - <EditText - android:id="@+id/script_editor_body" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:hint="Script Content" - android:typeface="monospace" - android:gravity="top" - android:inputType="textMultiLine" android:scrollHorizontally="true" android:scrollbars="horizontal|vertical"/> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/script_manager.xml b/sl4a/ScriptingLayerForAndroid/res/layout/script_manager.xml deleted file mode 100644 index e8ce08e..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/script_manager.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<RelativeLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_scripts_message" /> -</RelativeLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor.xml b/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor.xml deleted file mode 100644 index 7c57f3b..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_running_scripts_message" /> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor_list_item.xml b/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor_list_item.xml deleted file mode 100644 index df3c339..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/script_monitor_list_item.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="fill_parent" - android:layout_height="fill_parent"> - <RelativeLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content"> - - <TextView - android:id="@+id/process_title" - android:textSize="16sp" - android:textStyle="bold" - android:textColor="#FFF" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - <TextView - android:id="@+id/process_age" - android:layout_alignParentRight="true" - android:gravity="right" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - </RelativeLayout> - <RelativeLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content"> - <TextView - android:id="@+id/process_details" - android:gravity="left" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - <TextView - android:id="@+id/process_status" - android:layout_alignParentRight="true" - android:gravity="right" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> - </RelativeLayout> -</LinearLayout>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/title.xml b/sl4a/ScriptingLayerForAndroid/res/layout/title.xml deleted file mode 100644 index 54df631..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/title.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project - - 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. ---> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen" - android:layout_width="fill_parent" android:layout_height="fill_parent" - android:orientation="vertical"> - <TextView android:id="@+id/left_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="end" - android:maxLines="1" - android:scrollHorizontally="true" - android:layout_centerVertical="true" - android:fadingEdge="horizontal" - android:layout_alignParentLeft="true" - android:textStyle="bold" - android:textColor="#ffffff" - android:shadowColor="#000000" - android:shadowRadius="1" - android:layout_toLeftOf="@+id/right_text"/> - <TextView android:id="@+id/right_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_centerVertical="true" - android:layout_toLeftOf="@+id/progress_bar" - android:layout_alignWithParentIfMissing="true"/> - <ProgressBar android:id="@+id/progress_bar" - android:layout_height="18sp" - android:layout_width="18sp" - android:layout_marginLeft="5sp" - android:visibility="gone" - style="android:attr/ProgressBar_indeterminate" - android:layout_centerVertical="true" - android:layout_alignParentRight="true" - /> -</RelativeLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/layout/trigger_manager.xml b/sl4a/ScriptingLayerForAndroid/res/layout/trigger_manager.xml deleted file mode 100644 index 926da9d..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/layout/trigger_manager.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<LinearLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" android:orientation="vertical"> - <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnTriggerCancel" android:onClick="clickCancel" android:text="@string/cancel_all"></Button><ListView - android:id="@+id/android:list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" /> - <TextView - android:id="@+id/android:empty" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/no_triggers_message" /> - -</LinearLayout> diff --git a/sl4a/ScriptingLayerForAndroid/res/menu/terminal.xml b/sl4a/ScriptingLayerForAndroid/res/menu/terminal.xml deleted file mode 100644 index 136dcaf..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/menu/terminal.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - -<menu - xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:id="@+id/terminal_menu_resize" - android:title="@string/terminal_menu_resize" - android:alphabeticShortcut="s" - android:icon="@android:drawable/ic_menu_crop" /> - <item - android:id="@+id/terminal_menu_send_email" - android:title="Email" - android:alphabeticShortcut="e" - android:icon="@android:drawable/ic_menu_send" /> - <item - android:id="@+id/terminal_menu_preferences" - android:title="Preferences" - android:alphabeticShortcut="p" - android:icon="@android:drawable/ic_menu_preferences" /> - <item - android:id="@+id/terminal_menu_exit_and_edit" - android:title="Exit & Edit" - android:alphabeticShortcut="q" - android:enabled="false" - android:icon="@android:drawable/ic_menu_edit" /> -</menu>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/raw/bell.ogg b/sl4a/ScriptingLayerForAndroid/res/raw/bell.ogg Binary files differdeleted file mode 100644 index 674f25d..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/raw/bell.ogg +++ /dev/null diff --git a/sl4a/ScriptingLayerForAndroid/res/values/arrays.xml b/sl4a/ScriptingLayerForAndroid/res/values/arrays.xml deleted file mode 100644 index a4e3851..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/values/arrays.xml +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - -<resources> - <string-array - name="entries_fontsize_preference"> - <item>4 x 8 pixels</item> - <item>6 pt</item> - <item>7 pt</item> - <item>8 pt</item> - <item>9 pt</item> - <item>10 pt</item> - <item>12 pt</item> - <item>14 pt</item> - <item>16 pt</item> - <item>18 pt</item> - <item>20 pt</item> - <item>22 pt</item> - <item>24 pt</item> - <item>26 pt</item> - <item>28 pt</item> - <item>30 pt</item> - </string-array> - <string-array - name="list_rotation"> - <item>@string/list_rotation_default</item> - <item>@string/list_rotation_land</item> - <item>@string/list_rotation_port</item> - <item>@string/list_rotation_auto</item> - </string-array> - <string-array - name="list_rotation_values"> - <item>Default</item> - <item>Force landscape</item> - <item>Force portrait</item> - <item>Automatic</item> - </string-array> - - <string-array name="list_keymode"> - <item>@string/list_keymode_right</item> - <item>@string/list_keymode_left</item> - <item>@string/list_keymode_none</item> - </string-array> - - <string-array name="list_keymode_values"> - <item>Use right-side keys</item> - <item>Use left-side keys</item> - <item>none</item> - </string-array> - - <string-array name="list_camera"> - <item>@string/list_camera_ctrlaspace</item> - <item>@string/list_camera_ctrla</item> - <item>@string/list_camera_esc</item> - <item>@string/list_camera_esc_a</item> - <item>@string/list_camera_none</item> - </string-array> - - <string-array name="list_camera_values"> - <item>Ctrl+A then Space</item> - <item>Ctrl+A</item> - <item>Esc</item> - <item>Esc+A</item> - <item>None</item> - </string-array> - - <string-array name="list_delkey"> - <item>@string/list_delkey_del</item> - <item>@string/list_delkey_backspace</item> - </string-array> - - <string-array name="list_delkey_values"> - <item>del</item> - <item>backspace</item> - </string-array> - - <string-array - name="entryvalues_fontsize_preference"> - <item>0</item> - <item>6</item> - <item>7</item> - <item>8</item> - <item>9</item> - <item>10</item> - <item>12</item> - <item>14</item> - <item>16</item> - <item>18</item> - <item>20</item> - <item>22</item> - <item>24</item> - <item>26</item> - <item>28</item> - <item>30</item> - </string-array> - <string-array - name="entries_color_preference"> - <item>Black text on white</item> - <item>White text on black</item> - <item>White text on blue</item> - </string-array> - <string-array - name="entryvalues_color_preference"> - <item>0</item> - <item>1</item> - <item>2</item> - </string-array> - <string-array - name="entries_controlkey_preference"> - <item>Jog ball</item> - <item>\@ key</item> - <item>Left Alt key</item> - <item>Right Alt key</item> - </string-array> - <string-array - name="entryvalues_controlkey_preference"> - <item>0</item> - <item>1</item> - <item>2</item> - <item>3</item> - </string-array> -</resources>
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/res/values/strings.xml b/sl4a/ScriptingLayerForAndroid/res/values/strings.xml deleted file mode 100644 index b95427e..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/values/strings.xml +++ /dev/null @@ -1,213 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - -<resources> - <string name="help_force_browser">Force API Browser</string> - <string - name="stop_all">Stop All</string> - <string - name="application_title">SL4A</string> - <string - name="application_nice_title">Scripting Layer for Android</string> - <string - name="text_preferences">Text</string> - <string - name="title_fontsize_preference">Font size</string> - <string - name="summary_fontsize_preference">Choose character height in pixels.</string> - <string - name="dialog_title_fontsize_preference">Font size</string> - <string - name="title_color_preference">Colors</string> - <string - name="summary_color_preference">Choose text color.</string> - <string - name="dialog_title_color_preference">Text color</string> - <string - name="keyboard_preferences">Keyboard</string> - <string - name="title_controlkey_preference">Control key</string> - <string - name="summary_controlkey_preference">Choose control key.</string> - <string - name="dialog_title_controlkey_preference">Control key</string> - <string - name="shell_preferences">Shell</string> - <string - name="title_shell_preference">Command line</string> - <string - name="summary_shell_preference">Specify the shell command line.</string> - <string - name="dialog_title_shell_preference">Shell</string> - <string - name="title_initialcommand_preference">Initial command</string> - <string - name="summary_initialcommand_preference">Sent to the shell when it starts.</string> - <string - name="dialog_title_initialcommand_preference">Initial Command</string> - <string - name="default_value_fontsize_preference">10</string> - <string - name="default_value_color_preference">1</string> - <string - name="default_value_controlkey_preference">0</string> - <string - name="no_scripts_message">Start adding scripts and interpreters by pressing the menu - button.</string> - <string - name="no_apis_message">No matching APIs found.</string> - <string - name="notification_action_message">Tap to open Script Monitor.</string> - <string - name="no_running_scripts_message">There are no currently running scripts.</string> - <string - name="script_number_message">Number of running scripts:\t</string> - <string - name="no_triggers_message">No triggers.</string> - <string - name="no_bluetooth_devices_message">No Bluetooth devices found.</string> - <string - name="search_description_scripts">Search scripts</string> - <string - name="search_description_apis">Search APIs</string> - - <string name="prompt_process_exited">Process has exited.\nClose terminal?</string> - <string name="prompt_confirm_exit">Confirm exit.\nKill process?</string> - - <string name="terminal_copy_done">Copied %1$d bytes to clipboard</string> - <string name="terminal_copy_start">Touch and drag\nor use directional pad\nto select area to copy</string> - - - <string name="terminal_menu_close">Close</string> - <string name="terminal_menu_copy">Copy</string> - <string name="terminal_menu_paste">Paste</string> - <string name="terminal_menu_resize">Force Size</string> - - <string name="button_resize">Resize</string> - - <!-- Name for the scrollback size preference --> - <string name="pref_scrollback_title">Scrollback size</string> - <!-- Description of the scrollback size preference --> - <string name="pref_scrollback_summary">Size of scrollback buffer to keep in memory for each console</string> - <!-- Name for the rotation mode preference --> - <string name="pref_rotation_title">Rotation mode</string> - <!-- Summary for the rotation mode preference --> - <string name="pref_rotation_summary">How to change rotation when keyboard popped in/out</string> - <!-- Name for the full screen preference --> - <string name="pref_fullscreen_title">Full screen</string> - <!-- Summary for the full screen preference --> - <string name="pref_fullscreen_summary">Hide status bar while in console</string> - <!-- Name for the keyboard shortcuts preference --> - <string name="pref_keymode_title">Directory shortcuts</string> - <!-- Summary for the keyboard shortcuts preference --> - <string name="pref_keymode_summary">Select how to use Alt for \'/\' and Shift for Tab</string> - <!-- Name for the camera shortcut usage preference --> - <string name="pref_camera_title">Camera shortcut</string> - <!-- Summary for the camera shortcut usage preference --> - <string name="pref_camera_summary">Select which shortcut to trigger when the camera button is pushed</string> - <!-- Name for the keep screen on preference --> - <string name="pref_keepalive_title">Keep screen awake</string> - <!-- Summary for the camera shortcut usage preference --> - <string name="pref_keepalive_summary">Prevent the screen from turning off when working in a console</string> - <!-- Name for the haptic feedback (bumpy arrow) preference --> - <string name="pref_bumpyarrows_title">Bumpy arrows</string> - <!-- Summary for the haptic feedback (bumpy arrow) preference --> - <string name="pref_bumpyarrows_summary">Vibrate when sending arrow keys from trackball</string> - <string name="pref_hidekeyboard_title">Hide Keyboard</string> - <string name="pref_hidekeyboard_summary">Hide soft keyboard in terminal on startup</string> - <!-- Category title for the Terminal Bell preferences --> - <string name="pref_bell_category">Terminal bell</string> - <!-- Checkbox preference title for the audible terminal bell feature --> - <string name="pref_bell_title">Audible bell</string> - <!-- Title for the slider preference to set the volume --> - <string name="pref_bell_volume_title">Bell volume</string> - <!-- Checkbox preference title for the vibrate on terminal bell feature --> - <string name="pref_bell_vibrate_title">Vibrate on bell</string> - <string name="pref_fontsize_title">Font size (pt)</string> - <!-- Setting for what key code is sent to the server when DEL key is pressed. --> - <string name="pref_delkey_title">DEL Key</string> - <!-- Summary for field asking what key code is sent to the server when DEL key is pressed. --> - <string name="pref_delkey_summary">The key code sent when DEL key is pressed</string> - <!-- Host character encoding preference title --> - <string name="pref_encoding_title">Encoding</string> - <!-- Host character encoding preference summary --> - <string name="pref_encoding_summary">Character encoding for the host</string> - <string name="pref_hide_notifications">Hide Notifications</string> - <!-- Default screen rotation preference selection --> - <string name="list_rotation_default">Default</string> - <string name="list_rotation_land">Force landscape</string> - <string name="list_rotation_port">Force portrait</string> - <!-- Selection to indicate the rotation should be selected automatically based on the tilt sensor. --> - <string name="list_rotation_auto">Automatic</string> - <!-- Preference selection to indicate use of right side of keyboard for special shortcuts. --> - <string name="list_keymode_right">Use right-side keys</string> - <!-- Preference selection to indicate use of left side of keyboard for special shortcuts. --> - <string name="list_keymode_left">Use left-side keys</string> - <!-- Preference selection to indicate never to use special shortcut keys. --> - <string name="list_keymode_none">Disable</string> - <!-- Selection to indicate pressing the Camera button should send "Ctrl+A then Space". --> - <string name="list_camera_ctrlaspace">Ctrl+A then Space</string> - <!-- Selection to indicate pressing the Camera button should send "Ctrl+A". --> - <string name="list_camera_ctrla">Ctrl+A</string> - <!-- Selection to indicate pressing the Camera button should send the "Esc" key. --> - <string name="list_camera_esc">Esc</string> - <!-- Selection to indicate pressing the Camera button should send "Esc+A". --> - <string name="list_camera_esc_a">Esc+A</string> - <!-- Selection to indicate pressing the Camera button should send nothing at all. --> - <string name="list_camera_none">None</string> - <!-- Name for the backspace character --> - <string name="list_delkey_backspace">Backspace</string> - <!-- Name for the ASCII DEL character --> - <string name="list_delkey_del">Delete</string> - - <!-- Window title for Help index --> - <string name="title_help">Help</string> - - <string name="help_acks">SL4A uses <a href="http://code.google.com/p/connectbot/">ConnectBot</a> terminal.</string> - <string name="help_intro">Please select a topic below for more information on a particular subject.</string> - <string name="enable_auto_close">Enable Auto Close</string> - <string name="prompt_no">No</string> - <string name="prompt_yes">Yes</string> - <string name="prompt_finish">Finish</string> - <string name="default_width">80</string> - <string name="default_height">25</string> - <string name="display_days">Days</string> - <string name="display_hours">Hours</string> - <string name="display_minutes">Minutes</string> - <string name="display_seconds">Seconds</string> - <string name="display_find">Find</string> - <string name="display_replace">Replace</string> - <string name="display_whole_words">Whole Words</string> - <string name="display_case_sensitive">Case Sensitive</string> - <string name="display_replace_all">Replace All</string> - <string name="display_from_start">From Start</string> - <string name="findreplace_undo_reminder">Remember you can use the volume keys to undo mistakes.</string> - <string name="no_interpreters">No interpreters.</string> - <string name="no_logcat_msg">No logcat messages.</string> - <string name="cancel_all">Cancel All</string> - - <string name="title_triggers">Triggers</string> - <string name="title_scripts">Scripts</string> - <string name="title_api_browser">API Browser</string> - <string name="title_logcat">Logcat</string> - <string name="title_interpreters">Interpreters</string> - <string name="title_script_monitor">Script Monitor</string> - <string name="title_bluetooth_devices">Bluetooth Devices</string> - -</resources> diff --git a/sl4a/ScriptingLayerForAndroid/res/xml/paths.xml b/sl4a/ScriptingLayerForAndroid/res/xml/paths.xml deleted file mode 100644 index ca3b85a..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/xml/paths.xml +++ /dev/null @@ -1,3 +0,0 @@ -<paths xmlns:android="http://schemas.android.com/apk/res/android"> - <cache-path name="mms" path="." /> -</paths> diff --git a/sl4a/ScriptingLayerForAndroid/res/xml/preferences.xml b/sl4a/ScriptingLayerForAndroid/res/xml/preferences.xml deleted file mode 100644 index e0e6d35..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/xml/preferences.xml +++ /dev/null @@ -1,139 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - -<PreferenceScreen - xmlns:android="http://schemas.android.com/apk/res/android"> - <PreferenceCategory - android:title="General"> - <EditTextPreference android:summary="Port to use for running server. Leave at 0 for random selection." android:key="use_service_port" android:title="Server Port" android:defaultValue="0" android:numeric="integer"></EditTextPreference> - </PreferenceCategory> - <PreferenceCategory - android:title="Script Manager"> - <CheckBoxPreference - android:key="show_all_files" - android:title="Show all files" - android:defaultValue="false" /> - </PreferenceCategory> - <PreferenceCategory - android:title="Script Editor"> - <ListPreference - android:key="editor_fontsize" - android:defaultValue="@string/default_value_fontsize_preference" - android:title="@string/title_fontsize_preference" - android:summary="@string/summary_fontsize_preference" - android:entries="@array/entries_fontsize_preference" - android:entryValues="@array/entryvalues_fontsize_preference" - android:dialogTitle="@string/dialog_title_fontsize_preference" /> - <CheckBoxPreference android:title="@string/help_force_browser" android:key="helpForceBrowser" android:defaultValue="true" android:summary="Force API Help to use default Android Browser"></CheckBoxPreference> - <CheckBoxPreference android:summary="When enabled, quotes and brackets are automatically completed." android:key="enableAutoClose" android:title="@string/enable_auto_close" android:defaultValue="true"></CheckBoxPreference> - <CheckBoxPreference android:title="No Wrap" android:summary="Don't wrap text in editor" android:key="editor_no_wrap"></CheckBoxPreference> - <CheckBoxPreference android:key="editor_auto_indent" android:defaultValue="false" android:summaryOff="Auto Indent Disabled" android:summaryOn="Auto Indent Enabled" android:title="Auto Indent"></CheckBoxPreference> -</PreferenceCategory> - <PreferenceCategory - android:title="Terminal"> - <EditTextPreference - android:key="scrollback" - android:title="@string/pref_scrollback_title" - android:summary="@string/pref_scrollback_summary" - android:defaultValue="140" /> - <EditTextPreference - android:key="fontsize" - android:title="@string/pref_fontsize_title" - android:defaultValue="10" /> - <org.connectbot.util.EncodingPreference - android:key="encoding" - android:title="@string/pref_encoding_title" - android:summary="@string/pref_encoding_summary" /> - <ListPreference - android:key="rotation" - android:title="@string/pref_rotation_title" - android:summary="@string/pref_rotation_summary" - android:entries="@array/list_rotation" - android:entryValues="@array/list_rotation_values" - android:defaultValue="Default" /> - <Preference - android:key="color" - android:title="@string/title_color_preference" - android:summary="@string/summary_color_preference"> - <intent - android:action="com.googlecode.android_scripting.PICK_TERMINAL_COLORS" /> - </Preference> - <CheckBoxPreference - android:key="fullscreen" - android:title="@string/pref_fullscreen_title" - android:summary="@string/pref_fullscreen_summary" - android:defaultValue="false" /> - <ListPreference - android:key="delkey" - android:title="@string/pref_delkey_title" - android:summary="@string/pref_delkey_summary" - android:entries="@array/list_delkey" - android:entryValues="@array/list_delkey_values" /> - <ListPreference - android:key="keymode" - android:title="@string/pref_keymode_title" - android:summary="@string/pref_keymode_summary" - android:entries="@array/list_keymode" - android:entryValues="@array/list_keymode_values" - android:defaultValue="Use right-side keys" /> - <ListPreference - android:key="camera" - android:title="@string/pref_camera_title" - android:summary="@string/pref_camera_summary" - android:entries="@array/list_camera" - android:entryValues="@array/list_camera_values" - android:defaultValue="Ctrl+A then Space" ></ListPreference> - <CheckBoxPreference - android:key="keepalive" - android:title="@string/pref_keepalive_title" - android:summary="@string/pref_keepalive_summary" - android:defaultValue="true" /> - <CheckBoxPreference - android:key="bumpyarrows" - android:title="@string/pref_bumpyarrows_title" - android:summary="@string/pref_bumpyarrows_summary" - android:defaultValue="true" /> - <CheckBoxPreference - android:key="hidekeyboard" - android:title="@string/pref_hidekeyboard_title" - android:summary="@string/pref_hidekeyboard_summary" - android:defaultValue="false" /> - </PreferenceCategory> - <PreferenceCategory - android:title="Terminal bell"> - <CheckBoxPreference - android:key="bell" - android:title="@string/pref_bell_title" - android:defaultValue="true" /> - <org.connectbot.util.VolumePreference - android:key="bellVolume" - android:title="@string/pref_bell_volume_title" /> - <CheckBoxPreference - android:key="bellVibrate" - android:title="@string/pref_bell_vibrate_title" - android:defaultValue="true" /> - </PreferenceCategory> - <PreferenceCategory - android:title="Trigger Behaviour"> - <CheckBoxPreference - android:key="hideServiceNotifications" - android:title="@string/pref_hide_notifications" - android:defaultValue="false" /> - </PreferenceCategory> -</PreferenceScreen> diff --git a/sl4a/ScriptingLayerForAndroid/res/xml/searchable_apis.xml b/sl4a/ScriptingLayerForAndroid/res/xml/searchable_apis.xml deleted file mode 100644 index bab5acc..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/xml/searchable_apis.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - - <searchable xmlns:android="http://schemas.android.com/apk/res/android" - android:label="@string/application_title" - android:hint="@string/search_description_apis" - android:searchSettingsDescription="@string/search_description_apis" - android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" - android:searchSuggestAuthority="com.googlecode.android_scripting.provider.apiprovider" - android:searchSuggestPath="searchSuggestions"> -</searchable> - diff --git a/sl4a/ScriptingLayerForAndroid/res/xml/searchable_scripts.xml b/sl4a/ScriptingLayerForAndroid/res/xml/searchable_scripts.xml deleted file mode 100644 index b0773cc..0000000 --- a/sl4a/ScriptingLayerForAndroid/res/xml/searchable_scripts.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2016, The Android Open Source Project -** -** 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. -*/ ---> - - <searchable xmlns:android="http://schemas.android.com/apk/res/android" - android:label="@string/application_title" - android:hint="@string/search_description_scripts" - android:searchSettingsDescription="@string/search_description_scripts" - android:includeInGlobalSearch="true" - android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" - android:searchSuggestAuthority="com.googlecode.android_scripting.provider.scriptprovider" - android:searchSuggestPath="searchSuggestions" - android:searchSuggestIntentAction="android.intent.action.SEARCH"> -</searchable> - diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ActivityFlinger.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ActivityFlinger.java deleted file mode 100644 index 91216ac..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ActivityFlinger.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; -import android.view.GestureDetector.SimpleOnGestureListener; -import android.view.View.OnTouchListener; - -import com.googlecode.android_scripting.activity.InterpreterManager; -import com.googlecode.android_scripting.activity.LogcatViewer; -import com.googlecode.android_scripting.activity.ScriptManager; -import com.googlecode.android_scripting.activity.TriggerManager; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class ActivityFlinger { - - private static final int SWIPE_MIN_DISTANCE = 120; - private static final int SWIPE_MAX_OFF_PATH = 100; - private static final int SWIPE_THRESHOLD_VELOCITY = 200; - - private static class ActivityTransition { - Class<? extends Activity> mLeft; - Class<? extends Activity> mRight; - - public ActivityTransition(Class<? extends Activity> left, Class<? extends Activity> right) { - mLeft = left; - mRight = right; - } - } - - private static Map<Class<?>, ActivityTransition> mActivityTransitions = - new HashMap<Class<?>, ActivityTransition>(); - - private ActivityFlinger() { - // Utility class. - } - - static { - List<Class<? extends Activity>> entries = new ArrayList<Class<? extends Activity>>(); - entries.add(ScriptManager.class); - entries.add(InterpreterManager.class); - entries.add(TriggerManager.class); - entries.add(LogcatViewer.class); - - Class<? extends Activity> left = null; - Class<? extends Activity> current = null; - Class<? extends Activity> right = null; - - for (Iterator<Class<? extends Activity>> it = entries.iterator(); it.hasNext() - || current != null;) { - if (current == null) { - current = it.next(); - } - if (it.hasNext()) { - right = it.next(); - } else { - right = null; - } - mActivityTransitions.put(current, new ActivityTransition(left, right)); - left = current; - current = right; - } - } - - public static void attachView(View view, Context context) { - final LeftRightFlingListener mListener = new LeftRightFlingListener(); - final GestureDetector mGestureDetector = new GestureDetector(mListener); - ActivityTransition transition = mActivityTransitions.get(context.getClass()); - if (transition.mLeft != null) { - mListener.mLeftRunnable = new StartActivityRunnable(context, transition.mLeft); - } - if (transition.mRight != null) { - mListener.mRightRunnable = new StartActivityRunnable(context, transition.mRight); - } - view.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return mGestureDetector.onTouchEvent(event); - } - }); - } - - private static class StartActivityRunnable implements Runnable { - - private final Context mContext; - private final Class<?> mActivityClass; - - private StartActivityRunnable(Context context, Class<?> activity) { - mContext = context; - mActivityClass = activity; - } - - @Override - public void run() { - Intent intent = new Intent(mContext, mActivityClass); - mContext.startActivity(intent); - } - } - - private static class LeftRightFlingListener extends SimpleOnGestureListener { - Runnable mLeftRunnable; - Runnable mRightRunnable; - - @Override - public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { - if (Math.abs(event1.getY() - event2.getY()) > SWIPE_MAX_OFF_PATH) { - return false; - } - if (event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE - && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { - if (mRightRunnable != null) { - mRightRunnable.run(); - } - } else if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE - && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { - if (mLeftRunnable != null) { - mLeftRunnable.run(); - } - } else { - return super.onFling(event1, event2, velocityX, velocityY); - } - return true; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ScriptListAdapter.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ScriptListAdapter.java deleted file mode 100644 index d1e6f65..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/ScriptListAdapter.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import java.io.File; -import java.util.List; - -public abstract class ScriptListAdapter extends BaseAdapter { - - protected final Context mContext; - protected final LayoutInflater mInflater; - - public ScriptListAdapter(Context context) { - mContext = context; - mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } - - @Override - public int getCount() { - return getScriptList().size(); - } - - @Override - public Object getItem(int position) { - return getScriptList().get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - LinearLayout container; - File script = getScriptList().get(position); - - if (convertView == null) { - container = (LinearLayout) mInflater.inflate(R.layout.list_item, null); - } else { - container = (LinearLayout) convertView; - } - - ImageView icon = (ImageView) container.findViewById(R.id.list_item_icon); - int resourceId; - if (script.isDirectory()) { - resourceId = R.drawable.folder; - } else { - resourceId = FeaturedInterpreters.getInterpreterIcon(mContext, script.getName()); - if (resourceId == 0) { - resourceId = R.drawable.sl4a_logo_32; - } - } - icon.setImageResource(resourceId); - - TextView text = (TextView) container.findViewById(R.id.list_item_title); - text.setText(getScriptList().get(position).getName()); - return container; - } - - protected abstract List<File> getScriptList(); -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/Sl4aApplication.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/Sl4aApplication.java deleted file mode 100644 index 953c6aa..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/Sl4aApplication.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -public class Sl4aApplication extends BaseApplication { - - @Override - public void onCreate() { - super.onCreate(); - } - - @Override - public void onTerminate() { - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiBrowser.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiBrowser.java deleted file mode 100644 index 8255313..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiBrowser.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.app.SearchManager; -import android.content.Intent; -import android.database.MatrixCursor; -import android.os.Bundle; -import android.util.TypedValue; -import android.view.ContextMenu; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ContextMenu.ContextMenuInfo; -import android.widget.AdapterView; -import android.widget.AlphabetIndexer; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.SectionIndexer; -import android.widget.TextView; - -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.language.SupportedLanguages; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.ParameterDescriptor; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcMinSdk; - -import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class ApiBrowser extends ListActivity { - - private boolean searchResultMode = false; - - private static enum RequestCode { - RPC_PROMPT - } - - private static enum MenuId { - EXPAND_ALL, COLLAPSE_ALL, SEARCH; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private static enum ContextMenuId { - INSERT_TEXT, PROMPT_PARAMETERS, HELP; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private List<MethodDescriptor> mMethodDescriptors; - private Set<Integer> mExpandedPositions; - private ApiBrowserAdapter mAdapter; - private boolean mIsLanguageSupported; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "API Browser", R.layout.api_browser); - getListView().setFastScrollEnabled(true); - mExpandedPositions = new HashSet<Integer>(); - updateAndFilterMethodDescriptors(null); - String scriptName = getIntent().getStringExtra(Constants.EXTRA_SCRIPT_PATH); - mIsLanguageSupported = SupportedLanguages.checkLanguageSupported(scriptName); - mAdapter = new ApiBrowserAdapter(); - setListAdapter(mAdapter); - registerForContextMenu(getListView()); - setResult(RESULT_CANCELED); - } - - private void updateAndFilterMethodDescriptors(final String query) { - mMethodDescriptors = - Lists.newArrayList(Collections2.filter(FacadeConfiguration.collectMethodDescriptors(), - new Predicate<MethodDescriptor>() { - @Override - public boolean apply(MethodDescriptor descriptor) { - Method method = descriptor.getMethod(); - if (method.isAnnotationPresent(RpcDeprecated.class)) { - return false; - } else if (method.isAnnotationPresent(RpcMinSdk.class)) { - int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value(); - if (FacadeConfiguration.getSdkLevel() < requiredSdkLevel) { - return false; - } - } - if (query == null) { - return true; - } - return descriptor.getName().toLowerCase().contains(query.toLowerCase()); - } - })); - } - - @Override - protected void onNewIntent(Intent intent) { - if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - searchResultMode = true; - final String query = intent.getStringExtra(SearchManager.QUERY); - ((TextView) findViewById(R.id.left_text)).setText(query); - updateAndFilterMethodDescriptors(query); - if (mMethodDescriptors.size() == 1) { - mExpandedPositions.add(0); - } else { - mExpandedPositions.clear(); - } - mAdapter.notifyDataSetChanged(); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK && searchResultMode) { - searchResultMode = false; - mExpandedPositions.clear(); - ((TextView) findViewById(R.id.left_text)).setText("API Browser"); - updateAndFilterMethodDescriptors(""); - mAdapter.notifyDataSetChanged(); - return true; - } - return super.onKeyDown(keyCode, event); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - menu.clear(); - menu.add(Menu.NONE, MenuId.EXPAND_ALL.getId(), Menu.NONE, "Expand All").setIcon( - android.R.drawable.ic_menu_add); - menu.add(Menu.NONE, MenuId.COLLAPSE_ALL.getId(), Menu.NONE, "Collapse All").setIcon( - android.R.drawable.ic_menu_close_clear_cancel); - menu.add(Menu.NONE, MenuId.SEARCH.getId(), Menu.NONE, "Search").setIcon( - R.drawable.ic_menu_search); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - super.onOptionsItemSelected(item); - int itemId = item.getItemId(); - if (itemId == MenuId.EXPAND_ALL.getId()) { - for (int i = 0; i < mMethodDescriptors.size(); i++) { - mExpandedPositions.add(i); - } - } else if (itemId == MenuId.COLLAPSE_ALL.getId()) { - mExpandedPositions.clear(); - } else if (itemId == MenuId.SEARCH.getId()) { - onSearchRequested(); - } - - mAdapter.notifyDataSetInvalidated(); - return true; - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - if (mExpandedPositions.contains(position)) { - mExpandedPositions.remove(position); - } else { - mExpandedPositions.add(position); - } - mAdapter.notifyDataSetInvalidated(); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { - if (!mIsLanguageSupported) { - return; - } - menu.add(Menu.NONE, ContextMenuId.INSERT_TEXT.getId(), Menu.NONE, "Insert"); - menu.add(Menu.NONE, ContextMenuId.PROMPT_PARAMETERS.getId(), Menu.NONE, "Prompt"); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - } catch (ClassCastException e) { - Log.e("Bad menuInfo", e); - return false; - } - - MethodDescriptor rpc = (MethodDescriptor) getListAdapter().getItem(info.position); - if (rpc == null) { - Log.v("No RPC selected."); - return false; - } - - if (item.getItemId() == ContextMenuId.INSERT_TEXT.getId()) { - // There's no activity to track calls to insert (like there is for prompt) so we track it - // here instead. - insertText(rpc, new String[0]); - } else if (item.getItemId() == ContextMenuId.PROMPT_PARAMETERS.getId()) { - Intent intent = new Intent(this, ApiPrompt.class); - intent.putExtra(Constants.EXTRA_API_PROMPT_RPC_NAME, rpc.getName()); - ParameterDescriptor[] parameters = rpc.getParameterValues(new String[0]); - String[] values = new String[parameters.length]; - int index = 0; - for (ParameterDescriptor parameter : parameters) { - values[index++] = parameter.getValue(); - } - intent.putExtra(Constants.EXTRA_API_PROMPT_VALUES, values); - startActivityForResult(intent, RequestCode.RPC_PROMPT.ordinal()); - } else if (item.getItemId() == ContextMenuId.HELP.getId()) { - String help = rpc.getDeclaringClass().getSimpleName() + ".html#" + rpc.getName(); - - } - return true; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - RequestCode request = RequestCode.values()[requestCode]; - if (resultCode == RESULT_OK) { - switch (request) { - case RPC_PROMPT: - MethodDescriptor rpc = - FacadeConfiguration.getMethodDescriptor(data - .getStringExtra(Constants.EXTRA_API_PROMPT_RPC_NAME)); - String[] values = data.getStringArrayExtra(Constants.EXTRA_API_PROMPT_VALUES); - insertText(rpc, values); - break; - default: - break; - } - } else { - switch (request) { - case RPC_PROMPT: - break; - default: - break; - } - } - } - - private void insertText(MethodDescriptor rpc, String[] values) { - String scriptText = getIntent().getStringExtra(Constants.EXTRA_SCRIPT_TEXT); - InterpreterConfiguration config = - ((BaseApplication) getApplication()).getInterpreterConfiguration(); - - Interpreter interpreter = - config.getInterpreterByName(getIntent().getStringExtra(Constants.EXTRA_INTERPRETER_NAME)); - String rpcHelpText = interpreter.getRpcText(scriptText, rpc, values); - - Intent intent = new Intent(); - intent.putExtra(Constants.EXTRA_RPC_HELP_TEXT, rpcHelpText); - setResult(RESULT_OK, intent); - finish(); - } - - private class ApiBrowserAdapter extends BaseAdapter implements SectionIndexer { - - private final AlphabetIndexer mIndexer; - private final MatrixCursor mCursor; - - public ApiBrowserAdapter() { - mCursor = new MatrixCursor(new String[] { "NAME" }); - for (MethodDescriptor info : mMethodDescriptors) { - mCursor.addRow(new String[] { info.getName() }); - } - mIndexer = new AlphabetIndexer(mCursor, 0, " ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - } - - @Override - public int getCount() { - return mMethodDescriptors.size(); - } - - @Override - public Object getItem(int position) { - return mMethodDescriptors.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - TextView view; - if (convertView == null) { - view = new TextView(ApiBrowser.this); - } else { - view = (TextView) convertView; - } - view.setPadding(4, 4, 4, 4); - view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); - if (mExpandedPositions.contains(position)) { - view.setText(mMethodDescriptors.get(position).getHelp()); - } else { - view.setText(mMethodDescriptors.get(position).getName()); - } - return view; - } - - @Override - public int getPositionForSection(int section) { - return mIndexer.getPositionForSection(section); - } - - @Override - public int getSectionForPosition(int position) { - return mIndexer.getSectionForPosition(position); - } - - @Override - public Object[] getSections() { - return mIndexer.getSections(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiPrompt.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiPrompt.java deleted file mode 100644 index e9655a2..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ApiPrompt.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.View.OnClickListener; -import android.widget.BaseAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.rpc.MethodDescriptor; - -/** - * Prompts for API parameters. - * - * <p> - * This activity is started by {@link ApiBrowser} to prompt user for RPC call parameters. - * Input/output interface is RPC name and explicit parameter values. - * - * @author igor.v.karp@gmail.com (Igor Karp) - */ -public class ApiPrompt extends Activity { - private MethodDescriptor mRpc; - private String[] mHints; - private String[] mValues; - private ApiPromptAdapter mAdapter; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.api_prompt); - mRpc = - FacadeConfiguration.getMethodDescriptor(getIntent().getStringExtra( - Constants.EXTRA_API_PROMPT_RPC_NAME)); - mHints = mRpc.getParameterHints(); - mValues = getIntent().getStringArrayExtra(Constants.EXTRA_API_PROMPT_VALUES); - mAdapter = new ApiPromptAdapter(); - ((ListView) findViewById(R.id.list)).setAdapter(mAdapter); - ((Button) findViewById(R.id.done)).setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(); - intent.putExtra(Constants.EXTRA_API_PROMPT_RPC_NAME, mRpc.getName()); - intent.putExtra(Constants.EXTRA_API_PROMPT_VALUES, mValues); - setResult(RESULT_OK, intent); - finish(); - } - }); - setResult(RESULT_CANCELED); - } - - private class ApiPromptAdapter extends BaseAdapter { - @Override - public int getCount() { - return mHints.length; - } - - @Override - public Object getItem(int position) { - return mValues[position]; - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View item; - if (convertView == null) { - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - item = - inflater.inflate(R.layout.api_prompt_item, parent, false /* do not attach to root */); - } else { - item = convertView; - } - TextView description = (TextView) item.findViewById(R.id.api_prompt_item_description); - EditText value = (EditText) item.findViewById(R.id.api_prompt_item_value); - description.setText(mHints[position]); - value.setText(mValues[position]); - value.addTextChangedListener(new ValueWatcher(position)); - return item; - } - } - - private class ValueWatcher implements TextWatcher { - private final int mPosition; - - public ValueWatcher(int position) { - mPosition = position; - } - - @Override - public void afterTextChanged(Editable e) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - mValues[mPosition] = s.toString(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/BluetoothDeviceList.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/BluetoothDeviceList.java deleted file mode 100644 index 962f69f..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/BluetoothDeviceList.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.content.Intent; -import android.os.Bundle; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.TextView; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothDiscoveryHelper; -import com.googlecode.android_scripting.facade.bluetooth.BluetoothDiscoveryHelper.BluetoothDiscoveryListener; - -import java.util.ArrayList; -import java.util.List; - -public class BluetoothDeviceList extends ListActivity { - - private static class DeviceInfo { - public final String mmName; - public final String mmAddress; - - public DeviceInfo(String name, String address) { - mmName = name; - mmAddress = address; - } - } - - private final DeviceListAdapter mAdapter = new DeviceListAdapter(); - private final BluetoothDiscoveryHelper mBluetoothHelper = - new BluetoothDiscoveryHelper(this, mAdapter); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Bluetooth Devices", R.layout.bluetooth_device_list); - setListAdapter(mAdapter); - } - - @Override - protected void onStart() { - super.onStart(); - CustomizeWindow.toggleProgressBarVisibility(this, true); - mBluetoothHelper.startDiscovery(); - } - - @Override - protected void onStop() { - super.onStop(); - mBluetoothHelper.cancel(); - } - - @Override - protected void onListItemClick(android.widget.ListView l, View v, int position, long id) { - DeviceInfo device = (DeviceInfo) mAdapter.getItem(position); - final Intent result = new Intent(); - result.putExtra(Constants.EXTRA_DEVICE_ADDRESS, device.mmAddress); - setResult(RESULT_OK, result); - finish(); - }; - - private class DeviceListAdapter extends BaseAdapter implements BluetoothDiscoveryListener { - List<DeviceInfo> mmDeviceList; - - public DeviceListAdapter() { - mmDeviceList = new ArrayList<DeviceInfo>(); - } - - @Override - public void addDevice(String name, String address) { - mmDeviceList.add(new DeviceInfo(name, address)); - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return mmDeviceList.size(); - } - - @Override - public Object getItem(int position) { - return mmDeviceList.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup viewGroup) { - final DeviceInfo device = mmDeviceList.get(position); - final TextView view = new TextView(BluetoothDeviceList.this); - view.setPadding(2, 2, 2, 2); - view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); - view.setText(device.mmName + " (" + device.mmAddress + ")"); - return view; - } - - @Override - public void addBondedDevice(String name, String address) { - addDevice(name, address); - } - - @Override - public void scanDone() { - CustomizeWindow.toggleProgressBarVisibility(BluetoothDeviceList.this, false); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/CustomizeWindow.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/CustomizeWindow.java deleted file mode 100644 index 897748f..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/CustomizeWindow.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.view.View; -import android.view.Window; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.Version; - -public class CustomizeWindow { - private CustomizeWindow() { - // Utility class. - } - - public static void requestCustomTitle(Activity activity, String title, int contentViewLayoutResId) { - //b/26218264 - //activity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); - //activity.setContentView(contentViewLayoutResId); - //activity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title); - //((TextView) activity.findViewById(R.id.left_text)).setText(title); - //((TextView) activity.findViewById(R.id.right_text)).setText("SL4A r" - // + Version.getVersion(activity)); - } - - public static void toggleProgressBarVisibility(Activity activity, boolean on) { - ((ProgressBar) activity.findViewById(R.id.progress_bar)).setVisibility(on ? View.VISIBLE - : View.GONE); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterManager.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterManager.java deleted file mode 100644 index 1cd2fc2..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterManager.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.DataSetObserver; -import android.net.Uri; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.SubMenu; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; - -import com.googlecode.android_scripting.ActivityFlinger; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.FeaturedInterpreters; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration.ConfigurationObserver; - -import java.net.URL; -import java.util.ArrayList; -import java.util.List; - -public class InterpreterManager extends ListActivity { - - private InterpreterManagerAdapter mAdapter; - private InterpreterListObserver mObserver; - private List<Interpreter> mInterpreters; - private List<String> mFeaturedInterpreters; - private InterpreterConfiguration mConfiguration; - private SharedPreferences mPreferences; - - private static enum MenuId { - HELP, ADD, NETWORK, PREFERENCES; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Interpreters", R.layout.interpreter_manager); - mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - mInterpreters = new ArrayList<Interpreter>(); - mAdapter = new InterpreterManagerAdapter(); - mObserver = new InterpreterListObserver(); - mAdapter.registerDataSetObserver(mObserver); - setListAdapter(mAdapter); - ActivityFlinger.attachView(getListView(), this); - ActivityFlinger.attachView(getWindow().getDecorView(), this); - mFeaturedInterpreters = FeaturedInterpreters.getList(); - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - } - - @Override - public void onStart() { - super.onStart(); - mConfiguration.registerObserver(mObserver); - mAdapter.notifyDataSetInvalidated(); - } - - @Override - protected void onResume() { - super.onResume(); - mAdapter.notifyDataSetInvalidated(); - } - - @Override - public void onStop() { - super.onStop(); - mConfiguration.unregisterObserver(mObserver); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - menu.clear(); - buildInstallLanguagesMenu(menu); - menu.add(Menu.NONE, MenuId.NETWORK.getId(), Menu.NONE, "Start Server").setIcon( - android.R.drawable.ic_menu_share); - menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( - android.R.drawable.ic_menu_preferences); - return super.onPrepareOptionsMenu(menu); - } - - private void buildInstallLanguagesMenu(Menu menu) { - SubMenu installMenu = - menu.addSubMenu(Menu.NONE, MenuId.ADD.getId(), Menu.NONE, "Add").setIcon( - android.R.drawable.ic_menu_add); - int i = MenuId.values().length + Menu.FIRST; - for (String interpreterName : mFeaturedInterpreters) { - installMenu.add(Menu.NONE, i++, Menu.NONE, interpreterName); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == MenuId.NETWORK.getId()) { - AlertDialog.Builder dialog = new AlertDialog.Builder(this); - dialog.setItems(new CharSequence[] { "Public", "Private" }, new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - launchService(which == 0 /* usePublicIp */); - } - }); - dialog.show(); - } else if (itemId == MenuId.PREFERENCES.getId()) { - startActivity(new Intent(this, Preferences.class)); - } else if (itemId >= MenuId.values().length + Menu.FIRST) { - int i = itemId - MenuId.values().length - Menu.FIRST; - if (i < mFeaturedInterpreters.size()) { - URL url = FeaturedInterpreters.getUrlForName(mFeaturedInterpreters.get(i)); - Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url.toString())); - startActivity(viewIntent); - } - } - return true; - } - - private int getPrefInt(String key, int defaultValue) { - int result = defaultValue; - String value = mPreferences.getString(key, null); - if (value != null) { - try { - result = Integer.parseInt(value); - } catch (NumberFormatException e) { - result = defaultValue; - } - } - return result; - } - - private void launchService(boolean usePublicIp) { - Intent intent = new Intent(this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_LAUNCH_SERVER); - intent.putExtra(Constants.EXTRA_USE_EXTERNAL_IP, usePublicIp); - intent.putExtra(Constants.EXTRA_USE_SERVICE_PORT, getPrefInt("use_service_port", 0)); - startService(intent); - } - - private void launchTerminal(Interpreter interpreter) { - Intent intent = new Intent(this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_LAUNCH_INTERPRETER); - intent.putExtra(Constants.EXTRA_INTERPRETER_NAME, interpreter.getName()); - startService(intent); - } - - @Override - protected void onListItemClick(ListView list, View view, int position, long id) { - Interpreter interpreter = (Interpreter) list.getItemAtPosition(position); - launchTerminal(interpreter); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mConfiguration.unregisterObserver(mObserver); - } - - private class InterpreterListObserver extends DataSetObserver implements ConfigurationObserver { - @Override - public void onInvalidated() { - mInterpreters = mConfiguration.getInteractiveInterpreters(); - } - - @Override - public void onChanged() { - mInterpreters = mConfiguration.getInteractiveInterpreters(); - } - - @Override - public void onConfigurationChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - mAdapter.notifyDataSetChanged(); - } - }); - } - } - - private class InterpreterManagerAdapter extends BaseAdapter { - - @Override - public int getCount() { - return mInterpreters.size(); - } - - @Override - public Object getItem(int position) { - return mInterpreters.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - LinearLayout container; - - Interpreter interpreter = mInterpreters.get(position); - - if (convertView == null) { - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - container = (LinearLayout) inflater.inflate(R.layout.list_item, null); - } else { - container = (LinearLayout) convertView; - } - ImageView img = (ImageView) container.findViewById(R.id.list_item_icon); - - int imgId = - FeaturedInterpreters.getInterpreterIcon(InterpreterManager.this, - interpreter.getExtension()); - if (imgId == 0) { - imgId = R.drawable.sl4a_logo_32; - } - - img.setImageResource(imgId); - - TextView text = (TextView) container.findViewById(R.id.list_item_title); - - text.setText(interpreter.getNiceName()); - return container; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterPicker.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterPicker.java deleted file mode 100644 index 79145d5..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/InterpreterPicker.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.content.Context; -import android.content.Intent; -import android.database.DataSetObserver; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ListView; -import android.widget.TextView; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.FeaturedInterpreters; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration.ConfigurationObserver; - -import java.util.List; - -/** - * Presents available scripts and returns the selected one. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class InterpreterPicker extends ListActivity { - - private List<Interpreter> mInterpreters; - private InterpreterPickerAdapter mAdapter; - private InterpreterConfiguration mConfiguration; - private ScriptListObserver mObserver; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Interpreters", R.layout.script_manager); - mObserver = new ScriptListObserver(); - mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - mInterpreters = mConfiguration.getInteractiveInterpreters(); - mConfiguration.registerObserver(mObserver); - mAdapter = new InterpreterPickerAdapter(); - mAdapter.registerDataSetObserver(mObserver); - setListAdapter(mAdapter); - } - - @Override - protected void onListItemClick(ListView list, View view, int position, long id) { - final Interpreter interpreter = (Interpreter) list.getItemAtPosition(position); - if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { - int icon = - FeaturedInterpreters.getInterpreterIcon(InterpreterPicker.this, interpreter - .getExtension()); - if (icon == 0) { - icon = R.drawable.sl4a_logo_48; - } - Parcelable iconResource = - Intent.ShortcutIconResource.fromContext(InterpreterPicker.this, icon); - Intent intent = IntentBuilders.buildInterpreterShortcutIntent(interpreter, iconResource); - setResult(RESULT_OK, intent); - } - finish(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mConfiguration.unregisterObserver(mObserver); - } - - private class ScriptListObserver extends DataSetObserver implements ConfigurationObserver { - @Override - public void onInvalidated() { - mInterpreters = mConfiguration.getInteractiveInterpreters(); - } - - @Override - public void onConfigurationChanged() { - mAdapter.notifyDataSetInvalidated(); - } - } - - private class InterpreterPickerAdapter extends BaseAdapter { - - @Override - public int getCount() { - return mInterpreters.size(); - } - - @Override - public Object getItem(int position) { - return mInterpreters.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - LinearLayout container; - - Interpreter interpreter = mInterpreters.get(position); - - if (convertView == null) { - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - container = (LinearLayout) inflater.inflate(R.layout.list_item, null); - } else { - container = (LinearLayout) convertView; - } - ImageView img = (ImageView) container.findViewById(R.id.list_item_icon); - - int imgId = - FeaturedInterpreters.getInterpreterIcon(InterpreterPicker.this, interpreter - .getExtension()); - if (imgId == 0) { - imgId = R.drawable.sl4a_logo_32; - } - - img.setImageResource(imgId); - - TextView text = (TextView) container.findViewById(R.id.list_item_title); - - text.setText(interpreter.getNiceName()); - return container; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/LogcatViewer.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/LogcatViewer.java deleted file mode 100644 index 7025c23..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/LogcatViewer.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.text.ClipboardManager; -import android.util.TypedValue; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.TextView; -import android.widget.Toast; - -import com.googlecode.android_scripting.ActivityFlinger; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.Process; -import com.googlecode.android_scripting.R; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.LinkedList; -import java.util.List; - -public class LogcatViewer extends ListActivity { - - private List<String> mLogcatMessages; - private int mOldLastPosition; - private LogcatViewerAdapter mAdapter; - private Process mLogcatProcess; - - private static enum MenuId { - HELP, PREFERENCES, JUMP_TO_BOTTOM, SHARE, COPY; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private class LogcatWatcher implements Runnable { - @Override - public void run() { - mLogcatProcess = new Process(); - mLogcatProcess.setBinary(new File("/system/bin/logcat")); - mLogcatProcess.start(null); - try { - BufferedReader br = new BufferedReader(new InputStreamReader(mLogcatProcess.getIn())); - while (true) { - final String line = br.readLine(); - if (line == null) { - break; - } - runOnUiThread(new Runnable() { - @Override - public void run() { - mLogcatMessages.add(line); - mAdapter.notifyDataSetInvalidated(); - // This logic performs what transcriptMode="normal" should do. Since that doesn't seem - // to work, we do it this way. - int lastVisiblePosition = getListView().getLastVisiblePosition(); - int lastPosition = mLogcatMessages.size() - 1; - if (lastVisiblePosition == mOldLastPosition || lastVisiblePosition == -1) { - getListView().setSelection(lastPosition); - } - mOldLastPosition = lastPosition; - } - }); - } - } catch (IOException e) { - Log.e("Failed to read from logcat process.", e); - } finally { - mLogcatProcess.kill(); - } - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Logcat", R.layout.logcat_viewer); - mLogcatMessages = new LinkedList<String>(); - mOldLastPosition = 0; - mAdapter = new LogcatViewerAdapter(); - setListAdapter(mAdapter); - ActivityFlinger.attachView(getListView(), this); - ActivityFlinger.attachView(getWindow().getDecorView(), this); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( - android.R.drawable.ic_menu_preferences); - menu.add(Menu.NONE, MenuId.JUMP_TO_BOTTOM.getId(), Menu.NONE, "Jump to Bottom").setIcon( - android.R.drawable.ic_menu_revert); - menu.add(Menu.NONE, MenuId.SHARE.getId(), Menu.NONE, "Share").setIcon( - android.R.drawable.ic_menu_share); - menu.add(Menu.NONE, MenuId.COPY.getId(), Menu.NONE, "Copy").setIcon( - android.R.drawable.ic_menu_edit); - return super.onCreateOptionsMenu(menu); - } - - private String getAsString() { - StringBuilder builder = new StringBuilder(); - for (String message : mLogcatMessages) { - builder.append(message + "\n"); - } - return builder.toString(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == MenuId.JUMP_TO_BOTTOM.getId()) { - getListView().setSelection(mLogcatMessages.size() - 1); - } else if (itemId == MenuId.PREFERENCES.getId()) { - startActivity(new Intent(this, Preferences.class)); - } else if (itemId == MenuId.SHARE.getId()) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.putExtra(Intent.EXTRA_TEXT, getAsString().toString()); - intent.putExtra(Intent.EXTRA_SUBJECT, "Logcat Dump"); - intent.setType("text/plain"); - startActivity(Intent.createChooser(intent, "Send Logcat to:")); - } else if (itemId == MenuId.COPY.getId()) { - ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - clipboard.setText(getAsString()); - Toast.makeText(this, "Copied to clipboard", Toast.LENGTH_SHORT).show(); - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onStart() { - mLogcatMessages.clear(); - Thread logcatWatcher = new Thread(new LogcatWatcher()); - logcatWatcher.setPriority(Thread.NORM_PRIORITY - 1); - logcatWatcher.start(); - mAdapter.notifyDataSetInvalidated(); - super.onStart(); - } - - @Override - protected void onPause() { - super.onPause(); - mLogcatProcess.kill(); - } - - private class LogcatViewerAdapter extends BaseAdapter { - - @Override - public int getCount() { - return mLogcatMessages.size(); - } - - @Override - public Object getItem(int position) { - return mLogcatMessages.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - TextView view = new TextView(LogcatViewer.this); - view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); - view.setText(mLogcatMessages.get(position)); - return view; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/Preferences.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/Preferences.java deleted file mode 100644 index 5197d9e..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/Preferences.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.os.Bundle; -import android.preference.PreferenceActivity; - -import com.googlecode.android_scripting.R; - -public class Preferences extends PreferenceActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.preferences); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptEditor.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptEditor.java deleted file mode 100644 index b83720e..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptEditor.java +++ /dev/null @@ -1,621 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.media.AudioManager; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.Editable; -import android.text.InputFilter; -import android.text.InputType; -import android.text.Selection; -import android.text.Spanned; -import android.text.TextWatcher; -import android.text.style.UnderlineSpan; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Toast; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptStorageAdapter; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Vector; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A text editor for scripts. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ScriptEditor extends Activity implements OnClickListener { - private static final int DIALOG_FIND_REPLACE = 2; - private static final int DIALOG_LINE = 1; - private EditText mNameText; - private EditText mContentText; - private boolean mScheduleMoveLeft; - private String mLastSavedContent; - private SharedPreferences mPreferences; - private InterpreterConfiguration mConfiguration; - private ContentTextWatcher mWatcher; - private EditHistory mHistory; - private File mScript; - private EditText mLineNo; - - private boolean mIsUndoOrRedo = false; - private boolean mEnableAutoClose; - private boolean mAutoIndent; - - private EditText mSearchFind; - private EditText mSearchReplace; - private CheckBox mSearchCase; - private CheckBox mSearchWord; - private CheckBox mSearchAll; - private CheckBox mSearchStart; - - private static enum MenuId { - SAVE, SAVE_AND_RUN, PREFERENCES, API_BROWSER, HELP, SHARE, GOTO, SEARCH; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private static enum RequestCode { - RPC_HELP - } - - private int readIntPref(String key, int defaultValue, int maxValue) { - int val; - try { - val = Integer.parseInt(mPreferences.getString(key, Integer.toString(defaultValue))); - } catch (NumberFormatException e) { - val = defaultValue; - } - val = Math.max(0, Math.min(val, maxValue)); - return val; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.script_editor); - mNameText = (EditText) findViewById(R.id.script_editor_title); - mContentText = (EditText) findViewById(R.id.script_editor_body); - mHistory = new EditHistory(); - mWatcher = new ContentTextWatcher(mHistory); - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - updatePreferences(); - - mScript = new File(getIntent().getStringExtra(Constants.EXTRA_SCRIPT_PATH)); - mNameText.setText(mScript.getName()); - mNameText.setSelected(true); - // NOTE: This appears to be the only way to get Android to put the cursor to the beginning of - // the EditText field. - mNameText.setSelection(1); - mNameText.extendSelection(0); - mNameText.setSelection(0); - mLastSavedContent = getIntent().getStringExtra(Constants.EXTRA_SCRIPT_CONTENT); - if (mLastSavedContent == null) { - try { - mLastSavedContent = FileUtils.readToString(mScript); - } catch (IOException e) { - Log.e("Failed to read script.", e); - mLastSavedContent = ""; - } finally { - } - } - - mContentText.setText(mLastSavedContent); - InputFilter[] oldFilters = mContentText.getFilters(); - List<InputFilter> filters = new ArrayList<InputFilter>(oldFilters.length + 1); - filters.addAll(Arrays.asList(oldFilters)); - filters.add(new ContentInputFilter()); - mContentText.setFilters(filters.toArray(oldFilters)); - mContentText.addTextChangedListener(mWatcher); - mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - // Disables volume key beep. - setVolumeControlStream(AudioManager.STREAM_MUSIC); - mLineNo = new EditText(this); - mLineNo.setInputType(InputType.TYPE_CLASS_NUMBER); - int lastLocation = mPreferences.getInt("lasteditpos." + mScript, -1); - if (lastLocation >= 0) { - mContentText.requestFocus(); - mContentText.setSelection(lastLocation); - } - } - - @Override - protected void onResume() { - super.onResume(); - updatePreferences(); - } - - private void updatePreferences() { - mContentText.setTextSize(readIntPref("editor_fontsize", 10, 30)); - mEnableAutoClose = mPreferences.getBoolean("enableAutoClose", true); - mAutoIndent = mPreferences.getBoolean("editor_auto_indent", false); - mContentText.setHorizontallyScrolling(mPreferences.getBoolean("editor_no_wrap", false)); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - menu.add(0, MenuId.SAVE.getId(), 0, "Save & Exit").setIcon(android.R.drawable.ic_menu_save); - menu.add(0, MenuId.SAVE_AND_RUN.getId(), 0, "Save & Run").setIcon( - android.R.drawable.ic_media_play); - menu.add(0, MenuId.PREFERENCES.getId(), 0, "Preferences").setIcon( - android.R.drawable.ic_menu_preferences); - menu.add(0, MenuId.API_BROWSER.getId(), 0, "API Browser").setIcon( - android.R.drawable.ic_menu_info_details); - menu.add(0, MenuId.SHARE.getId(), 0, "Share").setIcon(android.R.drawable.ic_menu_share); - menu.add(0, MenuId.GOTO.getId(), 0, "GoTo").setIcon(android.R.drawable.ic_menu_directions); - menu.add(0, MenuId.SEARCH.getId(), 0, "Find").setIcon(android.R.drawable.ic_menu_search); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == MenuId.SAVE.getId()) { - save(); - finish(); - } else if (item.getItemId() == MenuId.SAVE_AND_RUN.getId()) { - save(); - Interpreter interpreter = - mConfiguration.getInterpreterForScript(mNameText.getText().toString()); - if (interpreter != null) { // We may be editing an unknown type. - Intent intent = new Intent(this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_LAUNCH_FOREGROUND_SCRIPT); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, mScript.getAbsolutePath()); - startService(intent); - } else { - // TODO(damonkohler): Should remove menu option. - Toast.makeText(this, "Can't run this type.", Toast.LENGTH_SHORT).show(); - } - finish(); - } else if (item.getItemId() == MenuId.PREFERENCES.getId()) { - startActivity(new Intent(this, Preferences.class)); - } else if (item.getItemId() == MenuId.API_BROWSER.getId()) { - Intent intent = new Intent(this, ApiBrowser.class); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, mNameText.getText().toString()); - intent.putExtra(Constants.EXTRA_INTERPRETER_NAME, - mConfiguration.getInterpreterForScript(mNameText.getText().toString()).getName()); - intent.putExtra(Constants.EXTRA_SCRIPT_TEXT, mContentText.getText().toString()); - startActivityForResult(intent, RequestCode.RPC_HELP.ordinal()); - } else if (item.getItemId() == MenuId.SHARE.getId()) { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.putExtra(Intent.EXTRA_TEXT, mContentText.getText().toString()); - intent.putExtra(Intent.EXTRA_SUBJECT, "Share " + mNameText.getText().toString()); - intent.setType("text/plain"); - startActivity(Intent.createChooser(intent, "Send Script to:")); - } else if (item.getItemId() == MenuId.GOTO.getId()) { - showDialog(DIALOG_LINE); - } else if (item.getItemId() == MenuId.SEARCH.getId()) { - showDialog(DIALOG_FIND_REPLACE); - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - RequestCode request = RequestCode.values()[requestCode]; - - if (resultCode == RESULT_OK) { - switch (request) { - case RPC_HELP: - String rpcText = data.getStringExtra(Constants.EXTRA_RPC_HELP_TEXT); - insertContent(rpcText); - break; - default: - break; - } - } else { - switch (request) { - case RPC_HELP: - break; - default: - break; - } - } - } - - private void save() { - int start = mContentText.getSelectionStart(); - mLastSavedContent = mContentText.getText().toString(); - mScript = new File(mScript.getParent(), mNameText.getText().toString()); - ScriptStorageAdapter.writeScript(mScript, mLastSavedContent); - Toast.makeText(this, "Saved " + mNameText.getText().toString(), Toast.LENGTH_SHORT).show(); - Editor e = mPreferences.edit(); - e.putInt("lasteditpos." + mScript, start); - e.commit(); - } - - private void insertContent(String text) { - int selectionStart = Math.min(mContentText.getSelectionStart(), mContentText.getSelectionEnd()); - int selectionEnd = Math.max(mContentText.getSelectionStart(), mContentText.getSelectionEnd()); - mContentText.getEditableText().replace(selectionStart, selectionEnd, text); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK && hasContentChanged()) { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - alert.setCancelable(false); - alert.setTitle("Confirm exit"); - alert.setMessage("Would you like to save?"); - alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - save(); - finish(); - } - }); - alert.setNegativeButton("No", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - finish(); - } - }); - alert.setNeutralButton("Cancel", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - } - }); - alert.show(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - redo(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { - undo(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_SEARCH) { - showDialog(DIALOG_FIND_REPLACE); - return true; - } else { - return super.onKeyDown(keyCode, event); - } - } - - @Override - protected Dialog onCreateDialog(int id, Bundle args) { - AlertDialog.Builder b = new AlertDialog.Builder(this); - if (id == DIALOG_LINE) { - b.setTitle("Goto Line"); - b.setView(mLineNo); - b.setPositiveButton("Ok", new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - gotoLine(Integer.parseInt(mLineNo.getText().toString())); - } - }); - b.setNegativeButton("Cancel", null); - return b.create(); - } else if (id == DIALOG_FIND_REPLACE) { - View v = getLayoutInflater().inflate(R.layout.findreplace, null); - mSearchFind = (EditText) v.findViewById(R.id.searchFind); - mSearchReplace = (EditText) v.findViewById(R.id.searchReplace); - mSearchAll = (CheckBox) v.findViewById(R.id.searchAll); - mSearchCase = (CheckBox) v.findViewById(R.id.searchCase); - mSearchStart = (CheckBox) v.findViewById(R.id.searchStart); - mSearchWord = (CheckBox) v.findViewById(R.id.searchWord); - b.setTitle("Search and Replace"); - b.setView(v); - b.setPositiveButton("Find", this); - b.setNeutralButton("Next", this); - b.setNegativeButton("Replace", this); - return b.create(); - } - - return super.onCreateDialog(id, args); - } - - @Override - protected void onPrepareDialog(int id, Dialog dialog, Bundle args) { - if (id == DIALOG_LINE) { - mLineNo.setText(String.valueOf(getLineNo())); - } else if (id == DIALOG_FIND_REPLACE) { - mSearchStart.setChecked(false); - } - super.onPrepareDialog(id, dialog, args); - } - - protected int getLineNo() { - int pos = mContentText.getSelectionStart(); - String text = mContentText.getText().toString(); - int i = 0; - int n = 1; - while (i < pos) { - int j = text.indexOf("\n", i); - if (j < 0) { - break; - } - i = j + 1; - if (i < pos) { - n += 1; - } - } - return n; - } - - protected void gotoLine(int line) { - String text = mContentText.getText().toString(); - if (text.length() < 1) { - return; - } - int i = 0; - int n = 1; - while (i < text.length() && n < line) { - int j = text.indexOf("\n", i); - if (j < 0) { - break; - } - i = j + 1; - n += 1; - } - mContentText.setSelection(Math.min(text.length() - 1, i)); - } - - @Override - protected void onUserLeaveHint() { - if (hasContentChanged()) { - save(); - } - } - - private boolean hasContentChanged() { - return !mLastSavedContent.equals(mContentText.getText().toString()); - } - - private final class ContentInputFilter implements InputFilter { - @Override - public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, - int dend) { - if (end - start == 1) { - Interpreter ip = mConfiguration.getInterpreterForScript(mNameText.getText().toString()); - String auto = null; - if (ip != null && mEnableAutoClose) { - auto = ip.getLanguage().autoClose(source.charAt(start)); - } - // Auto indent code? - if (auto == null && source.charAt(start) == '\n' && mAutoIndent) { - int i = dstart - 1; - int spaces = 0; - while ((i >= 0) && dest.charAt(i) != '\n') { - i -= 1; // Find start of line. - } - i += 1; - while (i < dest.length() && dest.charAt(i++) == ' ') { - spaces += 1; - } - if (spaces > 0) { - return String.format("\n%" + spaces + "s", " "); - } - } - if (auto != null) { - mScheduleMoveLeft = true; - return auto; - } - } - return null; - } - } - - private final class ContentTextWatcher implements TextWatcher { - private final EditHistory mmEditHistory; - private CharSequence mmBeforeChange; - private CharSequence mmAfterChange; - - private ContentTextWatcher(EditHistory history) { - mmEditHistory = history; - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - if (!mIsUndoOrRedo) { - mmAfterChange = s.subSequence(start, start + count); - mmEditHistory.add(new EditItem(start, mmBeforeChange, mmAfterChange)); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - if (!mIsUndoOrRedo) { - mmBeforeChange = s.subSequence(start, start + count); - } - } - - @Override - public void afterTextChanged(Editable s) { - if (mScheduleMoveLeft) { - mScheduleMoveLeft = false; - Selection.moveLeft(mContentText.getText(), mContentText.getLayout()); - } - } - } - - /** - * Keeps track of all the edit history of a text. - */ - private final class EditHistory { - int mmPosition = 0; - private final Vector<EditItem> mmHistory = new Vector<EditItem>(); - - /** - * Adds a new edit operation to the history at the current position. If executed after a call to - * getPrevious() removes all the future history (elements with positions >= current history - * position). - * - */ - private void add(EditItem item) { - mmHistory.setSize(mmPosition); - mmHistory.add(item); - mmPosition++; - } - - /** - * Traverses the history backward by one position, returns and item at that position. - */ - private EditItem getPrevious() { - if (mmPosition == 0) { - return null; - } - mmPosition--; - return mmHistory.get(mmPosition); - } - - /** - * Traverses the history forward by one position, returns and item at that position. - */ - private EditItem getNext() { - if (mmPosition == mmHistory.size()) { - return null; - } - EditItem item = mmHistory.get(mmPosition); - mmPosition++; - return item; - } - } - - /** - * Represents a single edit operation. - */ - private final class EditItem { - private final int mmIndex; - private final CharSequence mmBefore; - private final CharSequence mmAfter; - - /** - * Constructs EditItem of a modification that was applied at position start and replaced - * CharSequence before with CharSequence after. - */ - public EditItem(int start, CharSequence before, CharSequence after) { - mmIndex = start; - mmBefore = before; - mmAfter = after; - } - } - - private void undo() { - EditItem edit = mHistory.getPrevious(); - if (edit == null) { - return; - } - Editable text = mContentText.getText(); - int start = edit.mmIndex; - int end = start + (edit.mmAfter != null ? edit.mmAfter.length() : 0); - mIsUndoOrRedo = true; - text.replace(start, end, edit.mmBefore); - mIsUndoOrRedo = false; - // This will get rid of underlines inserted when editor tries to come up with a suggestion. - for (Object o : text.getSpans(0, text.length(), UnderlineSpan.class)) { - text.removeSpan(o); - } - Selection.setSelection(text, edit.mmBefore == null ? start : (start + edit.mmBefore.length())); - } - - private void redo() { - EditItem edit = mHistory.getNext(); - if (edit == null) { - return; - } - Editable text = mContentText.getText(); - int start = edit.mmIndex; - int end = start + (edit.mmBefore != null ? edit.mmBefore.length() : 0); - mIsUndoOrRedo = true; - text.replace(start, end, edit.mmAfter); - mIsUndoOrRedo = false; - for (Object o : text.getSpans(0, text.length(), UnderlineSpan.class)) { - text.removeSpan(o); - } - Selection.setSelection(text, edit.mmAfter == null ? start : (start + edit.mmAfter.length())); - } - - @Override - public void onClick(DialogInterface dialog, int which) { - int start = mContentText.getSelectionStart(); - int end = mContentText.getSelectionEnd(); - String original = mContentText.getText().toString(); - if (start == end || which != AlertDialog.BUTTON_NEGATIVE) { - end = original.length(); - } - if (which == AlertDialog.BUTTON_NEUTRAL) { - start += 1; - } - if (mSearchStart.isChecked()) { - start = 0; - end = original.length(); - } - String findText = mSearchFind.getText().toString(); - String replaceText = mSearchReplace.getText().toString(); - String search = Pattern.quote(findText); - int flags = 0; - if (!mSearchCase.isChecked()) { - flags |= Pattern.CASE_INSENSITIVE; - } - if (mSearchWord.isChecked()) { - search = "\\b" + search + "\\b"; - } - Pattern p = Pattern.compile(search, flags); - Matcher m = p.matcher(original); - m.region(start, end); - if (!m.find()) { - Toast.makeText(this, "Search not found.", Toast.LENGTH_SHORT).show(); - return; - } - int foundpos = m.start(); - if (which != AlertDialog.BUTTON_NEGATIVE) { // Find - mContentText.setSelection(foundpos, foundpos + findText.length()); - } else { // Replace - String s; - // Seems to be a bug in the android 2.2 implementation of replace... regions not returning - // whole string. - m = p.matcher(original.substring(start, end)); - String replace = Matcher.quoteReplacement(replaceText); - if (mSearchAll.isChecked()) { - s = m.replaceAll(replace); - } else { - s = m.replaceFirst(replace); - } - mContentText.setText(original.substring(0, start) + s + original.substring(end)); - mContentText.setSelection(foundpos, foundpos + replaceText.length()); - } - mContentText.requestFocus(); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptManager.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptManager.java deleted file mode 100644 index 9cc7c97..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptManager.java +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.app.SearchManager; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.DataSetObserver; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.preference.PreferenceManager; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.AdapterView; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.googlecode.android_scripting.ActivityFlinger; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.FileUtils; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptListAdapter; -import com.googlecode.android_scripting.ScriptStorageAdapter; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration.ConfigurationObserver; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; - -import java.io.File; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map.Entry; - -/** - * Manages creation, deletion, and execution of stored scripts. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ScriptManager extends ListActivity { - - private final static String EMPTY = ""; - - private List<File> mScripts; - private ScriptManagerAdapter mAdapter; - private SharedPreferences mPreferences; - private HashMap<Integer, Interpreter> mAddMenuIds; - private ScriptListObserver mObserver; - private InterpreterConfiguration mConfiguration; - private SearchManager mManager; - private boolean mInSearchResultMode = false; - private String mQuery = EMPTY; - private File mCurrentDir; - private final File mBaseDir = new File(InterpreterConstants.SCRIPTS_ROOT); - private final Handler mHandler = new Handler(); - private File mCurrent; - - private static enum RequestCode { - INSTALL_INTERPETER, QRCODE_ADD - } - - private static enum MenuId { - DELETE, HELP, FOLDER_ADD, QRCODE_ADD, INTERPRETER_MANAGER, PREFERENCES, LOGCAT_VIEWER, - TRIGGER_MANAGER, REFRESH, SEARCH, RENAME, EXTERNAL; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Scripts", R.layout.script_manager); - if (FileUtils.externalStorageMounted()) { - File sl4a = mBaseDir.getParentFile(); - if (!sl4a.exists()) { - sl4a.mkdir(); - try { - FileUtils.chmod(sl4a, 0755); // Handle the sl4a parent folder first. - } catch (Exception e) { - // Not much we can do here if it doesn't work. - } - } - if (!FileUtils.makeDirectories(mBaseDir, 0755)) { - new AlertDialog.Builder(this) - .setTitle("Error") - .setMessage( - "Failed to create scripts directory.\n" + mBaseDir + "\n" - + "Please check the permissions of your external storage media.") - .setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton("Ok", null).show(); - } - } else { - new AlertDialog.Builder(this).setTitle("External Storage Unavilable") - .setMessage("Scripts will be unavailable as long as external storage is unavailable.") - .setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton("Ok", null).show(); - } - - mCurrentDir = mBaseDir; - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - mAdapter = new ScriptManagerAdapter(this); - mObserver = new ScriptListObserver(); - mAdapter.registerDataSetObserver(mObserver); - mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - mManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); - - registerForContextMenu(getListView()); - updateAndFilterScriptList(mQuery); - setListAdapter(mAdapter); - ActivityFlinger.attachView(getListView(), this); - ActivityFlinger.attachView(getWindow().getDecorView(), this); - startService(IntentBuilders.buildTriggerServiceIntent()); - handleIntent(getIntent()); - } - - @Override - protected void onNewIntent(Intent intent) { - handleIntent(intent); - } - - @SuppressWarnings("serial") - private void updateAndFilterScriptList(final String query) { - List<File> scripts; - if (mPreferences.getBoolean("show_all_files", false)) { - scripts = ScriptStorageAdapter.listAllScripts(mCurrentDir); - } else { - scripts = ScriptStorageAdapter.listExecutableScripts(mCurrentDir, mConfiguration); - } - mScripts = Lists.newArrayList(Collections2.filter(scripts, new Predicate<File>() { - @Override - public boolean apply(File file) { - return file.getName().toLowerCase().contains(query.toLowerCase()); - } - })); - - // TODO(tturney): Add a text view that shows the queried text. - synchronized (mQuery) { - if (!mQuery.equals(query)) { - if (query != null || !query.equals(EMPTY)) { - mQuery = query; - } - } - } - - if ((mScripts.size() == 0) && findViewById(android.R.id.empty) != null) { - ((TextView) findViewById(android.R.id.empty)).setText("No matches found."); - } - - // TODO(damonkohler): Extending the File class here seems odd. - if (!mCurrentDir.equals(mBaseDir)) { - mScripts.add(0, new File(mCurrentDir.getParent()) { - @Override - public boolean isDirectory() { - return true; - } - - @Override - public String getName() { - return ".."; - } - }); - } - } - - private void handleIntent(Intent intent) { - if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - mInSearchResultMode = true; - String query = intent.getStringExtra(SearchManager.QUERY); - updateAndFilterScriptList(query); - mAdapter.notifyDataSetChanged(); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - menu.add(Menu.NONE, MenuId.RENAME.getId(), Menu.NONE, "Rename"); - menu.add(Menu.NONE, MenuId.DELETE.getId(), Menu.NONE, "Delete"); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - } catch (ClassCastException e) { - Log.e("Bad menuInfo", e); - return false; - } - File file = (File) mAdapter.getItem(info.position); - int itemId = item.getItemId(); - if (itemId == MenuId.DELETE.getId()) { - delete(file); - return true; - } else if (itemId == MenuId.RENAME.getId()) { - rename(file); - return true; - } - return false; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK && mInSearchResultMode) { - mInSearchResultMode = false; - mAdapter.notifyDataSetInvalidated(); - return true; - } - return super.onKeyDown(keyCode, event); - } - - @Override - public void onStop() { - super.onStop(); - mConfiguration.unregisterObserver(mObserver); - } - - @Override - public void onStart() { - super.onStart(); - mConfiguration.registerObserver(mObserver); - } - - @Override - protected void onResume() { - super.onResume(); - if (!mInSearchResultMode && findViewById(android.R.id.empty) != null) { - ((TextView) findViewById(android.R.id.empty)).setText(R.string.no_scripts_message); - } - updateAndFilterScriptList(mQuery); - mAdapter.notifyDataSetChanged(); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - menu.clear(); - buildMenuIdMaps(); - buildAddMenu(menu); - buildSwitchActivityMenu(menu); - menu.add(Menu.NONE, MenuId.SEARCH.getId(), Menu.NONE, "Search").setIcon( - R.drawable.ic_menu_search); - menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( - android.R.drawable.ic_menu_preferences); - menu.add(Menu.NONE, MenuId.REFRESH.getId(), Menu.NONE, "Refresh").setIcon( - R.drawable.ic_menu_refresh); - return true; - } - - private void buildSwitchActivityMenu(Menu menu) { - Menu subMenu = - menu.addSubMenu(Menu.NONE, Menu.NONE, Menu.NONE, "View").setIcon( - android.R.drawable.ic_menu_more); - subMenu.add(Menu.NONE, MenuId.INTERPRETER_MANAGER.getId(), Menu.NONE, "Interpreters"); - subMenu.add(Menu.NONE, MenuId.TRIGGER_MANAGER.getId(), Menu.NONE, "Triggers"); - subMenu.add(Menu.NONE, MenuId.LOGCAT_VIEWER.getId(), Menu.NONE, "Logcat"); - } - - private void buildMenuIdMaps() { - mAddMenuIds = new LinkedHashMap<Integer, Interpreter>(); - int i = MenuId.values().length + Menu.FIRST; - List<Interpreter> installed = mConfiguration.getInstalledInterpreters(); - Collections.sort(installed, new Comparator<Interpreter>() { - @Override - public int compare(Interpreter interpreterA, Interpreter interpreterB) { - return interpreterA.getNiceName().compareTo(interpreterB.getNiceName()); - } - }); - for (Interpreter interpreter : installed) { - mAddMenuIds.put(i, interpreter); - ++i; - } - } - - private void buildAddMenu(Menu menu) { - Menu addMenu = - menu.addSubMenu(Menu.NONE, Menu.NONE, Menu.NONE, "Add").setIcon( - android.R.drawable.ic_menu_add); - addMenu.add(Menu.NONE, MenuId.FOLDER_ADD.getId(), Menu.NONE, "Folder"); - for (Entry<Integer, Interpreter> entry : mAddMenuIds.entrySet()) { - addMenu.add(Menu.NONE, entry.getKey(), Menu.NONE, entry.getValue().getNiceName()); - } - addMenu.add(Menu.NONE, MenuId.QRCODE_ADD.getId(), Menu.NONE, "Scan Barcode"); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == MenuId.INTERPRETER_MANAGER.getId()) { - // Show interpreter manger. - Intent i = new Intent(this, InterpreterManager.class); - startActivity(i); - } else if (mAddMenuIds.containsKey(itemId)) { - // Add a new script. - Intent intent = new Intent(Constants.ACTION_EDIT_SCRIPT); - Interpreter interpreter = mAddMenuIds.get(itemId); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, - new File(mCurrentDir.getPath(), interpreter.getExtension()).getPath()); - intent.putExtra(Constants.EXTRA_SCRIPT_CONTENT, interpreter.getContentTemplate()); - intent.putExtra(Constants.EXTRA_IS_NEW_SCRIPT, true); - startActivity(intent); - synchronized (mQuery) { - mQuery = EMPTY; - } - } else if (itemId == MenuId.QRCODE_ADD.getId()) { - try { - Intent intent = new Intent("com.google.zxing.client.android.SCAN"); - startActivityForResult(intent, RequestCode.QRCODE_ADD.ordinal()); - }catch(ActivityNotFoundException e) { - Log.e("No handler found to Scan a QR Code!", e); - } - } else if (itemId == MenuId.FOLDER_ADD.getId()) { - addFolder(); - } else if (itemId == MenuId.PREFERENCES.getId()) { - startActivity(new Intent(this, Preferences.class)); - } else if (itemId == MenuId.TRIGGER_MANAGER.getId()) { - startActivity(new Intent(this, TriggerManager.class)); - } else if (itemId == MenuId.LOGCAT_VIEWER.getId()) { - startActivity(new Intent(this, LogcatViewer.class)); - } else if (itemId == MenuId.REFRESH.getId()) { - updateAndFilterScriptList(mQuery); - mAdapter.notifyDataSetChanged(); - } else if (itemId == MenuId.SEARCH.getId()) { - onSearchRequested(); - } - return true; - } - - @Override - protected void onListItemClick(ListView list, View view, int position, long id) { - final File file = (File) list.getItemAtPosition(position); - mCurrent = file; - if (file.isDirectory()) { - mCurrentDir = file; - mAdapter.notifyDataSetInvalidated(); - return; - } - doDialogMenu(); - return; - } - - // Quickedit chokes on sdk 3 or below, and some Android builds. Provides alternative menu. - private void doDialogMenu() { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - final CharSequence[] menuList = - { "Run Foreground", "Run Background", "Edit", "Delete", "Rename" }; - builder.setTitle(mCurrent.getName()); - builder.setItems(menuList, new DialogInterface.OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent; - switch (which) { - case 0: - intent = new Intent(ScriptManager.this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_LAUNCH_FOREGROUND_SCRIPT); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, mCurrent.getPath()); - startService(intent); - break; - case 1: - intent = new Intent(ScriptManager.this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_LAUNCH_BACKGROUND_SCRIPT); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, mCurrent.getPath()); - startService(intent); - break; - case 2: - editScript(mCurrent); - break; - case 3: - delete(mCurrent); - break; - case 4: - rename(mCurrent); - break; - } - } - }); - builder.show(); - } - - /** - * Opens the script for editing. - * - * @param script - * the name of the script to edit - */ - private void editScript(File script) { - Intent i = new Intent(Constants.ACTION_EDIT_SCRIPT); - i.putExtra(Constants.EXTRA_SCRIPT_PATH, script.getAbsolutePath()); - startActivity(i); - } - - private void delete(final File file) { - AlertDialog.Builder alert = new AlertDialog.Builder(this); - alert.setTitle("Delete"); - alert.setMessage("Would you like to delete " + file.getName() + "?"); - alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - FileUtils.delete(file); - mScripts.remove(file); - mAdapter.notifyDataSetChanged(); - } - }); - alert.setNegativeButton("No", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - // Ignore. - } - }); - alert.show(); - } - - private void addFolder() { - final EditText folderName = new EditText(this); - folderName.setHint("Folder Name"); - AlertDialog.Builder alert = new AlertDialog.Builder(this); - alert.setTitle("Add Folder"); - alert.setView(folderName); - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - String name = folderName.getText().toString(); - if (name.length() == 0) { - Log.e(ScriptManager.this, "Folder name is empty."); - return; - } else { - for (File f : mScripts) { - if (f.getName().equals(name)) { - Log.e(ScriptManager.this, String.format("Folder \"%s\" already exists.", name)); - return; - } - } - } - File dir = new File(mCurrentDir, name); - if (!FileUtils.makeDirectories(dir, 0755)) { - Log.e(ScriptManager.this, String.format("Cannot create folder \"%s\".", name)); - } - mAdapter.notifyDataSetInvalidated(); - } - }); - alert.show(); - } - - private void rename(final File file) { - final EditText newName = new EditText(this); - newName.setText(file.getName()); - AlertDialog.Builder alert = new AlertDialog.Builder(this); - alert.setTitle("Rename"); - alert.setView(newName); - alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - String name = newName.getText().toString(); - if (name.length() == 0) { - Log.e(ScriptManager.this, "Name is empty."); - return; - } else { - for (File f : mScripts) { - if (f.getName().equals(name)) { - Log.e(ScriptManager.this, String.format("\"%s\" already exists.", name)); - return; - } - } - } - if (!FileUtils.rename(file, name)) { - throw new RuntimeException(String.format("Cannot rename \"%s\".", file.getPath())); - } - mAdapter.notifyDataSetInvalidated(); - } - }); - alert.show(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - RequestCode request = RequestCode.values()[requestCode]; - if (resultCode == RESULT_OK) { - switch (request) { - case QRCODE_ADD: - writeScriptFromBarcode(data); - break; - default: - break; - } - } else { - switch (request) { - case QRCODE_ADD: - break; - default: - break; - } - } - mAdapter.notifyDataSetInvalidated(); - } - - private void writeScriptFromBarcode(Intent data) { - String result = data.getStringExtra("SCAN_RESULT"); - if (result == null) { - Log.e(this, "Invalid QR code content."); - return; - } - String contents[] = result.split("\n", 2); - if (contents.length != 2) { - Log.e(this, "Invalid QR code content."); - return; - } - String title = contents[0]; - String body = contents[1]; - File script = new File(mCurrentDir, title); - ScriptStorageAdapter.writeScript(script, body); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mConfiguration.unregisterObserver(mObserver); - mManager.setOnCancelListener(null); - } - - private class ScriptListObserver extends DataSetObserver implements ConfigurationObserver { - @Override - public void onInvalidated() { - updateAndFilterScriptList(EMPTY); - } - - @Override - public void onConfigurationChanged() { - runOnUiThread(new Runnable() { - @Override - public void run() { - updateAndFilterScriptList(mQuery); - mAdapter.notifyDataSetChanged(); - } - }); - } - } - - private class ScriptManagerAdapter extends ScriptListAdapter { - public ScriptManagerAdapter(Context context) { - super(context); - } - - @Override - protected List<File> getScriptList() { - return mScripts; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptPicker.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptPicker.java deleted file mode 100644 index 9385382..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptPicker.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.content.Context; -import android.content.Intent; -import android.database.DataSetObserver; -import android.os.Bundle; -import android.os.Parcelable; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ListView; - -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.FeaturedInterpreters; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptListAdapter; -import com.googlecode.android_scripting.ScriptStorageAdapter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; - -import java.io.File; -import java.util.List; - - -/** - * Presents available scripts and returns the selected one. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ScriptPicker extends ListActivity { - - private List<File> mScripts; - private ScriptPickerAdapter mAdapter; - private InterpreterConfiguration mConfiguration; - private File mCurrentDir; - private final File mBaseDir = new File(InterpreterConstants.SCRIPTS_ROOT); - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Scripts", R.layout.script_manager); - mCurrentDir = mBaseDir; - mConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - mScripts = ScriptStorageAdapter.listExecutableScripts(null, mConfiguration); - mAdapter = new ScriptPickerAdapter(this); - mAdapter.registerDataSetObserver(new ScriptListObserver()); - setListAdapter(mAdapter); - } - - @Override - protected void onListItemClick(ListView list, View view, int position, long id) { - final File script = (File) list.getItemAtPosition(position); - - if (script.isDirectory()) { - mCurrentDir = script; - mAdapter.notifyDataSetInvalidated(); - return; - } - - //TODO: Take action here based on item click - } - - private class ScriptListObserver extends DataSetObserver { - @SuppressWarnings("serial") - @Override - public void onInvalidated() { - mScripts = ScriptStorageAdapter.listExecutableScripts(mCurrentDir, mConfiguration); - // TODO(damonkohler): Extending the File class here seems odd. - if (!mCurrentDir.equals(mBaseDir)) { - mScripts.add(0, new File(mCurrentDir.getParent()) { - @Override - public boolean isDirectory() { - return true; - } - - @Override - public String getName() { - return ".."; - } - }); - } - } - } - - private class ScriptPickerAdapter extends ScriptListAdapter { - - public ScriptPickerAdapter(Context context) { - super(context); - } - - @Override - protected List<File> getScriptList() { - return mScripts; - } - - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptProcessMonitor.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptProcessMonitor.java deleted file mode 100644 index 614890a..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptProcessMonitor.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.ListActivity; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.IBinder; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; - -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import org.connectbot.ConsoleActivity; - -/** - * An activity that allows to monitor running scripts. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public class ScriptProcessMonitor extends ListActivity { - - private final static int UPDATE_INTERVAL_SECS = 1; - - private final Timer mTimer = new Timer(); - - private volatile ScriptingLayerService mService; - - private ScriptListAdapter mUpdater; - private List<InterpreterProcess> mProcessList; - private ScriptMonitorAdapter mAdapter; - private boolean mIsConnected = false; - - private ServiceConnection mConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - mService = ((ScriptingLayerService.LocalBinder) service).getService(); - mUpdater = new ScriptListAdapter(); - mTimer.scheduleAtFixedRate(mUpdater, 0, UPDATE_INTERVAL_SECS * 1000); - mIsConnected = true; - } - - @Override - public void onServiceDisconnected(ComponentName name) { - mService = null; - mIsConnected = false; - mProcessList = null; - mAdapter.notifyDataSetChanged(); - } - }; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - bindService(new Intent(this, ScriptingLayerService.class), mConnection, 0); - CustomizeWindow.requestCustomTitle(this, "Script Monitor", R.layout.script_monitor); - mAdapter = new ScriptMonitorAdapter(); - setListAdapter(mAdapter); - registerForContextMenu(getListView()); - } - - @Override - public void onPause() { - super.onPause(); - if (mUpdater != null) { - mUpdater.cancel(); - } - mTimer.purge(); - } - - @Override - public void onResume() { - super.onResume(); - if (mIsConnected) { - try { - mUpdater = new ScriptListAdapter(); - mTimer.scheduleAtFixedRate(mUpdater, 0, UPDATE_INTERVAL_SECS * 1000); - } catch (IllegalStateException e) { - Log.e(e.getMessage(), e); - } - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - mTimer.cancel(); - unbindService(mConnection); - } - - @Override - protected void onListItemClick(ListView list, View view, int position, long id) { - final InterpreterProcess script = (InterpreterProcess) list.getItemAtPosition(position); - Intent intent = new Intent(this, ConsoleActivity.class); - intent.putExtra(Constants.EXTRA_PROXY_PORT, script.getPort()); - startActivity(intent); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { - menu.add(Menu.NONE, 0, Menu.NONE, "Stop"); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - } catch (ClassCastException e) { - Log.e("Bad menuInfo", e); - return false; - } - - InterpreterProcess script = mAdapter.getItem(info.position); - if (script == null) { - Log.v("No script selected."); - return false; - } - - Intent intent = new Intent(ScriptProcessMonitor.this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_KILL_PROCESS); - intent.putExtra(Constants.EXTRA_PROXY_PORT, script.getPort()); - startService(intent); - - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - menu.clear(); - // TODO(damonkohler): How could mProcessList ever be null? - if (mProcessList != null && !mProcessList.isEmpty()) { - menu.add(Menu.NONE, 0, Menu.NONE, R.string.stop_all).setIcon( - android.R.drawable.ic_menu_close_clear_cancel); - } - return super.onPrepareOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - Intent intent = new Intent(this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_KILL_ALL); - startService(intent); - return true; - } - - private class ScriptListAdapter extends TimerTask { - private int mmExpectedModCount = 0; - private volatile List<InterpreterProcess> mmList; - - @Override - public void run() { - if (mService == null) { - mmList.clear(); - mTimer.cancel(); - } else { - int freshModCount = mService.getModCount(); - if (freshModCount != mmExpectedModCount) { - mmExpectedModCount = freshModCount; - mmList = mService.getScriptProcessesList(); - } - } - runOnUiThread(new Runnable() { - public void run() { - mProcessList = mUpdater.getFreshProcessList(); - mAdapter.notifyDataSetChanged(); - } - }); - } - - private List<InterpreterProcess> getFreshProcessList() { - return mmList; - } - } - - private class ScriptMonitorAdapter extends BaseAdapter { - - @Override - public int getCount() { - if (mProcessList == null) { - return 0; - } - return mProcessList.size(); - } - - @Override - public InterpreterProcess getItem(int position) { - return mProcessList.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View itemView; - if (convertView == null) { - LayoutInflater inflater = - (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); - itemView = inflater.inflate(R.layout.script_monitor_list_item, parent, false); - } else { - itemView = convertView; - } - InterpreterProcess process = mProcessList.get(position); - ((TextView) itemView.findViewById(R.id.process_title)).setText(process.getName()); - ((TextView) itemView.findViewById(R.id.process_age)).setText(process.getUptime()); - ((TextView) itemView.findViewById(R.id.process_details)).setText(process.getHost() + ":" - + process.getPort()); - ((TextView) itemView.findViewById(R.id.process_status)).setText("PID " + process.getPid()); - return itemView; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerService.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerService.java deleted file mode 100644 index 80b7aae..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerService.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Binder; -import android.os.IBinder; -import android.os.Build; -import android.os.StrictMode; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.googlecode.android_scripting.AndroidProxy; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.ForegroundService; -import com.googlecode.android_scripting.NotificationIdFactory; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptLauncher; -import com.googlecode.android_scripting.ScriptProcess; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; -import com.googlecode.android_scripting.interpreter.shell.ShellInterpreter; - -import org.connectbot.ConsoleActivity; -import org.connectbot.service.TerminalManager; - -import java.io.File; -import java.lang.ref.WeakReference; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * A service that allows scripts and the RPC server to run in the background. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class ScriptingLayerService extends ForegroundService { - private static final int NOTIFICATION_ID = NotificationIdFactory.create(); - - private final IBinder mBinder; - private final Map<Integer, InterpreterProcess> mProcessMap; - private final String LOG_TAG = "sl4a"; - private volatile int mModCount = 0; - private NotificationManager mNotificationManager; - private Notification mNotification; - private PendingIntent mNotificationPendingIntent; - private InterpreterConfiguration mInterpreterConfiguration; - - private volatile WeakReference<InterpreterProcess> mRecentlyKilledProcess; - - private TerminalManager mTerminalManager; - - private SharedPreferences mPreferences = null; - private boolean mHide; - - public class LocalBinder extends Binder { - public ScriptingLayerService getService() { - return ScriptingLayerService.this; - } - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - public ScriptingLayerService() { - super(NOTIFICATION_ID); - mProcessMap = new ConcurrentHashMap<Integer, InterpreterProcess>(); - mBinder = new LocalBinder(); - } - - @Override - public void onCreate() { - super.onCreate(); - mInterpreterConfiguration = ((BaseApplication) getApplication()).getInterpreterConfiguration(); - mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - mRecentlyKilledProcess = new WeakReference<InterpreterProcess>(null); - mTerminalManager = new TerminalManager(this); - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - mHide = mPreferences.getBoolean(Constants.HIDE_NOTIFY, false); - } - - @Override - protected Notification createNotification() { - Intent notificationIntent = new Intent(this, ScriptingLayerService.class); - notificationIntent.setAction(Constants.ACTION_SHOW_RUNNING_SCRIPTS); - mNotificationPendingIntent = PendingIntent.getService(this, 0, notificationIntent, 0); - - Notification.Builder builder = new Notification.Builder(this); - builder.setSmallIcon(R.drawable.sl4a_notification_logo) - .setTicker(null) - .setWhen(System.currentTimeMillis()) - .setContentTitle("SL4A Service") - .setContentText("Tap to view running scripts") - .setContentIntent(mNotificationPendingIntent); - mNotification = builder.build(); - mNotification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; - return mNotification; - } - - private void updateNotification(String tickerText) { - if (tickerText.equals(mNotification.tickerText)) { - // Consequent notifications with the same ticker-text are displayed without any ticker-text. - // This is a way around. Alternatively, we can display process name and port. - tickerText = tickerText + " "; - } - String msg; - if (mProcessMap.size() <= 1) { - msg = "Tap to view " + Integer.toString(mProcessMap.size()) + " running script"; - } else { - msg = "Tap to view " + Integer.toString(mProcessMap.size()) + " running scripts"; - } - Notification.Builder builder = new Notification.Builder(this); - builder.setContentTitle("SL4A Service") - .setContentText(msg) - .setContentIntent(mNotificationPendingIntent) - .setSmallIcon(mNotification.icon, mProcessMap.size()) - .setWhen(mNotification.when) - .setTicker(tickerText); - - mNotification = builder.build(); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - super.onStartCommand(intent, flags, startId); - String errmsg = null; - if (intent == null) { - return START_REDELIVER_INTENT; - } - if (intent.getAction().equals(Constants.ACTION_KILL_ALL)) { - killAll(); - stopSelf(startId); - return START_REDELIVER_INTENT; - } - - if (intent.getAction().equals(Constants.ACTION_KILL_PROCESS)) { - killProcess(intent); - if (mProcessMap.isEmpty()) { - stopSelf(startId); - } - return START_REDELIVER_INTENT; - } - - if (intent.getAction().equals(Constants.ACTION_SHOW_RUNNING_SCRIPTS)) { - showRunningScripts(); - return START_REDELIVER_INTENT; - } - - //TODO: b/26538940 We need to go back to a strict policy and fix the problems - StrictMode.ThreadPolicy sl4aPolicy = new StrictMode.ThreadPolicy.Builder() - .detectAll() - .penaltyLog() - .build(); - - StrictMode.setThreadPolicy(sl4aPolicy); - - AndroidProxy proxy = null; - InterpreterProcess interpreterProcess = null; - if (intent.getAction().equals(Constants.ACTION_LAUNCH_SERVER)) { - proxy = launchServer(intent, false); - // TODO(damonkohler): This is just to make things easier. Really, we shouldn't need to start - // an interpreter when all we want is a server. - interpreterProcess = new InterpreterProcess(new ShellInterpreter(), proxy); - interpreterProcess.setName("Server"); - } else { - proxy = launchServer(intent, true); - if (intent.getAction().equals(Constants.ACTION_LAUNCH_FOREGROUND_SCRIPT)) { - launchTerminal(proxy.getAddress()); - try { - interpreterProcess = launchScript(intent, proxy); - } catch (RuntimeException e) { - errmsg = - "Unable to run " + intent.getStringExtra(Constants.EXTRA_SCRIPT_PATH) + "\n" - + e.getMessage(); - interpreterProcess = null; - } - } else if (intent.getAction().equals(Constants.ACTION_LAUNCH_BACKGROUND_SCRIPT)) { - interpreterProcess = launchScript(intent, proxy); - } else if (intent.getAction().equals(Constants.ACTION_LAUNCH_INTERPRETER)) { - launchTerminal(proxy.getAddress()); - interpreterProcess = launchInterpreter(intent, proxy); - } - } - if (errmsg != null) { - updateNotification(errmsg); - } else if (interpreterProcess == null) { - updateNotification("Action not implemented: " + intent.getAction()); - } else { - addProcess(interpreterProcess); - } - return START_REDELIVER_INTENT; - } - - private boolean tryPort(AndroidProxy androidProxy, boolean usePublicIp, int usePort) { - if (usePublicIp) { - return (androidProxy.startPublic(usePort) != null); - } else { - return (androidProxy.startLocal(usePort) != null); - } - } - - private AndroidProxy launchServer(Intent intent, boolean requiresHandshake) { - AndroidProxy androidProxy = new AndroidProxy(this, intent, requiresHandshake); - boolean usePublicIp = intent.getBooleanExtra(Constants.EXTRA_USE_EXTERNAL_IP, false); - int usePort = intent.getIntExtra(Constants.EXTRA_USE_SERVICE_PORT, 0); - // If port is in use, fall back to default behaviour - if (!tryPort(androidProxy, usePublicIp, usePort)) { - if (usePort != 0) { - tryPort(androidProxy, usePublicIp, 0); - } - } - return androidProxy; - } - - private ScriptProcess launchScript(Intent intent, AndroidProxy proxy) { - final int port = proxy.getAddress().getPort(); - File script = new File(intent.getStringExtra(Constants.EXTRA_SCRIPT_PATH)); - return ScriptLauncher.launchScript(script, mInterpreterConfiguration, proxy, new Runnable() { - @Override - public void run() { - // TODO(damonkohler): This action actually kills the script rather than notifying the - // service that script exited on its own. We should distinguish between these two cases. - Intent intent = new Intent(ScriptingLayerService.this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_KILL_PROCESS); - intent.putExtra(Constants.EXTRA_PROXY_PORT, port); - startService(intent); - } - }); - } - - private InterpreterProcess launchInterpreter(Intent intent, AndroidProxy proxy) { - InterpreterConfiguration config = - ((BaseApplication) getApplication()).getInterpreterConfiguration(); - final int port = proxy.getAddress().getPort(); - return ScriptLauncher.launchInterpreter(proxy, intent, config, new Runnable() { - @Override - public void run() { - // TODO(damonkohler): This action actually kills the script rather than notifying the - // service that script exited on its own. We should distinguish between these two cases. - Intent intent = new Intent(ScriptingLayerService.this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_KILL_PROCESS); - intent.putExtra(Constants.EXTRA_PROXY_PORT, port); - startService(intent); - } - }); - } - - private void launchTerminal(InetSocketAddress address) { - Intent i = new Intent(this, ConsoleActivity.class); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - i.putExtra(Constants.EXTRA_PROXY_PORT, address.getPort()); - startActivity(i); - } - - private void showRunningScripts() { - Intent i = new Intent(this, ScriptProcessMonitor.class); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(i); - } - - private void addProcess(InterpreterProcess process) { - mProcessMap.put(process.getPort(), process); - mModCount++; - if (!mHide) { - updateNotification(process.getName() + " started."); - } - } - - private InterpreterProcess removeProcess(int port) { - InterpreterProcess process = mProcessMap.remove(port); - if (process == null) { - return null; - } - mModCount++; - if (!mHide) { - updateNotification(process.getName() + " exited."); - } - return process; - } - - private void killProcess(Intent intent) { - int processId = intent.getIntExtra(Constants.EXTRA_PROXY_PORT, 0); - InterpreterProcess process = removeProcess(processId); - if (process != null) { - process.kill(); - mRecentlyKilledProcess = new WeakReference<InterpreterProcess>(process); - } - } - - public int getModCount() { - return mModCount; - } - - private void killAll() { - for (InterpreterProcess process : getScriptProcessesList()) { - process = removeProcess(process.getPort()); - if (process != null) { - process.kill(); - } - } - } - - public List<InterpreterProcess> getScriptProcessesList() { - ArrayList<InterpreterProcess> result = new ArrayList<InterpreterProcess>(); - result.addAll(mProcessMap.values()); - return result; - } - - public InterpreterProcess getProcess(int port) { - InterpreterProcess p = mProcessMap.get(port); - if (p == null) { - return mRecentlyKilledProcess.get(); - } - return p; - } - - public TerminalManager getTerminalManager() { - return mTerminalManager; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerServiceLauncher.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerServiceLauncher.java deleted file mode 100644 index e373670..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptingLayerServiceLauncher.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.os.SystemProperties; - -import android.util.Log; - -import com.googlecode.android_scripting.Constants; - -public class ScriptingLayerServiceLauncher extends Activity { - - private static final int DEBUGGABLE_BUILD = 1; - - private static final String LOG_TAG = "sl4a"; - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Forward the intent that launched us to start the service. - - if(SystemProperties.getInt("ro.debuggable", 0) == DEBUGGABLE_BUILD) { - Intent intent = getIntent(); - intent.setComponent(Constants.SL4A_SERVICE_COMPONENT_NAME); - startService(intent); - finish(); - } - else { - Log.e(LOG_TAG, "ERROR: Cannot to start SL4A on non-debuggable build!"); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptsLiveFolder.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptsLiveFolder.java deleted file mode 100644 index 191c641..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptsLiveFolder.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.Intent.ShortcutIconResource; -import android.net.Uri; -import android.os.Bundle; -import android.provider.LiveFolders; - -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.provider.ScriptProvider; - -public class ScriptsLiveFolder extends Activity { - - public static final Uri CONTENT_URI = - Uri.parse("content://" + ScriptProvider.AUTHORITY + "/" + ScriptProvider.LIVEFOLDER); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final Intent intent = getIntent(); - final String action = intent.getAction(); - if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) { - setResult(RESULT_OK, createLiveFolder(this, CONTENT_URI, "Scripts", R.drawable.live_folder)); - } else { - setResult(RESULT_CANCELED); - } - finish(); - } - - private Intent createLiveFolder(Context context, Uri uri, String name, int icon) { - final Intent intent = new Intent(); - intent.setData(uri); - intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, name); - intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, ShortcutIconResource - .fromContext(this, icon)); - intent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST); - return intent; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ServiceUtils.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ServiceUtils.java deleted file mode 100644 index ddb5937..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ServiceUtils.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Context; - -import com.googlecode.android_scripting.Log; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * A utility class supplying helper methods for {@link Service} objects. - * - * @author Felix Arends (felix.arends@gmail.com) - */ -public class ServiceUtils { - private ServiceUtils() { - } - - /** - * Marks the service as a foreground service. This uses reflection to figure out whether the new - * APIs for marking a service as a foreground service are available. If not, it falls back to the - * old {@link #setForeground(boolean)} call. - * - * @param service - * the service to put in foreground mode - * @param notificationId - * id of the notification to show - * @param notification - * the notification to show - */ - public static void setForeground(Service service, Integer notificationId, - Notification notification) { - final Class<?>[] startForegroundSignature = new Class[] { int.class, Notification.class }; - Method startForeground = null; - try { - startForeground = service.getClass().getMethod("startForeground", startForegroundSignature); - - try { - startForeground.invoke(service, new Object[] { notificationId, notification }); - } catch (IllegalArgumentException e) { - // Should not happen! - Log.e("Could not set TriggerService to foreground mode.", e); - } catch (IllegalAccessException e) { - // Should not happen! - Log.e("Could not set TriggerService to foreground mode.", e); - } catch (InvocationTargetException e) { - // Should not happen! - Log.e("Could not set TriggerService to foreground mode.", e); - } - - } catch (NoSuchMethodException e) { - // Fall back on old API. - // service.setForeground(true); //too old to be supported - - NotificationManager manager = - (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE); - manager.notify(notificationId, notification); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerManager.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerManager.java deleted file mode 100644 index fc37796..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerManager.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.DialogInterface.OnClickListener; -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.ContextMenu.ContextMenuInfo; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; - -import com.google.common.collect.Lists; -import com.googlecode.android_scripting.ActivityFlinger; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.trigger.ScriptTrigger; -import com.googlecode.android_scripting.trigger.Trigger; -import com.googlecode.android_scripting.trigger.TriggerRepository; -import com.googlecode.android_scripting.trigger.TriggerRepository.TriggerRepositoryObserver; - -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -public class TriggerManager extends ListActivity { - private final List<ScriptTrigger> mTriggers = Lists.newArrayList(); - - private ScriptTriggerAdapter mAdapter; - private TriggerRepository mTriggerRepository; - - private static enum ContextMenuId { - REMOVE; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private static enum MenuId { - ADD, PREFERENCES, HELP; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - CustomizeWindow.requestCustomTitle(this, "Triggers", R.layout.trigger_manager); - ScriptTriggerListObserver observer = new ScriptTriggerListObserver(); - mAdapter = new ScriptTriggerAdapter(); - setListAdapter(mAdapter); - registerForContextMenu(getListView()); - mTriggerRepository = ((BaseApplication) getApplication()).getTriggerRepository(); - mTriggerRepository.bootstrapObserver(observer); - ActivityFlinger.attachView(getListView(), this); - ActivityFlinger.attachView(getWindow().getDecorView(), this); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(Menu.NONE, MenuId.ADD.getId(), Menu.NONE, "Add").setIcon( - android.R.drawable.ic_menu_add); - menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon( - android.R.drawable.ic_menu_preferences); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == MenuId.PREFERENCES.getId()) { - startActivity(new Intent(this, Preferences.class)); - } else if (itemId != Menu.NONE) { - Intent intent = new Intent(this, ScriptPicker.class); - intent.setAction(Intent.ACTION_PICK); - startActivityForResult(intent, itemId); - } - return true; - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - menu.add(Menu.NONE, ContextMenuId.REMOVE.getId(), Menu.NONE, "Remove"); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - AdapterView.AdapterContextMenuInfo info; - try { - info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); - } catch (ClassCastException e) { - Log.e("Bad menuInfo", e); - return false; - } - - Trigger trigger = mAdapter.getItem(info.position); - if (trigger == null) { - Log.v("No trigger selected."); - return false; - } - - if (item.getItemId() == ContextMenuId.REMOVE.getId()) { - mTriggerRepository.remove(trigger); - } - return true; - } - - @Override - public void onListItemClick(ListView l, View v, int position, long id) { - mAdapter.notifyDataSetInvalidated(); - } - - private class ScriptTriggerListObserver implements TriggerRepositoryObserver { - - @Override - public void onPut(Trigger trigger) { - mTriggers.add((ScriptTrigger) trigger); - mAdapter.notifyDataSetInvalidated(); - } - - @Override - public void onRemove(Trigger trigger) { - mTriggers.remove(trigger); - mAdapter.notifyDataSetInvalidated(); - } - } - - private class ScriptTriggerAdapter extends BaseAdapter { - - @Override - public int getCount() { - return mTriggers.size(); - } - - @Override - public Trigger getItem(int position) { - return mTriggers.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(final int position, View convertView, ViewGroup parent) { - ScriptTrigger trigger = mTriggers.get(position); - TextView textView = new TextView(TriggerManager.this); - textView.setText(trigger.getEventName() + " " + trigger.getScript().getName()); - return textView; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == RESULT_OK) { - final File script = new File(data.getStringExtra(Constants.EXTRA_SCRIPT_PATH)); - if (requestCode == MenuId.ADD.getId()) { - Map<String, MethodDescriptor> eventMethodDescriptors = - FacadeConfiguration.collectStartEventMethodDescriptors(); - final List<String> eventNames = Lists.newArrayList(eventMethodDescriptors.keySet()); - Collections.sort(eventNames); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setItems(eventNames.toArray(new CharSequence[eventNames.size()]), - new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int position) { - mTriggerRepository.put(new ScriptTrigger(eventNames.get(position), script)); - } - }); - builder.show(); - } - } - } - - public void clickCancel(View v) { - for (Trigger t : mTriggerRepository.getAllTriggers().values()) { - mTriggerRepository.remove(t); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerService.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerService.java deleted file mode 100644 index 8024533..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/TriggerService.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.activity; - -import android.app.AlarmManager; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.os.Binder; -import android.os.IBinder; - -import com.google.common.base.Preconditions; -import com.googlecode.android_scripting.BaseApplication; -import com.googlecode.android_scripting.ForegroundService; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.NotificationIdFactory; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.event.Event; -import com.googlecode.android_scripting.event.EventObserver; -import com.googlecode.android_scripting.facade.EventFacade; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.facade.FacadeManager; -import com.googlecode.android_scripting.trigger.EventGenerationControllingObserver; -import com.googlecode.android_scripting.trigger.Trigger; -import com.googlecode.android_scripting.trigger.TriggerRepository; -import com.googlecode.android_scripting.trigger.TriggerRepository.TriggerRepositoryObserver; - -/** - * The trigger service takes care of installing triggers serialized to the preference storage. - * - * <p> - * The service also installs an alarm that keeps it running, unless the user force-quits the - * service. - * - * <p> - * When no triggers are installed the service shuts down silently as to not consume resources - * unnecessarily. - * - * @author Felix Arends (felix.arends@gmail.com) - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class TriggerService extends ForegroundService { - private static final int NOTIFICATION_ID = NotificationIdFactory.create(); - private static final long PING_MILLIS = 10 * 1000 * 60; - - private final IBinder mBinder; - private TriggerRepository mTriggerRepository; - private FacadeManager mFacadeManager; - private EventFacade mEventFacade; - - public class LocalBinder extends Binder { - public TriggerService getService() { - return TriggerService.this; - } - } - - public TriggerService() { - super(NOTIFICATION_ID); - mBinder = new LocalBinder(); - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - @Override - public void onCreate() { - super.onCreate(); - - mFacadeManager = - new FacadeManager(FacadeConfiguration.getSdkLevel(), this, null, - FacadeConfiguration.getFacadeClasses()); - mEventFacade = mFacadeManager.getReceiver(EventFacade.class); - - mTriggerRepository = ((BaseApplication) getApplication()).getTriggerRepository(); - mTriggerRepository.bootstrapObserver(new RepositoryObserver()); - mTriggerRepository.bootstrapObserver(new EventGenerationControllingObserver(mFacadeManager)); - installAlarm(); - } - - @Override - public void onStart(Intent intent, int startId) { - if (mTriggerRepository.isEmpty()) { - stopSelfResult(startId); - return; - } - } - - /** Returns the notification to display whenever the service is running. */ - @Override - protected Notification createNotification() { - Intent notificationIntent = new Intent(this, TriggerManager.class); - Notification.Builder builder = new Notification.Builder(this); - builder.setSmallIcon(R.drawable.sl4a_logo_48) - .setTicker("SL4A Trigger Service started.") - .setWhen(System.currentTimeMillis()) - .setContentTitle("SL4A Trigger Service") - .setContentText("Tap to view triggers") - .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, 0)); - Notification notification = builder.build(); - notification.flags = Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; - return notification; - } - - private class TriggerEventObserver implements EventObserver { - private final Trigger mTrigger; - - public TriggerEventObserver(Trigger trigger) { - mTrigger = trigger; - } - - @Override - public void onEventReceived(Event event) { - mTrigger.handleEvent(event, TriggerService.this); - } - } - - private class RepositoryObserver implements TriggerRepositoryObserver { - int mTriggerCount = 0; - - @Override - public void onPut(Trigger trigger) { - mTriggerCount++; - mEventFacade.addNamedEventObserver(trigger.getEventName(), new TriggerEventObserver(trigger)); - } - - @Override - public void onRemove(Trigger trigger) { - Preconditions.checkArgument(mTriggerCount > 0); - // TODO(damonkohler): Tear down EventObserver associated with trigger. - if (--mTriggerCount == 0) { - // TODO(damonkohler): Use stopSelfResult() which would require tracking startId. - stopSelf(); - } - } - } - - private void installAlarm() { - AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); - alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + PING_MILLIS, - PING_MILLIS, IntentBuilders.buildTriggerServicePendingIntent(this)); - } - - private void uninstallAlarm() { - AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); - alarmManager.cancel(IntentBuilders.buildTriggerServicePendingIntent(this)); - } - - @Override - public void onDestroy() { - super.onDestroy(); - uninstallAlarm(); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/dialog/DurationPickerDialog.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/dialog/DurationPickerDialog.java deleted file mode 100644 index 6a53fac..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/dialog/DurationPickerDialog.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.dialog; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; - -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.widget.DurationPicker; - -public class DurationPickerDialog { - - private DurationPickerDialog() { - // Utility class. - } - - public interface DurationPickedListener { - public void onSet(double duration); - - public void onCancel(); - } - - public static void getDurationFromDialog(Activity activity, String title, - final DurationPickedListener done) { - final DurationPicker picker = new DurationPicker(activity); - AlertDialog.Builder alert = new AlertDialog.Builder(activity); - alert.setIcon(R.drawable.ic_dialog_time); - alert.setTitle(title); - alert.setView(picker); - alert.setPositiveButton("Set", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int whichButton) { - done.onSet(picker.getDuration()); - } - }); - alert.setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface arg0) { - done.onCancel(); - } - }); - alert.show(); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/locale/LocaleReceiver.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/locale/LocaleReceiver.java deleted file mode 100644 index 9c51720..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/locale/LocaleReceiver.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.locale; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.util.Log; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.IntentBuilders; - -import java.io.File; - -public class LocaleReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - - final File script = - new File(intent.getBundleExtra(com.twofortyfouram.locale.platform.Intent.EXTRA_BUNDLE) - .getString(Constants.EXTRA_SCRIPT_PATH)); - Log.v("LocaleReceiver", "Locale initiated launch of " + script); - Intent launchIntent; - if (intent.getBooleanExtra(Constants.EXTRA_LAUNCH_IN_BACKGROUND, false)) { - launchIntent = IntentBuilders.buildStartInBackgroundIntent(script); - } else { - launchIntent = IntentBuilders.buildStartInTerminalIntent(script); - } - launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(launchIntent); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ApiProvider.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ApiProvider.java deleted file mode 100644 index 5bc1754..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ApiProvider.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.provider; - -import android.app.SearchManager; -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.UriMatcher; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.provider.BaseColumns; - -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.rpc.MethodDescriptor; -import com.googlecode.android_scripting.rpc.Rpc; -import com.googlecode.android_scripting.rpc.RpcDeprecated; -import com.googlecode.android_scripting.rpc.RpcMinSdk; - -import java.lang.reflect.Method; -import java.util.Collection; - -public class ApiProvider extends ContentProvider { - - public static final String SINGLE_MIME = "vnd.android.cursor.item/vnd.sl4a.api"; - - private static final int SUGGESTIONS_ID = 1; - - public static final String AUTHORITY = ApiProvider.class.getName().toLowerCase(); - public static final String SUGGESTIONS = "searchSuggestions/*/*"; - - private final UriMatcher mUriMatcher; - private final Collection<MethodDescriptor> mMethodDescriptors; - - public ApiProvider() { - mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - mUriMatcher.addURI(AUTHORITY, SUGGESTIONS, SUGGESTIONS_ID); - mMethodDescriptors = - Collections2.filter(FacadeConfiguration.collectMethodDescriptors(), - new Predicate<MethodDescriptor>() { - @Override - public boolean apply(MethodDescriptor descriptor) { - Method method = descriptor.getMethod(); - if (method.isAnnotationPresent(RpcDeprecated.class)) { - return false; - } else if (method.isAnnotationPresent(RpcMinSdk.class)) { - int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value(); - if (FacadeConfiguration.getSdkLevel() < requiredSdkLevel) { - return false; - } - } - return true; - } - }); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - return 0; - } - - @Override - public String getType(Uri uri) { - return SINGLE_MIME; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - return null; - } - - @Override - public boolean onCreate() { - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - switch (mUriMatcher.match(uri)) { - case SUGGESTIONS_ID: - String query = uri.getLastPathSegment().toLowerCase(); - return querySearchSuggestions(query); - } - return null; - } - - private Cursor querySearchSuggestions(String query) { - String[] columns = - { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_QUERY }; - MatrixCursor cursor = new MatrixCursor(columns); - int index = 0; - for (MethodDescriptor descriptor : mMethodDescriptors) { - String name = descriptor.getMethod().getName(); - if (!name.toLowerCase().contains(query)) { - continue; - } - String description = descriptor.getMethod().getAnnotation(Rpc.class).description(); - description = description.replaceAll("\\s+", " "); - Object[] row = { index, name, description, name }; - cursor.addRow(row); - ++index; - } - return cursor; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - return 0; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ScriptProvider.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ScriptProvider.java deleted file mode 100644 index 0f16e0d..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/ScriptProvider.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.provider; - -import android.app.SearchManager; -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.UriMatcher; -import android.content.Intent.ShortcutIconResource; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.provider.BaseColumns; -import android.provider.LiveFolders; - -import com.googlecode.android_scripting.FeaturedInterpreters; -import com.googlecode.android_scripting.IntentBuilders; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptStorageAdapter; -import com.googlecode.android_scripting.interpreter.Interpreter; -import com.googlecode.android_scripting.interpreter.InterpreterConfiguration; -import com.googlecode.android_scripting.interpreter.InterpreterConstants; - -import java.io.File; - -public class ScriptProvider extends ContentProvider { - - public static final String SINGLE_MIME = "vnd.android.cursor.item/vnd.sl4a.script"; - public static final String MULTIPLE_MIME = "vnd.android.cursor.dir/vnd.sl4a.script"; - - private static final int LIVEFOLDER_ID = 1; - private static final int SUGGESTIONS_ID = 2; - - public static final String AUTHORITY = ScriptProvider.class.getName().toLowerCase(); - public static final String LIVEFOLDER = "liveFolder"; - public static final String SUGGESTIONS = "searchSuggestions/*/*"; - - private final UriMatcher mUriMatcher; - - private Context mContext; - private InterpreterConfiguration mConfiguration; - - public ScriptProvider() { - mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - mUriMatcher.addURI(AUTHORITY, LIVEFOLDER, LIVEFOLDER_ID); - mUriMatcher.addURI(AUTHORITY, SUGGESTIONS, SUGGESTIONS_ID); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - return 0; - } - - @Override - public String getType(Uri uri) { - if (uri.getLastPathSegment().equals("scripts")) { - return MULTIPLE_MIME; - } - return SINGLE_MIME; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - return null; - } - - @Override - public boolean onCreate() { - mContext = getContext(); - mConfiguration = new InterpreterConfiguration(mContext); - mConfiguration.startDiscovering(); - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - switch (mUriMatcher.match(uri)) { - case LIVEFOLDER_ID: - return queryLiveFolder(); - case SUGGESTIONS_ID: - String query = uri.getLastPathSegment().toLowerCase(); - return querySearchSuggestions(query); - default: - return null; - } - } - - private Cursor querySearchSuggestions(String query) { - String[] columns = - { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_ICON_2, - SearchManager.SUGGEST_COLUMN_QUERY, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID }; - MatrixCursor cursor = new MatrixCursor(columns); - int index = 0; - for (File script : ScriptStorageAdapter.listExecutableScripts(null, mConfiguration)) { - String scriptName = script.getName().toLowerCase(); - if (!scriptName.contains(query)) { - continue; - } - Interpreter interpreter = mConfiguration.getInterpreterForScript(scriptName); - String secondLine = interpreter.getNiceName(); - int icon = FeaturedInterpreters.getInterpreterIcon(mContext, interpreter.getExtension()); - Object[] row = - { index, scriptName, secondLine, icon, scriptName, - SearchManager.SUGGEST_NEVER_MAKE_SHORTCUT }; - cursor.addRow(row); - ++index; - } - return cursor; - } - - private Cursor queryLiveFolder() { - String[] columns = - { BaseColumns._ID, LiveFolders.NAME, LiveFolders.INTENT, LiveFolders.ICON_RESOURCE, - LiveFolders.ICON_PACKAGE, LiveFolders.DESCRIPTION }; - MatrixCursor cursor = new MatrixCursor(columns); - int index = 0; - for (File script : ScriptStorageAdapter.listExecutableScriptsRecursively(null, mConfiguration)) { - int iconId = 0; - if (script.isDirectory()) { - iconId = R.drawable.folder; - } else { - iconId = FeaturedInterpreters.getInterpreterIcon(mContext, script.getName()); - if (iconId == 0) { - iconId = R.drawable.sl4a_logo_32; - } - } - ShortcutIconResource icon = ShortcutIconResource.fromContext(mContext, iconId); - Intent intent = IntentBuilders.buildStartInBackgroundIntent(script); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - String description = script.getAbsolutePath(); - if (description.startsWith(InterpreterConstants.SCRIPTS_ROOT)) { - description = description.replaceAll(InterpreterConstants.SCRIPTS_ROOT, "scripts/"); - } - Object[] row = - { index, script.getName(), intent.toURI(), icon.resourceName, icon.packageName, - description }; - cursor.addRow(row); - ++index; - } - return cursor; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - return 0; - } - -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/TelephonyTestProvider.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/TelephonyTestProvider.java deleted file mode 100644 index 2ab7c24..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/provider/TelephonyTestProvider.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.provider; - -import android.content.ContentProvider; -import android.content.ContentValues; -import android.database.Cursor; -import android.net.Uri; -import android.os.ParcelFileDescriptor; -import android.text.TextUtils; - -import java.io.File; -import java.io.FileReader; -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; - -import com.googlecode.android_scripting.Log; - -/** - * A simple provider to send MMS PDU to platform MMS service - */ -public class TelephonyTestProvider extends ContentProvider { - - public static final String AUTHORITY = "telephonytestauthority"; - - private final boolean DBG = false; - - @Override - public boolean onCreate() { - if(DBG) Log.d("TelephonTestProvider Successfully created!"); - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - // Not supported - return null; - } - - @Override - public String getType(Uri uri) { - // Not supported - return null; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - // Not supported - return null; - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - // Not supported - return 0; - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - // Not supported - return 0; - } - - @Override - public ParcelFileDescriptor openFile(Uri uri, String fileMode) throws FileNotFoundException { - Log.d(String.format("Entered ParcelFileDescriptor: Uri(%s), Mode(%s)", uri.toString(), - fileMode)); - File file = new File(getContext().getCacheDir(), uri.getPath()); - file.setReadable(true); - - Log.d(String.format("Looking for file at %s", getContext().getCacheDir() + uri.getPath())); - int mode = (TextUtils.equals(fileMode, "r") ? ParcelFileDescriptor.MODE_READ_ONLY : - ParcelFileDescriptor.MODE_WRITE_ONLY - | ParcelFileDescriptor.MODE_TRUNCATE - | ParcelFileDescriptor.MODE_CREATE); - - try { - ParcelFileDescriptor descriptor = ParcelFileDescriptor.open(file, mode); - - if(DBG) { - try { - BufferedReader br = new BufferedReader(new - FileReader(descriptor.getFileDescriptor())); - String line = null; - while ((line = br.readLine()) != null) { - Log.d("MMS:" + line); - } - } catch (IOException e) { - } - } - - return descriptor; - } catch (FileNotFoundException fnf) { - Log.e(fnf); - return null; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/FacadeService.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/FacadeService.java deleted file mode 100644 index 7ca4e18..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/FacadeService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.googlecode.android_scripting.service; - -import android.app.Service; -import android.content.Intent; -import android.os.HandlerThread; -import android.os.IBinder; -import android.os.Messenger; - -import com.googlecode.android_scripting.facade.FacadeConfiguration; -import com.googlecode.android_scripting.facade.FacadeManagerFactory; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; - -/** - * FacadeService exposes SL4A's Facade methods through a {@link Service} so - * they can be invoked from third-party apps. - * <p> - * Example binding code:<br> - * {@code - * Intent intent = new Intent(); - * intent.setPackage("com.googlecode.android_scripting"); - * intent.setAction("com.googlecode.android_scripting.service.FacadeService.ACTION_BIND"); - * sl4aService = bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - * } - * Example using the service:<br> - * {@code - * Bundle sl4aBundle = new Bundle; - * bundle.putString{"sl4aMethod", "makeToast"}; - * bundle.putString{"message", "Hello World!"}; - * Message msg = Message.obtain(null, SL4A_ACTION); - * msg.setData(sl4aBundle); - * msg.replyTo = myReplyHandler; // Set a Messenger if you need the response - * mSl4aService.send(msg); - * } - * <p> - * For more info on binding a {@link Service} using a {@link Messenger} please - * refer to Android's public developer documentation. - */ -public class FacadeService extends Service { - - private RpcReceiverManagerFactory rpcReceiverManagerFactory; - - @Override - public IBinder onBind(Intent intent) { - if (rpcReceiverManagerFactory == null) { - rpcReceiverManagerFactory = - new FacadeManagerFactory(FacadeConfiguration.getSdkLevel(), this, null, - FacadeConfiguration.getFacadeClasses()); - } - HandlerThread handlerThread = new HandlerThread("MessageHandlerThread"); - handlerThread.start(); - Messenger aMessenger = new Messenger(new MessageHandler(handlerThread, - rpcReceiverManagerFactory)); - return aMessenger.getBinder(); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/MessageHandler.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/MessageHandler.java deleted file mode 100644 index 8c6fb3f..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/service/MessageHandler.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.googlecode.android_scripting.service; - -import android.annotation.TargetApi; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Message; -import android.os.RemoteException; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.jsonrpc.JsonRpcResult; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; -import com.googlecode.android_scripting.rpc.MethodDescriptor; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Class responsible for Handling messages that came through the FacadeService - * interface. - * <br> - * Please refer to {@link FacadeService} for details on how to use. - */ -@TargetApi(3) -public class MessageHandler extends Handler { - - private static final int SL4A_ACTION = 0; - private static final int DEFAULT_SENDING_ID = 0; - - // Android sets this to -1 when the message is not sent by a Messenger. - // see http://developer.android.com/reference/android/os/Message.html#sendingUid - private static final int DEFAULT_UNSET_SENDING_ID = 1; - - // Keys for the Bundles. - private static final String SL4A_METHOD = "sl4aMethod"; - private static final String SL4A_RESULT = "sl4aResult"; - - private final RpcReceiverManagerFactory mRpcReceiverManagerFactory; - - public MessageHandler(HandlerThread handlerThread, - RpcReceiverManagerFactory rpcReceiverManagerFactory) { - super(handlerThread.getLooper()); - this.mRpcReceiverManagerFactory = rpcReceiverManagerFactory; - } - - /** - * Handles messages for the service. It does this via the same mechanism used - * for RPCs through RpcManagers. - * - * @param message The message that contains the method and parameters to - * execute. - */ - @Override - public void handleMessage(Message message) { - Log.d("Handling Remote request"); - int senderId = message.sendingUid == DEFAULT_UNSET_SENDING_ID ? - DEFAULT_SENDING_ID : message.sendingUid; - if (message.what == SL4A_ACTION) { - RpcReceiverManager receiverManager; - if (mRpcReceiverManagerFactory.getRpcReceiverManagers().containsKey(senderId)) { - receiverManager = mRpcReceiverManagerFactory.getRpcReceiverManagers().get(senderId); - } else { - receiverManager = mRpcReceiverManagerFactory.create(senderId); - } - Bundle sl4aRequest = message.getData(); - String method = sl4aRequest.getString(SL4A_METHOD); - if (method == null || "".equals(method)) { - Log.e("No SL4A method specified on the Bundle. Specify one with " - + SL4A_METHOD); - return; - } - MethodDescriptor rpc = receiverManager.getMethodDescriptor(method); - if (rpc == null) { - Log.e("Unknown RPC: \"" + method + "\""); - return; - } - try { - Log.d("Invoking method " + rpc.getName()); - Object result = rpc.invoke(receiverManager, sl4aRequest); - // Only return a result if we were passed a Messenger. Otherwise assume - // client did not care for the response. - if (message.replyTo != null) { - Message reply = Message.obtain(); - Bundle sl4aResponse = new Bundle(); - putResult(senderId, result, sl4aResponse); - reply.setData(sl4aResponse); - message.replyTo.send(reply); - } - } catch (RemoteException e) { - Log.e("Could not send reply back to client", e); - } catch (Throwable t) { - Log.e("Exception while executing sl4a method", t); - } - } - } - - private void putResult(int id, Object result, Bundle reply) { - JSONObject json; - try { - if (result instanceof Throwable) { - json = JsonRpcResult.error(id, (Throwable) result); - } else { - json = JsonRpcResult.result(id, result); - } - } catch (JSONException e) { - // There was an error converting the result to JSON. This shouldn't - // happen normally. - Log.e("Caught exception when filling JSON result.", e); - reply.putString(SL4A_RESULT, e.toString()); - return; - } - Log.d("Returning result: " + json.toString()); - reply.putString(SL4A_RESULT, json.toString()); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/DurationPicker.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/DurationPicker.java deleted file mode 100644 index 7652471..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/DurationPicker.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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 com.googlecode.android_scripting.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.widget.FrameLayout; - -import com.googlecode.android_scripting.R; - -/** - * A view for selecting the a duration using days, hours, minutes, and seconds. - */ -public class DurationPicker extends FrameLayout { - - private int mCurrentDay = 0; // 0-99 - private int mCurrentHour = 0; // 0-23 - private int mCurrentMinute = 0; // 0-59 - private int mCurrentSecond = 0; // 0-59 - - private final NumberPicker mDayPicker; - private final NumberPicker mHourPicker; - private final NumberPicker mMinutePicker; - private final NumberPicker mSecondPicker; - - public DurationPicker(Context context) { - this(context, null); - } - - public DurationPicker(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public DurationPicker(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - LayoutInflater inflater = - (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - inflater.inflate(R.layout.duration_picker, this, true); - - mDayPicker = (NumberPicker) findViewById(R.id.day); - mDayPicker.setRange(0, 99); - mDayPicker.setSpeed(100); - // mHourPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); - mDayPicker.setOnChangeListener(new NumberPicker.OnChangedListener() { - public void onChanged(NumberPicker spinner, int oldVal, int newVal) { - mCurrentDay = newVal; - } - }); - - mHourPicker = (NumberPicker) findViewById(R.id.hour); - mHourPicker.setRange(0, 23); - mHourPicker.setSpeed(100); - // mHourPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); - mHourPicker.setOnChangeListener(new NumberPicker.OnChangedListener() { - public void onChanged(NumberPicker spinner, int oldVal, int newVal) { - mCurrentHour = newVal; - } - }); - - mMinutePicker = (NumberPicker) findViewById(R.id.minute); - mMinutePicker.setRange(0, 59); - mMinutePicker.setSpeed(100); - mMinutePicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); - mMinutePicker.setOnChangeListener(new NumberPicker.OnChangedListener() { - public void onChanged(NumberPicker spinner, int oldVal, int newVal) { - mCurrentMinute = newVal; - } - }); - - mSecondPicker = (NumberPicker) findViewById(R.id.second); - mSecondPicker.setRange(0, 59); - mSecondPicker.setSpeed(100); - mSecondPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); - mSecondPicker.setOnChangeListener(new NumberPicker.OnChangedListener() { - public void onChanged(NumberPicker spinner, int oldVal, int newVal) { - mCurrentSecond = newVal; - } - }); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - mDayPicker.setEnabled(enabled); - mHourPicker.setEnabled(enabled); - mMinutePicker.setEnabled(enabled); - mSecondPicker.setEnabled(enabled); - } - - /** - * Returns the current day. - */ - public Integer getCurrentDay() { - return mCurrentDay; - } - - /** - * Set the current hour. - */ - public void setCurrentDay(Integer currentDay) { - mCurrentDay = currentDay; - updateDayDisplay(); - } - - /** - * Returns the current hour. - */ - public Integer getCurrentHour() { - return mCurrentHour; - } - - /** - * Set the current hour. - */ - public void setCurrentHour(Integer currentHour) { - mCurrentHour = currentHour; - updateHourDisplay(); - } - - /** - * Returns the current minute. - */ - public Integer getCurrentMinute() { - return mCurrentMinute; - } - - /** - * Set the current minute. - */ - public void setCurrentMinute(Integer currentMinute) { - mCurrentMinute = currentMinute; - updateMinuteDisplay(); - } - - /** - * Returns the current second. - */ - public Integer getCurrentSecond() { - return mCurrentSecond; - } - - /** - * Set the current minute. - */ - public void setCurrentSecond(Integer currentSecond) { - mCurrentSecond = currentSecond; - updateSecondDisplay(); - } - - /** - * Set the state of the spinners appropriate to the current day. - */ - private void updateDayDisplay() { - int currentDay = mCurrentDay; - mDayPicker.setCurrent(currentDay); - } - - /** - * Set the state of the spinners appropriate to the current hour. - */ - private void updateHourDisplay() { - int currentHour = mCurrentHour; - mHourPicker.setCurrent(currentHour); - } - - /** - * Set the state of the spinners appropriate to the current minute. - */ - private void updateMinuteDisplay() { - mMinutePicker.setCurrent(mCurrentMinute); - } - - /** - * Set the state of the spinners appropriate to the current minute. - */ - private void updateSecondDisplay() { - mSecondPicker.setCurrent(mCurrentSecond); - } - - /** - * Returns the duration in seconds. - */ - public double getDuration() { - // The text views may still have focus so clear theirs focus which will trigger the on focus - // changed and any typed values to be pulled. - mDayPicker.clearFocus(); - mHourPicker.clearFocus(); - mMinutePicker.clearFocus(); - mSecondPicker.clearFocus(); - return (((((mCurrentDay * 24l + mCurrentHour) * 60) + mCurrentMinute) * 60) + mCurrentSecond); - } - - /** - * Sets the duration in milliseconds. - * - * @return - */ - public void setDuration(long duration) { - double seconds = duration / 1000; - double minutes = seconds / 60; - seconds = seconds % 60; - double hours = minutes / 60; - minutes = minutes % 60; - double days = hours / 24; - hours = hours % 24; - - setCurrentDay((int) days); - setCurrentHour((int) hours); - setCurrentMinute((int) minutes); - setCurrentSecond((int) seconds); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPicker.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPicker.java deleted file mode 100644 index 061eacd..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPicker.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * 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 com.googlecode.android_scripting.widget; - -import android.content.Context; -import android.os.Handler; -import android.text.InputFilter; -import android.text.InputType; -import android.text.Spanned; -import android.text.method.NumberKeyListener; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.view.View.OnLongClickListener; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.googlecode.android_scripting.R; - -public class NumberPicker extends LinearLayout implements OnClickListener, OnFocusChangeListener, - OnLongClickListener { - - public interface OnChangedListener { - void onChanged(NumberPicker picker, int oldVal, int newVal); - } - - public interface Formatter { - String toString(int value); - } - - /* - * Use a custom NumberPicker formatting callback to use two-digit minutes strings like "01". - * Keeping a static formatter etc. is the most efficient way to do this; it avoids creating - * temporary objects on every call to format(). - */ - public static final NumberPicker.Formatter TWO_DIGIT_FORMATTER = new NumberPicker.Formatter() { - final StringBuilder mBuilder = new StringBuilder(); - final java.util.Formatter mFmt = new java.util.Formatter(mBuilder); - final Object[] mArgs = new Object[1]; - - public String toString(int value) { - mArgs[0] = value; - mBuilder.delete(0, mBuilder.length()); - mFmt.format("%02d", mArgs); - return mFmt.toString(); - } - }; - - private final Handler mHandler; - private final Runnable mRunnable = new Runnable() { - public void run() { - if (mIncrement) { - changeCurrent(mCurrent + 1); - mHandler.postDelayed(this, mSpeed); - } else if (mDecrement) { - changeCurrent(mCurrent - 1); - mHandler.postDelayed(this, mSpeed); - } - } - }; - - private final EditText mText; - private final InputFilter mNumberInputFilter; - - private String[] mDisplayedValues; - private int mStart; - private int mEnd; - private int mCurrent; - private int mPrevious; - private OnChangedListener mListener; - private Formatter mFormatter; - private long mSpeed = 300; - - private boolean mIncrement; - private boolean mDecrement; - - public NumberPicker(Context context) { - this(context, null); - } - - public NumberPicker(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public NumberPicker(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - setOrientation(VERTICAL); - LayoutInflater inflater = - (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - inflater.inflate(R.layout.number_picker, this, true); - mHandler = new Handler(); - InputFilter inputFilter = new NumberPickerInputFilter(); - mNumberInputFilter = new NumberRangeKeyListener(); - mIncrementButton = (NumberPickerButton) findViewById(R.id.increment); - mIncrementButton.setOnClickListener(this); - mIncrementButton.setOnLongClickListener(this); - mIncrementButton.setNumberPicker(this); - mDecrementButton = (NumberPickerButton) findViewById(R.id.decrement); - mDecrementButton.setOnClickListener(this); - mDecrementButton.setOnLongClickListener(this); - mDecrementButton.setNumberPicker(this); - - mText = (EditText) findViewById(R.id.timepicker_input); - mText.setOnFocusChangeListener(this); - mText.setFilters(new InputFilter[] { inputFilter }); - mText.setRawInputType(InputType.TYPE_CLASS_NUMBER); - - if (!isEnabled()) { - setEnabled(false); - } - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - mIncrementButton.setEnabled(enabled); - mDecrementButton.setEnabled(enabled); - mText.setEnabled(enabled); - } - - public void setOnChangeListener(OnChangedListener listener) { - mListener = listener; - } - - public void setFormatter(Formatter formatter) { - mFormatter = formatter; - } - - /** - * Set the range of numbers allowed for the number picker. The current value will be automatically - * set to the start. - * - * @param start - * the start of the range (inclusive) - * @param end - * the end of the range (inclusive) - */ - public void setRange(int start, int end) { - mStart = start; - mEnd = end; - mCurrent = start; - updateView(); - } - - /** - * Set the range of numbers allowed for the number picker. The current value will be automatically - * set to the start. Also provide a mapping for values used to display to the user. - * - * @param start - * the start of the range (inclusive) - * @param end - * the end of the range (inclusive) - * @param displayedValues - * the values displayed to the user. - */ - public void setRange(int start, int end, String[] displayedValues) { - mDisplayedValues = displayedValues; - mStart = start; - mEnd = end; - mCurrent = start; - updateView(); - } - - public void setCurrent(int current) { - mCurrent = current; - updateView(); - } - - /** - * The speed (in milliseconds) at which the numbers will scroll when the the +/- buttons are - * longpressed. Default is 300ms. - */ - public void setSpeed(long speed) { - mSpeed = speed; - } - - public void onClick(View v) { - validateInput(mText); - if (!mText.hasFocus()) { - mText.requestFocus(); - } - - // now perform the increment/decrement - if (R.id.increment == v.getId()) { - changeCurrent(mCurrent + 1); - } else if (R.id.decrement == v.getId()) { - changeCurrent(mCurrent - 1); - } - } - - private String formatNumber(int value) { - return (mFormatter != null) ? mFormatter.toString(value) : String.valueOf(value); - } - - private void changeCurrent(int current) { - - // Wrap around the values if we go past the start or end - if (current > mEnd) { - current = mStart; - } else if (current < mStart) { - current = mEnd; - } - mPrevious = mCurrent; - mCurrent = current; - notifyChange(); - updateView(); - } - - private void notifyChange() { - if (mListener != null) { - mListener.onChanged(this, mPrevious, mCurrent); - } - } - - private void updateView() { - - /* - * If we don't have displayed values then use the current number else find the correct value in - * the displayed values for the current number. - */ - if (mDisplayedValues == null) { - mText.setText(formatNumber(mCurrent)); - } else { - mText.setText(mDisplayedValues[mCurrent - mStart]); - } - mText.setSelection(mText.getText().length()); - } - - private void validateCurrentView(CharSequence str) { - int val = getSelectedPos(str.toString()); - if ((val >= mStart) && (val <= mEnd)) { - mPrevious = mCurrent; - mCurrent = val; - notifyChange(); - } - updateView(); - } - - public void onFocusChange(View v, boolean hasFocus) { - - /* - * When focus is lost check that the text field has valid values. - */ - if (!hasFocus) { - validateInput(v); - } - } - - private void validateInput(View v) { - String str = String.valueOf(((TextView) v).getText()); - if ("".equals(str)) { - - // Restore to the old value as we don't allow empty values - updateView(); - } else { - - // Check the new value and ensure it's in range - validateCurrentView(str); - } - } - - /** - * We start the long click here but rely on the {@link NumberPickerButton} to inform us when the - * long click has ended. - */ - public boolean onLongClick(View v) { - - /* - * The text view may still have focus so clear it's focus which will trigger the on focus - * changed and any typed values to be pulled. - */ - mText.clearFocus(); - - if (R.id.increment == v.getId()) { - mIncrement = true; - mHandler.post(mRunnable); - } else if (R.id.decrement == v.getId()) { - mDecrement = true; - mHandler.post(mRunnable); - } - return true; - } - - public void cancelIncrement() { - mIncrement = false; - } - - public void cancelDecrement() { - mDecrement = false; - } - - private static final char[] DIGIT_CHARACTERS = - new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; - - private final NumberPickerButton mIncrementButton; - private final NumberPickerButton mDecrementButton; - - private class NumberPickerInputFilter implements InputFilter { - public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, - int dend) { - if (mDisplayedValues == null) { - return mNumberInputFilter.filter(source, start, end, dest, dstart, dend); - } - CharSequence filtered = String.valueOf(source.subSequence(start, end)); - String result = - String.valueOf(dest.subSequence(0, dstart)) + filtered - + dest.subSequence(dend, dest.length()); - String str = String.valueOf(result).toLowerCase(); - for (String val : mDisplayedValues) { - val = val.toLowerCase(); - if (val.startsWith(str)) { - return filtered; - } - } - return ""; - } - } - - private class NumberRangeKeyListener extends NumberKeyListener { - - // XXX This doesn't allow for range limits when controlled by a - // soft input method! - public int getInputType() { - return InputType.TYPE_CLASS_NUMBER; - } - - @Override - protected char[] getAcceptedChars() { - return DIGIT_CHARACTERS; - } - - @Override - public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, - int dend) { - - CharSequence filtered = super.filter(source, start, end, dest, dstart, dend); - if (filtered == null) { - filtered = source.subSequence(start, end); - } - - String result = - String.valueOf(dest.subSequence(0, dstart)) + filtered - + dest.subSequence(dend, dest.length()); - - if ("".equals(result)) { - return result; - } - int val = getSelectedPos(result); - - /* - * Ensure the user can't type in a value greater than the max allowed. We have to allow less - * than min as the user might want to delete some numbers and then type a new number. - */ - if (val > mEnd) { - return ""; - } else { - return filtered; - } - } - } - - private int getSelectedPos(String str) { - if (mDisplayedValues == null) { - return Integer.parseInt(str); - } else { - for (int i = 0; i < mDisplayedValues.length; i++) { - - /* Don't force the user to type in jan when ja will do */ - str = str.toLowerCase(); - if (mDisplayedValues[i].toLowerCase().startsWith(str)) { - return mStart + i; - } - } - - /* - * The user might have typed in a number into the month field i.e. 10 instead of OCT so - * support that too. - */ - try { - return Integer.parseInt(str); - } catch (NumberFormatException e) { - - /* Ignore as if it's not a number we don't care */ - } - } - return mStart; - } - - /** - * @return the current value. - */ - public int getCurrent() { - return mCurrent; - } -}
\ No newline at end of file diff --git a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPickerButton.java b/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPickerButton.java deleted file mode 100644 index cb8d184..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/widget/NumberPickerButton.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * 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 com.googlecode.android_scripting.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.widget.ImageButton; - -import com.googlecode.android_scripting.R; - -/** - * This class exists purely to cancel long click events. - */ -public class NumberPickerButton extends ImageButton { - - private NumberPicker mNumberPicker; - - public NumberPickerButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public NumberPickerButton(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public NumberPickerButton(Context context) { - super(context); - } - - public void setNumberPicker(NumberPicker picker) { - mNumberPicker = picker; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - cancelLongpressIfRequired(event); - return super.onTouchEvent(event); - } - - @Override - public boolean onTrackballEvent(MotionEvent event) { - cancelLongpressIfRequired(event); - return super.onTrackballEvent(event); - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) || (keyCode == KeyEvent.KEYCODE_ENTER)) { - cancelLongpress(); - } - return super.onKeyUp(keyCode, event); - } - - private void cancelLongpressIfRequired(MotionEvent event) { - if ((event.getAction() == MotionEvent.ACTION_CANCEL) - || (event.getAction() == MotionEvent.ACTION_UP)) { - cancelLongpress(); - } - } - - private void cancelLongpress() { - if (R.id.increment == getId()) { - mNumberPicker.cancelIncrement(); - } else if (R.id.decrement == getId()) { - mNumberPicker.cancelDecrement(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/Precomposer.java b/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/Precomposer.java deleted file mode 100644 index edad64c..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/Precomposer.java +++ /dev/null @@ -1,1052 +0,0 @@ -/* - * 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 de.mud.terminal; - -/** - * @author Kenny Root - * This data was taken from xterm's precompose.c - */ -public class Precomposer { - public final static char precompositions[][] = { - { 0x226E, 0x003C, 0x0338}, - { 0x2260, 0x003D, 0x0338}, - { 0x226F, 0x003E, 0x0338}, - { 0x00C0, 0x0041, 0x0300}, - { 0x00C1, 0x0041, 0x0301}, - { 0x00C2, 0x0041, 0x0302}, - { 0x00C3, 0x0041, 0x0303}, - { 0x0100, 0x0041, 0x0304}, - { 0x0102, 0x0041, 0x0306}, - { 0x0226, 0x0041, 0x0307}, - { 0x00C4, 0x0041, 0x0308}, - { 0x1EA2, 0x0041, 0x0309}, - { 0x00C5, 0x0041, 0x030A}, - { 0x01CD, 0x0041, 0x030C}, - { 0x0200, 0x0041, 0x030F}, - { 0x0202, 0x0041, 0x0311}, - { 0x1EA0, 0x0041, 0x0323}, - { 0x1E00, 0x0041, 0x0325}, - { 0x0104, 0x0041, 0x0328}, - { 0x1E02, 0x0042, 0x0307}, - { 0x1E04, 0x0042, 0x0323}, - { 0x1E06, 0x0042, 0x0331}, - { 0x0106, 0x0043, 0x0301}, - { 0x0108, 0x0043, 0x0302}, - { 0x010A, 0x0043, 0x0307}, - { 0x010C, 0x0043, 0x030C}, - { 0x00C7, 0x0043, 0x0327}, - { 0x1E0A, 0x0044, 0x0307}, - { 0x010E, 0x0044, 0x030C}, - { 0x1E0C, 0x0044, 0x0323}, - { 0x1E10, 0x0044, 0x0327}, - { 0x1E12, 0x0044, 0x032D}, - { 0x1E0E, 0x0044, 0x0331}, - { 0x00C8, 0x0045, 0x0300}, - { 0x00C9, 0x0045, 0x0301}, - { 0x00CA, 0x0045, 0x0302}, - { 0x1EBC, 0x0045, 0x0303}, - { 0x0112, 0x0045, 0x0304}, - { 0x0114, 0x0045, 0x0306}, - { 0x0116, 0x0045, 0x0307}, - { 0x00CB, 0x0045, 0x0308}, - { 0x1EBA, 0x0045, 0x0309}, - { 0x011A, 0x0045, 0x030C}, - { 0x0204, 0x0045, 0x030F}, - { 0x0206, 0x0045, 0x0311}, - { 0x1EB8, 0x0045, 0x0323}, - { 0x0228, 0x0045, 0x0327}, - { 0x0118, 0x0045, 0x0328}, - { 0x1E18, 0x0045, 0x032D}, - { 0x1E1A, 0x0045, 0x0330}, - { 0x1E1E, 0x0046, 0x0307}, - { 0x01F4, 0x0047, 0x0301}, - { 0x011C, 0x0047, 0x0302}, - { 0x1E20, 0x0047, 0x0304}, - { 0x011E, 0x0047, 0x0306}, - { 0x0120, 0x0047, 0x0307}, - { 0x01E6, 0x0047, 0x030C}, - { 0x0122, 0x0047, 0x0327}, - { 0x0124, 0x0048, 0x0302}, - { 0x1E22, 0x0048, 0x0307}, - { 0x1E26, 0x0048, 0x0308}, - { 0x021E, 0x0048, 0x030C}, - { 0x1E24, 0x0048, 0x0323}, - { 0x1E28, 0x0048, 0x0327}, - { 0x1E2A, 0x0048, 0x032E}, - { 0x00CC, 0x0049, 0x0300}, - { 0x00CD, 0x0049, 0x0301}, - { 0x00CE, 0x0049, 0x0302}, - { 0x0128, 0x0049, 0x0303}, - { 0x012A, 0x0049, 0x0304}, - { 0x012C, 0x0049, 0x0306}, - { 0x0130, 0x0049, 0x0307}, - { 0x00CF, 0x0049, 0x0308}, - { 0x1EC8, 0x0049, 0x0309}, - { 0x01CF, 0x0049, 0x030C}, - { 0x0208, 0x0049, 0x030F}, - { 0x020A, 0x0049, 0x0311}, - { 0x1ECA, 0x0049, 0x0323}, - { 0x012E, 0x0049, 0x0328}, - { 0x1E2C, 0x0049, 0x0330}, - { 0x0134, 0x004A, 0x0302}, - { 0x1E30, 0x004B, 0x0301}, - { 0x01E8, 0x004B, 0x030C}, - { 0x1E32, 0x004B, 0x0323}, - { 0x0136, 0x004B, 0x0327}, - { 0x1E34, 0x004B, 0x0331}, - { 0x0139, 0x004C, 0x0301}, - { 0x013D, 0x004C, 0x030C}, - { 0x1E36, 0x004C, 0x0323}, - { 0x013B, 0x004C, 0x0327}, - { 0x1E3C, 0x004C, 0x032D}, - { 0x1E3A, 0x004C, 0x0331}, - { 0x1E3E, 0x004D, 0x0301}, - { 0x1E40, 0x004D, 0x0307}, - { 0x1E42, 0x004D, 0x0323}, - { 0x01F8, 0x004E, 0x0300}, - { 0x0143, 0x004E, 0x0301}, - { 0x00D1, 0x004E, 0x0303}, - { 0x1E44, 0x004E, 0x0307}, - { 0x0147, 0x004E, 0x030C}, - { 0x1E46, 0x004E, 0x0323}, - { 0x0145, 0x004E, 0x0327}, - { 0x1E4A, 0x004E, 0x032D}, - { 0x1E48, 0x004E, 0x0331}, - { 0x00D2, 0x004F, 0x0300}, - { 0x00D3, 0x004F, 0x0301}, - { 0x00D4, 0x004F, 0x0302}, - { 0x00D5, 0x004F, 0x0303}, - { 0x014C, 0x004F, 0x0304}, - { 0x014E, 0x004F, 0x0306}, - { 0x022E, 0x004F, 0x0307}, - { 0x00D6, 0x004F, 0x0308}, - { 0x1ECE, 0x004F, 0x0309}, - { 0x0150, 0x004F, 0x030B}, - { 0x01D1, 0x004F, 0x030C}, - { 0x020C, 0x004F, 0x030F}, - { 0x020E, 0x004F, 0x0311}, - { 0x01A0, 0x004F, 0x031B}, - { 0x1ECC, 0x004F, 0x0323}, - { 0x01EA, 0x004F, 0x0328}, - { 0x1E54, 0x0050, 0x0301}, - { 0x1E56, 0x0050, 0x0307}, - { 0x0154, 0x0052, 0x0301}, - { 0x1E58, 0x0052, 0x0307}, - { 0x0158, 0x0052, 0x030C}, - { 0x0210, 0x0052, 0x030F}, - { 0x0212, 0x0052, 0x0311}, - { 0x1E5A, 0x0052, 0x0323}, - { 0x0156, 0x0052, 0x0327}, - { 0x1E5E, 0x0052, 0x0331}, - { 0x015A, 0x0053, 0x0301}, - { 0x015C, 0x0053, 0x0302}, - { 0x1E60, 0x0053, 0x0307}, - { 0x0160, 0x0053, 0x030C}, - { 0x1E62, 0x0053, 0x0323}, - { 0x0218, 0x0053, 0x0326}, - { 0x015E, 0x0053, 0x0327}, - { 0x1E6A, 0x0054, 0x0307}, - { 0x0164, 0x0054, 0x030C}, - { 0x1E6C, 0x0054, 0x0323}, - { 0x021A, 0x0054, 0x0326}, - { 0x0162, 0x0054, 0x0327}, - { 0x1E70, 0x0054, 0x032D}, - { 0x1E6E, 0x0054, 0x0331}, - { 0x00D9, 0x0055, 0x0300}, - { 0x00DA, 0x0055, 0x0301}, - { 0x00DB, 0x0055, 0x0302}, - { 0x0168, 0x0055, 0x0303}, - { 0x016A, 0x0055, 0x0304}, - { 0x016C, 0x0055, 0x0306}, - { 0x00DC, 0x0055, 0x0308}, - { 0x1EE6, 0x0055, 0x0309}, - { 0x016E, 0x0055, 0x030A}, - { 0x0170, 0x0055, 0x030B}, - { 0x01D3, 0x0055, 0x030C}, - { 0x0214, 0x0055, 0x030F}, - { 0x0216, 0x0055, 0x0311}, - { 0x01AF, 0x0055, 0x031B}, - { 0x1EE4, 0x0055, 0x0323}, - { 0x1E72, 0x0055, 0x0324}, - { 0x0172, 0x0055, 0x0328}, - { 0x1E76, 0x0055, 0x032D}, - { 0x1E74, 0x0055, 0x0330}, - { 0x1E7C, 0x0056, 0x0303}, - { 0x1E7E, 0x0056, 0x0323}, - { 0x1E80, 0x0057, 0x0300}, - { 0x1E82, 0x0057, 0x0301}, - { 0x0174, 0x0057, 0x0302}, - { 0x1E86, 0x0057, 0x0307}, - { 0x1E84, 0x0057, 0x0308}, - { 0x1E88, 0x0057, 0x0323}, - { 0x1E8A, 0x0058, 0x0307}, - { 0x1E8C, 0x0058, 0x0308}, - { 0x1EF2, 0x0059, 0x0300}, - { 0x00DD, 0x0059, 0x0301}, - { 0x0176, 0x0059, 0x0302}, - { 0x1EF8, 0x0059, 0x0303}, - { 0x0232, 0x0059, 0x0304}, - { 0x1E8E, 0x0059, 0x0307}, - { 0x0178, 0x0059, 0x0308}, - { 0x1EF6, 0x0059, 0x0309}, - { 0x1EF4, 0x0059, 0x0323}, - { 0x0179, 0x005A, 0x0301}, - { 0x1E90, 0x005A, 0x0302}, - { 0x017B, 0x005A, 0x0307}, - { 0x017D, 0x005A, 0x030C}, - { 0x1E92, 0x005A, 0x0323}, - { 0x1E94, 0x005A, 0x0331}, - { 0x00E0, 0x0061, 0x0300}, - { 0x00E1, 0x0061, 0x0301}, - { 0x00E2, 0x0061, 0x0302}, - { 0x00E3, 0x0061, 0x0303}, - { 0x0101, 0x0061, 0x0304}, - { 0x0103, 0x0061, 0x0306}, - { 0x0227, 0x0061, 0x0307}, - { 0x00E4, 0x0061, 0x0308}, - { 0x1EA3, 0x0061, 0x0309}, - { 0x00E5, 0x0061, 0x030A}, - { 0x01CE, 0x0061, 0x030C}, - { 0x0201, 0x0061, 0x030F}, - { 0x0203, 0x0061, 0x0311}, - { 0x1EA1, 0x0061, 0x0323}, - { 0x1E01, 0x0061, 0x0325}, - { 0x0105, 0x0061, 0x0328}, - { 0x1E03, 0x0062, 0x0307}, - { 0x1E05, 0x0062, 0x0323}, - { 0x1E07, 0x0062, 0x0331}, - { 0x0107, 0x0063, 0x0301}, - { 0x0109, 0x0063, 0x0302}, - { 0x010B, 0x0063, 0x0307}, - { 0x010D, 0x0063, 0x030C}, - { 0x00E7, 0x0063, 0x0327}, - { 0x1E0B, 0x0064, 0x0307}, - { 0x010F, 0x0064, 0x030C}, - { 0x1E0D, 0x0064, 0x0323}, - { 0x1E11, 0x0064, 0x0327}, - { 0x1E13, 0x0064, 0x032D}, - { 0x1E0F, 0x0064, 0x0331}, - { 0x00E8, 0x0065, 0x0300}, - { 0x00E9, 0x0065, 0x0301}, - { 0x00EA, 0x0065, 0x0302}, - { 0x1EBD, 0x0065, 0x0303}, - { 0x0113, 0x0065, 0x0304}, - { 0x0115, 0x0065, 0x0306}, - { 0x0117, 0x0065, 0x0307}, - { 0x00EB, 0x0065, 0x0308}, - { 0x1EBB, 0x0065, 0x0309}, - { 0x011B, 0x0065, 0x030C}, - { 0x0205, 0x0065, 0x030F}, - { 0x0207, 0x0065, 0x0311}, - { 0x1EB9, 0x0065, 0x0323}, - { 0x0229, 0x0065, 0x0327}, - { 0x0119, 0x0065, 0x0328}, - { 0x1E19, 0x0065, 0x032D}, - { 0x1E1B, 0x0065, 0x0330}, - { 0x1E1F, 0x0066, 0x0307}, - { 0x01F5, 0x0067, 0x0301}, - { 0x011D, 0x0067, 0x0302}, - { 0x1E21, 0x0067, 0x0304}, - { 0x011F, 0x0067, 0x0306}, - { 0x0121, 0x0067, 0x0307}, - { 0x01E7, 0x0067, 0x030C}, - { 0x0123, 0x0067, 0x0327}, - { 0x0125, 0x0068, 0x0302}, - { 0x1E23, 0x0068, 0x0307}, - { 0x1E27, 0x0068, 0x0308}, - { 0x021F, 0x0068, 0x030C}, - { 0x1E25, 0x0068, 0x0323}, - { 0x1E29, 0x0068, 0x0327}, - { 0x1E2B, 0x0068, 0x032E}, - { 0x1E96, 0x0068, 0x0331}, - { 0x00EC, 0x0069, 0x0300}, - { 0x00ED, 0x0069, 0x0301}, - { 0x00EE, 0x0069, 0x0302}, - { 0x0129, 0x0069, 0x0303}, - { 0x012B, 0x0069, 0x0304}, - { 0x012D, 0x0069, 0x0306}, - { 0x00EF, 0x0069, 0x0308}, - { 0x1EC9, 0x0069, 0x0309}, - { 0x01D0, 0x0069, 0x030C}, - { 0x0209, 0x0069, 0x030F}, - { 0x020B, 0x0069, 0x0311}, - { 0x1ECB, 0x0069, 0x0323}, - { 0x012F, 0x0069, 0x0328}, - { 0x1E2D, 0x0069, 0x0330}, - { 0x0135, 0x006A, 0x0302}, - { 0x01F0, 0x006A, 0x030C}, - { 0x1E31, 0x006B, 0x0301}, - { 0x01E9, 0x006B, 0x030C}, - { 0x1E33, 0x006B, 0x0323}, - { 0x0137, 0x006B, 0x0327}, - { 0x1E35, 0x006B, 0x0331}, - { 0x013A, 0x006C, 0x0301}, - { 0x013E, 0x006C, 0x030C}, - { 0x1E37, 0x006C, 0x0323}, - { 0x013C, 0x006C, 0x0327}, - { 0x1E3D, 0x006C, 0x032D}, - { 0x1E3B, 0x006C, 0x0331}, - { 0x1E3F, 0x006D, 0x0301}, - { 0x1E41, 0x006D, 0x0307}, - { 0x1E43, 0x006D, 0x0323}, - { 0x01F9, 0x006E, 0x0300}, - { 0x0144, 0x006E, 0x0301}, - { 0x00F1, 0x006E, 0x0303}, - { 0x1E45, 0x006E, 0x0307}, - { 0x0148, 0x006E, 0x030C}, - { 0x1E47, 0x006E, 0x0323}, - { 0x0146, 0x006E, 0x0327}, - { 0x1E4B, 0x006E, 0x032D}, - { 0x1E49, 0x006E, 0x0331}, - { 0x00F2, 0x006F, 0x0300}, - { 0x00F3, 0x006F, 0x0301}, - { 0x00F4, 0x006F, 0x0302}, - { 0x00F5, 0x006F, 0x0303}, - { 0x014D, 0x006F, 0x0304}, - { 0x014F, 0x006F, 0x0306}, - { 0x022F, 0x006F, 0x0307}, - { 0x00F6, 0x006F, 0x0308}, - { 0x1ECF, 0x006F, 0x0309}, - { 0x0151, 0x006F, 0x030B}, - { 0x01D2, 0x006F, 0x030C}, - { 0x020D, 0x006F, 0x030F}, - { 0x020F, 0x006F, 0x0311}, - { 0x01A1, 0x006F, 0x031B}, - { 0x1ECD, 0x006F, 0x0323}, - { 0x01EB, 0x006F, 0x0328}, - { 0x1E55, 0x0070, 0x0301}, - { 0x1E57, 0x0070, 0x0307}, - { 0x0155, 0x0072, 0x0301}, - { 0x1E59, 0x0072, 0x0307}, - { 0x0159, 0x0072, 0x030C}, - { 0x0211, 0x0072, 0x030F}, - { 0x0213, 0x0072, 0x0311}, - { 0x1E5B, 0x0072, 0x0323}, - { 0x0157, 0x0072, 0x0327}, - { 0x1E5F, 0x0072, 0x0331}, - { 0x015B, 0x0073, 0x0301}, - { 0x015D, 0x0073, 0x0302}, - { 0x1E61, 0x0073, 0x0307}, - { 0x0161, 0x0073, 0x030C}, - { 0x1E63, 0x0073, 0x0323}, - { 0x0219, 0x0073, 0x0326}, - { 0x015F, 0x0073, 0x0327}, - { 0x1E6B, 0x0074, 0x0307}, - { 0x1E97, 0x0074, 0x0308}, - { 0x0165, 0x0074, 0x030C}, - { 0x1E6D, 0x0074, 0x0323}, - { 0x021B, 0x0074, 0x0326}, - { 0x0163, 0x0074, 0x0327}, - { 0x1E71, 0x0074, 0x032D}, - { 0x1E6F, 0x0074, 0x0331}, - { 0x00F9, 0x0075, 0x0300}, - { 0x00FA, 0x0075, 0x0301}, - { 0x00FB, 0x0075, 0x0302}, - { 0x0169, 0x0075, 0x0303}, - { 0x016B, 0x0075, 0x0304}, - { 0x016D, 0x0075, 0x0306}, - { 0x00FC, 0x0075, 0x0308}, - { 0x1EE7, 0x0075, 0x0309}, - { 0x016F, 0x0075, 0x030A}, - { 0x0171, 0x0075, 0x030B}, - { 0x01D4, 0x0075, 0x030C}, - { 0x0215, 0x0075, 0x030F}, - { 0x0217, 0x0075, 0x0311}, - { 0x01B0, 0x0075, 0x031B}, - { 0x1EE5, 0x0075, 0x0323}, - { 0x1E73, 0x0075, 0x0324}, - { 0x0173, 0x0075, 0x0328}, - { 0x1E77, 0x0075, 0x032D}, - { 0x1E75, 0x0075, 0x0330}, - { 0x1E7D, 0x0076, 0x0303}, - { 0x1E7F, 0x0076, 0x0323}, - { 0x1E81, 0x0077, 0x0300}, - { 0x1E83, 0x0077, 0x0301}, - { 0x0175, 0x0077, 0x0302}, - { 0x1E87, 0x0077, 0x0307}, - { 0x1E85, 0x0077, 0x0308}, - { 0x1E98, 0x0077, 0x030A}, - { 0x1E89, 0x0077, 0x0323}, - { 0x1E8B, 0x0078, 0x0307}, - { 0x1E8D, 0x0078, 0x0308}, - { 0x1EF3, 0x0079, 0x0300}, - { 0x00FD, 0x0079, 0x0301}, - { 0x0177, 0x0079, 0x0302}, - { 0x1EF9, 0x0079, 0x0303}, - { 0x0233, 0x0079, 0x0304}, - { 0x1E8F, 0x0079, 0x0307}, - { 0x00FF, 0x0079, 0x0308}, - { 0x1EF7, 0x0079, 0x0309}, - { 0x1E99, 0x0079, 0x030A}, - { 0x1EF5, 0x0079, 0x0323}, - { 0x017A, 0x007A, 0x0301}, - { 0x1E91, 0x007A, 0x0302}, - { 0x017C, 0x007A, 0x0307}, - { 0x017E, 0x007A, 0x030C}, - { 0x1E93, 0x007A, 0x0323}, - { 0x1E95, 0x007A, 0x0331}, - { 0x1FED, 0x00A8, 0x0300}, - { 0x0385, 0x00A8, 0x0301}, - { 0x1FC1, 0x00A8, 0x0342}, - { 0x1EA6, 0x00C2, 0x0300}, - { 0x1EA4, 0x00C2, 0x0301}, - { 0x1EAA, 0x00C2, 0x0303}, - { 0x1EA8, 0x00C2, 0x0309}, - { 0x01DE, 0x00C4, 0x0304}, - { 0x01FA, 0x00C5, 0x0301}, - { 0x01FC, 0x00C6, 0x0301}, - { 0x01E2, 0x00C6, 0x0304}, - { 0x1E08, 0x00C7, 0x0301}, - { 0x1EC0, 0x00CA, 0x0300}, - { 0x1EBE, 0x00CA, 0x0301}, - { 0x1EC4, 0x00CA, 0x0303}, - { 0x1EC2, 0x00CA, 0x0309}, - { 0x1E2E, 0x00CF, 0x0301}, - { 0x1ED2, 0x00D4, 0x0300}, - { 0x1ED0, 0x00D4, 0x0301}, - { 0x1ED6, 0x00D4, 0x0303}, - { 0x1ED4, 0x00D4, 0x0309}, - { 0x1E4C, 0x00D5, 0x0301}, - { 0x022C, 0x00D5, 0x0304}, - { 0x1E4E, 0x00D5, 0x0308}, - { 0x022A, 0x00D6, 0x0304}, - { 0x01FE, 0x00D8, 0x0301}, - { 0x01DB, 0x00DC, 0x0300}, - { 0x01D7, 0x00DC, 0x0301}, - { 0x01D5, 0x00DC, 0x0304}, - { 0x01D9, 0x00DC, 0x030C}, - { 0x1EA7, 0x00E2, 0x0300}, - { 0x1EA5, 0x00E2, 0x0301}, - { 0x1EAB, 0x00E2, 0x0303}, - { 0x1EA9, 0x00E2, 0x0309}, - { 0x01DF, 0x00E4, 0x0304}, - { 0x01FB, 0x00E5, 0x0301}, - { 0x01FD, 0x00E6, 0x0301}, - { 0x01E3, 0x00E6, 0x0304}, - { 0x1E09, 0x00E7, 0x0301}, - { 0x1EC1, 0x00EA, 0x0300}, - { 0x1EBF, 0x00EA, 0x0301}, - { 0x1EC5, 0x00EA, 0x0303}, - { 0x1EC3, 0x00EA, 0x0309}, - { 0x1E2F, 0x00EF, 0x0301}, - { 0x1ED3, 0x00F4, 0x0300}, - { 0x1ED1, 0x00F4, 0x0301}, - { 0x1ED7, 0x00F4, 0x0303}, - { 0x1ED5, 0x00F4, 0x0309}, - { 0x1E4D, 0x00F5, 0x0301}, - { 0x022D, 0x00F5, 0x0304}, - { 0x1E4F, 0x00F5, 0x0308}, - { 0x022B, 0x00F6, 0x0304}, - { 0x01FF, 0x00F8, 0x0301}, - { 0x01DC, 0x00FC, 0x0300}, - { 0x01D8, 0x00FC, 0x0301}, - { 0x01D6, 0x00FC, 0x0304}, - { 0x01DA, 0x00FC, 0x030C}, - { 0x1EB0, 0x0102, 0x0300}, - { 0x1EAE, 0x0102, 0x0301}, - { 0x1EB4, 0x0102, 0x0303}, - { 0x1EB2, 0x0102, 0x0309}, - { 0x1EB1, 0x0103, 0x0300}, - { 0x1EAF, 0x0103, 0x0301}, - { 0x1EB5, 0x0103, 0x0303}, - { 0x1EB3, 0x0103, 0x0309}, - { 0x1E14, 0x0112, 0x0300}, - { 0x1E16, 0x0112, 0x0301}, - { 0x1E15, 0x0113, 0x0300}, - { 0x1E17, 0x0113, 0x0301}, - { 0x1E50, 0x014C, 0x0300}, - { 0x1E52, 0x014C, 0x0301}, - { 0x1E51, 0x014D, 0x0300}, - { 0x1E53, 0x014D, 0x0301}, - { 0x1E64, 0x015A, 0x0307}, - { 0x1E65, 0x015B, 0x0307}, - { 0x1E66, 0x0160, 0x0307}, - { 0x1E67, 0x0161, 0x0307}, - { 0x1E78, 0x0168, 0x0301}, - { 0x1E79, 0x0169, 0x0301}, - { 0x1E7A, 0x016A, 0x0308}, - { 0x1E7B, 0x016B, 0x0308}, - { 0x1E9B, 0x017F, 0x0307}, - { 0x1EDC, 0x01A0, 0x0300}, - { 0x1EDA, 0x01A0, 0x0301}, - { 0x1EE0, 0x01A0, 0x0303}, - { 0x1EDE, 0x01A0, 0x0309}, - { 0x1EE2, 0x01A0, 0x0323}, - { 0x1EDD, 0x01A1, 0x0300}, - { 0x1EDB, 0x01A1, 0x0301}, - { 0x1EE1, 0x01A1, 0x0303}, - { 0x1EDF, 0x01A1, 0x0309}, - { 0x1EE3, 0x01A1, 0x0323}, - { 0x1EEA, 0x01AF, 0x0300}, - { 0x1EE8, 0x01AF, 0x0301}, - { 0x1EEE, 0x01AF, 0x0303}, - { 0x1EEC, 0x01AF, 0x0309}, - { 0x1EF0, 0x01AF, 0x0323}, - { 0x1EEB, 0x01B0, 0x0300}, - { 0x1EE9, 0x01B0, 0x0301}, - { 0x1EEF, 0x01B0, 0x0303}, - { 0x1EED, 0x01B0, 0x0309}, - { 0x1EF1, 0x01B0, 0x0323}, - { 0x01EE, 0x01B7, 0x030C}, - { 0x01EC, 0x01EA, 0x0304}, - { 0x01ED, 0x01EB, 0x0304}, - { 0x01E0, 0x0226, 0x0304}, - { 0x01E1, 0x0227, 0x0304}, - { 0x1E1C, 0x0228, 0x0306}, - { 0x1E1D, 0x0229, 0x0306}, - { 0x0230, 0x022E, 0x0304}, - { 0x0231, 0x022F, 0x0304}, - { 0x01EF, 0x0292, 0x030C}, - { 0x0344, 0x0308, 0x0301}, - { 0x1FBA, 0x0391, 0x0300}, - { 0x0386, 0x0391, 0x0301}, - { 0x1FB9, 0x0391, 0x0304}, - { 0x1FB8, 0x0391, 0x0306}, - { 0x1F08, 0x0391, 0x0313}, - { 0x1F09, 0x0391, 0x0314}, - { 0x1FBC, 0x0391, 0x0345}, - { 0x1FC8, 0x0395, 0x0300}, - { 0x0388, 0x0395, 0x0301}, - { 0x1F18, 0x0395, 0x0313}, - { 0x1F19, 0x0395, 0x0314}, - { 0x1FCA, 0x0397, 0x0300}, - { 0x0389, 0x0397, 0x0301}, - { 0x1F28, 0x0397, 0x0313}, - { 0x1F29, 0x0397, 0x0314}, - { 0x1FCC, 0x0397, 0x0345}, - { 0x1FDA, 0x0399, 0x0300}, - { 0x038A, 0x0399, 0x0301}, - { 0x1FD9, 0x0399, 0x0304}, - { 0x1FD8, 0x0399, 0x0306}, - { 0x03AA, 0x0399, 0x0308}, - { 0x1F38, 0x0399, 0x0313}, - { 0x1F39, 0x0399, 0x0314}, - { 0x1FF8, 0x039F, 0x0300}, - { 0x038C, 0x039F, 0x0301}, - { 0x1F48, 0x039F, 0x0313}, - { 0x1F49, 0x039F, 0x0314}, - { 0x1FEC, 0x03A1, 0x0314}, - { 0x1FEA, 0x03A5, 0x0300}, - { 0x038E, 0x03A5, 0x0301}, - { 0x1FE9, 0x03A5, 0x0304}, - { 0x1FE8, 0x03A5, 0x0306}, - { 0x03AB, 0x03A5, 0x0308}, - { 0x1F59, 0x03A5, 0x0314}, - { 0x1FFA, 0x03A9, 0x0300}, - { 0x038F, 0x03A9, 0x0301}, - { 0x1F68, 0x03A9, 0x0313}, - { 0x1F69, 0x03A9, 0x0314}, - { 0x1FFC, 0x03A9, 0x0345}, - { 0x1FB4, 0x03AC, 0x0345}, - { 0x1FC4, 0x03AE, 0x0345}, - { 0x1F70, 0x03B1, 0x0300}, - { 0x03AC, 0x03B1, 0x0301}, - { 0x1FB1, 0x03B1, 0x0304}, - { 0x1FB0, 0x03B1, 0x0306}, - { 0x1F00, 0x03B1, 0x0313}, - { 0x1F01, 0x03B1, 0x0314}, - { 0x1FB6, 0x03B1, 0x0342}, - { 0x1FB3, 0x03B1, 0x0345}, - { 0x1F72, 0x03B5, 0x0300}, - { 0x03AD, 0x03B5, 0x0301}, - { 0x1F10, 0x03B5, 0x0313}, - { 0x1F11, 0x03B5, 0x0314}, - { 0x1F74, 0x03B7, 0x0300}, - { 0x03AE, 0x03B7, 0x0301}, - { 0x1F20, 0x03B7, 0x0313}, - { 0x1F21, 0x03B7, 0x0314}, - { 0x1FC6, 0x03B7, 0x0342}, - { 0x1FC3, 0x03B7, 0x0345}, - { 0x1F76, 0x03B9, 0x0300}, - { 0x03AF, 0x03B9, 0x0301}, - { 0x1FD1, 0x03B9, 0x0304}, - { 0x1FD0, 0x03B9, 0x0306}, - { 0x03CA, 0x03B9, 0x0308}, - { 0x1F30, 0x03B9, 0x0313}, - { 0x1F31, 0x03B9, 0x0314}, - { 0x1FD6, 0x03B9, 0x0342}, - { 0x1F78, 0x03BF, 0x0300}, - { 0x03CC, 0x03BF, 0x0301}, - { 0x1F40, 0x03BF, 0x0313}, - { 0x1F41, 0x03BF, 0x0314}, - { 0x1FE4, 0x03C1, 0x0313}, - { 0x1FE5, 0x03C1, 0x0314}, - { 0x1F7A, 0x03C5, 0x0300}, - { 0x03CD, 0x03C5, 0x0301}, - { 0x1FE1, 0x03C5, 0x0304}, - { 0x1FE0, 0x03C5, 0x0306}, - { 0x03CB, 0x03C5, 0x0308}, - { 0x1F50, 0x03C5, 0x0313}, - { 0x1F51, 0x03C5, 0x0314}, - { 0x1FE6, 0x03C5, 0x0342}, - { 0x1F7C, 0x03C9, 0x0300}, - { 0x03CE, 0x03C9, 0x0301}, - { 0x1F60, 0x03C9, 0x0313}, - { 0x1F61, 0x03C9, 0x0314}, - { 0x1FF6, 0x03C9, 0x0342}, - { 0x1FF3, 0x03C9, 0x0345}, - { 0x1FD2, 0x03CA, 0x0300}, - { 0x0390, 0x03CA, 0x0301}, - { 0x1FD7, 0x03CA, 0x0342}, - { 0x1FE2, 0x03CB, 0x0300}, - { 0x03B0, 0x03CB, 0x0301}, - { 0x1FE7, 0x03CB, 0x0342}, - { 0x1FF4, 0x03CE, 0x0345}, - { 0x03D3, 0x03D2, 0x0301}, - { 0x03D4, 0x03D2, 0x0308}, - { 0x0407, 0x0406, 0x0308}, - { 0x04D0, 0x0410, 0x0306}, - { 0x04D2, 0x0410, 0x0308}, - { 0x0403, 0x0413, 0x0301}, - { 0x0400, 0x0415, 0x0300}, - { 0x04D6, 0x0415, 0x0306}, - { 0x0401, 0x0415, 0x0308}, - { 0x04C1, 0x0416, 0x0306}, - { 0x04DC, 0x0416, 0x0308}, - { 0x04DE, 0x0417, 0x0308}, - { 0x040D, 0x0418, 0x0300}, - { 0x04E2, 0x0418, 0x0304}, - { 0x0419, 0x0418, 0x0306}, - { 0x04E4, 0x0418, 0x0308}, - { 0x040C, 0x041A, 0x0301}, - { 0x04E6, 0x041E, 0x0308}, - { 0x04EE, 0x0423, 0x0304}, - { 0x040E, 0x0423, 0x0306}, - { 0x04F0, 0x0423, 0x0308}, - { 0x04F2, 0x0423, 0x030B}, - { 0x04F4, 0x0427, 0x0308}, - { 0x04F8, 0x042B, 0x0308}, - { 0x04EC, 0x042D, 0x0308}, - { 0x04D1, 0x0430, 0x0306}, - { 0x04D3, 0x0430, 0x0308}, - { 0x0453, 0x0433, 0x0301}, - { 0x0450, 0x0435, 0x0300}, - { 0x04D7, 0x0435, 0x0306}, - { 0x0451, 0x0435, 0x0308}, - { 0x04C2, 0x0436, 0x0306}, - { 0x04DD, 0x0436, 0x0308}, - { 0x04DF, 0x0437, 0x0308}, - { 0x045D, 0x0438, 0x0300}, - { 0x04E3, 0x0438, 0x0304}, - { 0x0439, 0x0438, 0x0306}, - { 0x04E5, 0x0438, 0x0308}, - { 0x045C, 0x043A, 0x0301}, - { 0x04E7, 0x043E, 0x0308}, - { 0x04EF, 0x0443, 0x0304}, - { 0x045E, 0x0443, 0x0306}, - { 0x04F1, 0x0443, 0x0308}, - { 0x04F3, 0x0443, 0x030B}, - { 0x04F5, 0x0447, 0x0308}, - { 0x04F9, 0x044B, 0x0308}, - { 0x04ED, 0x044D, 0x0308}, - { 0x0457, 0x0456, 0x0308}, - { 0x0476, 0x0474, 0x030F}, - { 0x0477, 0x0475, 0x030F}, - { 0x04DA, 0x04D8, 0x0308}, - { 0x04DB, 0x04D9, 0x0308}, - { 0x04EA, 0x04E8, 0x0308}, - { 0x04EB, 0x04E9, 0x0308}, - { 0xFB2E, 0x05D0, 0x05B7}, - { 0xFB2F, 0x05D0, 0x05B8}, - { 0xFB30, 0x05D0, 0x05BC}, - { 0xFB31, 0x05D1, 0x05BC}, - { 0xFB4C, 0x05D1, 0x05BF}, - { 0xFB32, 0x05D2, 0x05BC}, - { 0xFB33, 0x05D3, 0x05BC}, - { 0xFB34, 0x05D4, 0x05BC}, - { 0xFB4B, 0x05D5, 0x05B9}, - { 0xFB35, 0x05D5, 0x05BC}, - { 0xFB36, 0x05D6, 0x05BC}, - { 0xFB38, 0x05D8, 0x05BC}, - { 0xFB1D, 0x05D9, 0x05B4}, - { 0xFB39, 0x05D9, 0x05BC}, - { 0xFB3A, 0x05DA, 0x05BC}, - { 0xFB3B, 0x05DB, 0x05BC}, - { 0xFB4D, 0x05DB, 0x05BF}, - { 0xFB3C, 0x05DC, 0x05BC}, - { 0xFB3E, 0x05DE, 0x05BC}, - { 0xFB40, 0x05E0, 0x05BC}, - { 0xFB41, 0x05E1, 0x05BC}, - { 0xFB43, 0x05E3, 0x05BC}, - { 0xFB44, 0x05E4, 0x05BC}, - { 0xFB4E, 0x05E4, 0x05BF}, - { 0xFB46, 0x05E6, 0x05BC}, - { 0xFB47, 0x05E7, 0x05BC}, - { 0xFB48, 0x05E8, 0x05BC}, - { 0xFB49, 0x05E9, 0x05BC}, - { 0xFB2A, 0x05E9, 0x05C1}, - { 0xFB2B, 0x05E9, 0x05C2}, - { 0xFB4A, 0x05EA, 0x05BC}, - { 0xFB1F, 0x05F2, 0x05B7}, - { 0x0622, 0x0627, 0x0653}, - { 0x0623, 0x0627, 0x0654}, - { 0x0625, 0x0627, 0x0655}, - { 0x0624, 0x0648, 0x0654}, - { 0x0626, 0x064A, 0x0654}, - { 0x06C2, 0x06C1, 0x0654}, - { 0x06D3, 0x06D2, 0x0654}, - { 0x06C0, 0x06D5, 0x0654}, - { 0x0958, 0x0915, 0x093C}, - { 0x0959, 0x0916, 0x093C}, - { 0x095A, 0x0917, 0x093C}, - { 0x095B, 0x091C, 0x093C}, - { 0x095C, 0x0921, 0x093C}, - { 0x095D, 0x0922, 0x093C}, - { 0x0929, 0x0928, 0x093C}, - { 0x095E, 0x092B, 0x093C}, - { 0x095F, 0x092F, 0x093C}, - { 0x0931, 0x0930, 0x093C}, - { 0x0934, 0x0933, 0x093C}, - { 0x09DC, 0x09A1, 0x09BC}, - { 0x09DD, 0x09A2, 0x09BC}, - { 0x09DF, 0x09AF, 0x09BC}, - { 0x09CB, 0x09C7, 0x09BE}, - { 0x09CC, 0x09C7, 0x09D7}, - { 0x0A59, 0x0A16, 0x0A3C}, - { 0x0A5A, 0x0A17, 0x0A3C}, - { 0x0A5B, 0x0A1C, 0x0A3C}, - { 0x0A5E, 0x0A2B, 0x0A3C}, - { 0x0A33, 0x0A32, 0x0A3C}, - { 0x0A36, 0x0A38, 0x0A3C}, - { 0x0B5C, 0x0B21, 0x0B3C}, - { 0x0B5D, 0x0B22, 0x0B3C}, - { 0x0B4B, 0x0B47, 0x0B3E}, - { 0x0B48, 0x0B47, 0x0B56}, - { 0x0B4C, 0x0B47, 0x0B57}, - { 0x0B94, 0x0B92, 0x0BD7}, - { 0x0BCA, 0x0BC6, 0x0BBE}, - { 0x0BCC, 0x0BC6, 0x0BD7}, - { 0x0BCB, 0x0BC7, 0x0BBE}, - { 0x0C48, 0x0C46, 0x0C56}, - { 0x0CC0, 0x0CBF, 0x0CD5}, - { 0x0CCA, 0x0CC6, 0x0CC2}, - { 0x0CC7, 0x0CC6, 0x0CD5}, - { 0x0CC8, 0x0CC6, 0x0CD6}, - { 0x0CCB, 0x0CCA, 0x0CD5}, - { 0x0D4A, 0x0D46, 0x0D3E}, - { 0x0D4C, 0x0D46, 0x0D57}, - { 0x0D4B, 0x0D47, 0x0D3E}, - { 0x0DDA, 0x0DD9, 0x0DCA}, - { 0x0DDC, 0x0DD9, 0x0DCF}, - { 0x0DDE, 0x0DD9, 0x0DDF}, - { 0x0DDD, 0x0DDC, 0x0DCA}, - { 0x0F69, 0x0F40, 0x0FB5}, - { 0x0F43, 0x0F42, 0x0FB7}, - { 0x0F4D, 0x0F4C, 0x0FB7}, - { 0x0F52, 0x0F51, 0x0FB7}, - { 0x0F57, 0x0F56, 0x0FB7}, - { 0x0F5C, 0x0F5B, 0x0FB7}, - { 0x0F73, 0x0F71, 0x0F72}, - { 0x0F75, 0x0F71, 0x0F74}, - { 0x0F81, 0x0F71, 0x0F80}, - { 0x0FB9, 0x0F90, 0x0FB5}, - { 0x0F93, 0x0F92, 0x0FB7}, - { 0x0F9D, 0x0F9C, 0x0FB7}, - { 0x0FA2, 0x0FA1, 0x0FB7}, - { 0x0FA7, 0x0FA6, 0x0FB7}, - { 0x0FAC, 0x0FAB, 0x0FB7}, - { 0x0F76, 0x0FB2, 0x0F80}, - { 0x0F78, 0x0FB3, 0x0F80}, - { 0x1026, 0x1025, 0x102E}, - { 0x1B06, 0x1B05, 0x1B35}, - { 0x1B08, 0x1B07, 0x1B35}, - { 0x1B0A, 0x1B09, 0x1B35}, - { 0x1B0C, 0x1B0B, 0x1B35}, - { 0x1B0E, 0x1B0D, 0x1B35}, - { 0x1B12, 0x1B11, 0x1B35}, - { 0x1B3B, 0x1B3A, 0x1B35}, - { 0x1B3D, 0x1B3C, 0x1B35}, - { 0x1B40, 0x1B3E, 0x1B35}, - { 0x1B41, 0x1B3F, 0x1B35}, - { 0x1B43, 0x1B42, 0x1B35}, - { 0x1E38, 0x1E36, 0x0304}, - { 0x1E39, 0x1E37, 0x0304}, - { 0x1E5C, 0x1E5A, 0x0304}, - { 0x1E5D, 0x1E5B, 0x0304}, - { 0x1E68, 0x1E62, 0x0307}, - { 0x1E69, 0x1E63, 0x0307}, - { 0x1EAC, 0x1EA0, 0x0302}, - { 0x1EB6, 0x1EA0, 0x0306}, - { 0x1EAD, 0x1EA1, 0x0302}, - { 0x1EB7, 0x1EA1, 0x0306}, - { 0x1EC6, 0x1EB8, 0x0302}, - { 0x1EC7, 0x1EB9, 0x0302}, - { 0x1ED8, 0x1ECC, 0x0302}, - { 0x1ED9, 0x1ECD, 0x0302}, - { 0x1F02, 0x1F00, 0x0300}, - { 0x1F04, 0x1F00, 0x0301}, - { 0x1F06, 0x1F00, 0x0342}, - { 0x1F80, 0x1F00, 0x0345}, - { 0x1F03, 0x1F01, 0x0300}, - { 0x1F05, 0x1F01, 0x0301}, - { 0x1F07, 0x1F01, 0x0342}, - { 0x1F81, 0x1F01, 0x0345}, - { 0x1F82, 0x1F02, 0x0345}, - { 0x1F83, 0x1F03, 0x0345}, - { 0x1F84, 0x1F04, 0x0345}, - { 0x1F85, 0x1F05, 0x0345}, - { 0x1F86, 0x1F06, 0x0345}, - { 0x1F87, 0x1F07, 0x0345}, - { 0x1F0A, 0x1F08, 0x0300}, - { 0x1F0C, 0x1F08, 0x0301}, - { 0x1F0E, 0x1F08, 0x0342}, - { 0x1F88, 0x1F08, 0x0345}, - { 0x1F0B, 0x1F09, 0x0300}, - { 0x1F0D, 0x1F09, 0x0301}, - { 0x1F0F, 0x1F09, 0x0342}, - { 0x1F89, 0x1F09, 0x0345}, - { 0x1F8A, 0x1F0A, 0x0345}, - { 0x1F8B, 0x1F0B, 0x0345}, - { 0x1F8C, 0x1F0C, 0x0345}, - { 0x1F8D, 0x1F0D, 0x0345}, - { 0x1F8E, 0x1F0E, 0x0345}, - { 0x1F8F, 0x1F0F, 0x0345}, - { 0x1F12, 0x1F10, 0x0300}, - { 0x1F14, 0x1F10, 0x0301}, - { 0x1F13, 0x1F11, 0x0300}, - { 0x1F15, 0x1F11, 0x0301}, - { 0x1F1A, 0x1F18, 0x0300}, - { 0x1F1C, 0x1F18, 0x0301}, - { 0x1F1B, 0x1F19, 0x0300}, - { 0x1F1D, 0x1F19, 0x0301}, - { 0x1F22, 0x1F20, 0x0300}, - { 0x1F24, 0x1F20, 0x0301}, - { 0x1F26, 0x1F20, 0x0342}, - { 0x1F90, 0x1F20, 0x0345}, - { 0x1F23, 0x1F21, 0x0300}, - { 0x1F25, 0x1F21, 0x0301}, - { 0x1F27, 0x1F21, 0x0342}, - { 0x1F91, 0x1F21, 0x0345}, - { 0x1F92, 0x1F22, 0x0345}, - { 0x1F93, 0x1F23, 0x0345}, - { 0x1F94, 0x1F24, 0x0345}, - { 0x1F95, 0x1F25, 0x0345}, - { 0x1F96, 0x1F26, 0x0345}, - { 0x1F97, 0x1F27, 0x0345}, - { 0x1F2A, 0x1F28, 0x0300}, - { 0x1F2C, 0x1F28, 0x0301}, - { 0x1F2E, 0x1F28, 0x0342}, - { 0x1F98, 0x1F28, 0x0345}, - { 0x1F2B, 0x1F29, 0x0300}, - { 0x1F2D, 0x1F29, 0x0301}, - { 0x1F2F, 0x1F29, 0x0342}, - { 0x1F99, 0x1F29, 0x0345}, - { 0x1F9A, 0x1F2A, 0x0345}, - { 0x1F9B, 0x1F2B, 0x0345}, - { 0x1F9C, 0x1F2C, 0x0345}, - { 0x1F9D, 0x1F2D, 0x0345}, - { 0x1F9E, 0x1F2E, 0x0345}, - { 0x1F9F, 0x1F2F, 0x0345}, - { 0x1F32, 0x1F30, 0x0300}, - { 0x1F34, 0x1F30, 0x0301}, - { 0x1F36, 0x1F30, 0x0342}, - { 0x1F33, 0x1F31, 0x0300}, - { 0x1F35, 0x1F31, 0x0301}, - { 0x1F37, 0x1F31, 0x0342}, - { 0x1F3A, 0x1F38, 0x0300}, - { 0x1F3C, 0x1F38, 0x0301}, - { 0x1F3E, 0x1F38, 0x0342}, - { 0x1F3B, 0x1F39, 0x0300}, - { 0x1F3D, 0x1F39, 0x0301}, - { 0x1F3F, 0x1F39, 0x0342}, - { 0x1F42, 0x1F40, 0x0300}, - { 0x1F44, 0x1F40, 0x0301}, - { 0x1F43, 0x1F41, 0x0300}, - { 0x1F45, 0x1F41, 0x0301}, - { 0x1F4A, 0x1F48, 0x0300}, - { 0x1F4C, 0x1F48, 0x0301}, - { 0x1F4B, 0x1F49, 0x0300}, - { 0x1F4D, 0x1F49, 0x0301}, - { 0x1F52, 0x1F50, 0x0300}, - { 0x1F54, 0x1F50, 0x0301}, - { 0x1F56, 0x1F50, 0x0342}, - { 0x1F53, 0x1F51, 0x0300}, - { 0x1F55, 0x1F51, 0x0301}, - { 0x1F57, 0x1F51, 0x0342}, - { 0x1F5B, 0x1F59, 0x0300}, - { 0x1F5D, 0x1F59, 0x0301}, - { 0x1F5F, 0x1F59, 0x0342}, - { 0x1F62, 0x1F60, 0x0300}, - { 0x1F64, 0x1F60, 0x0301}, - { 0x1F66, 0x1F60, 0x0342}, - { 0x1FA0, 0x1F60, 0x0345}, - { 0x1F63, 0x1F61, 0x0300}, - { 0x1F65, 0x1F61, 0x0301}, - { 0x1F67, 0x1F61, 0x0342}, - { 0x1FA1, 0x1F61, 0x0345}, - { 0x1FA2, 0x1F62, 0x0345}, - { 0x1FA3, 0x1F63, 0x0345}, - { 0x1FA4, 0x1F64, 0x0345}, - { 0x1FA5, 0x1F65, 0x0345}, - { 0x1FA6, 0x1F66, 0x0345}, - { 0x1FA7, 0x1F67, 0x0345}, - { 0x1F6A, 0x1F68, 0x0300}, - { 0x1F6C, 0x1F68, 0x0301}, - { 0x1F6E, 0x1F68, 0x0342}, - { 0x1FA8, 0x1F68, 0x0345}, - { 0x1F6B, 0x1F69, 0x0300}, - { 0x1F6D, 0x1F69, 0x0301}, - { 0x1F6F, 0x1F69, 0x0342}, - { 0x1FA9, 0x1F69, 0x0345}, - { 0x1FAA, 0x1F6A, 0x0345}, - { 0x1FAB, 0x1F6B, 0x0345}, - { 0x1FAC, 0x1F6C, 0x0345}, - { 0x1FAD, 0x1F6D, 0x0345}, - { 0x1FAE, 0x1F6E, 0x0345}, - { 0x1FAF, 0x1F6F, 0x0345}, - { 0x1FB2, 0x1F70, 0x0345}, - { 0x1FC2, 0x1F74, 0x0345}, - { 0x1FF2, 0x1F7C, 0x0345}, - { 0x1FB7, 0x1FB6, 0x0345}, - { 0x1FCD, 0x1FBF, 0x0300}, - { 0x1FCE, 0x1FBF, 0x0301}, - { 0x1FCF, 0x1FBF, 0x0342}, - { 0x1FC7, 0x1FC6, 0x0345}, - { 0x1FF7, 0x1FF6, 0x0345}, - { 0x1FDD, 0x1FFE, 0x0300}, - { 0x1FDE, 0x1FFE, 0x0301}, - { 0x1FDF, 0x1FFE, 0x0342}, - { 0x219A, 0x2190, 0x0338}, - { 0x219B, 0x2192, 0x0338}, - { 0x21AE, 0x2194, 0x0338}, - { 0x21CD, 0x21D0, 0x0338}, - { 0x21CF, 0x21D2, 0x0338}, - { 0x21CE, 0x21D4, 0x0338}, - { 0x2204, 0x2203, 0x0338}, - { 0x2209, 0x2208, 0x0338}, - { 0x220C, 0x220B, 0x0338}, - { 0x2224, 0x2223, 0x0338}, - { 0x2226, 0x2225, 0x0338}, - { 0x2241, 0x223C, 0x0338}, - { 0x2244, 0x2243, 0x0338}, - { 0x2247, 0x2245, 0x0338}, - { 0x2249, 0x2248, 0x0338}, - { 0x226D, 0x224D, 0x0338}, - { 0x2262, 0x2261, 0x0338}, - { 0x2270, 0x2264, 0x0338}, - { 0x2271, 0x2265, 0x0338}, - { 0x2274, 0x2272, 0x0338}, - { 0x2275, 0x2273, 0x0338}, - { 0x2278, 0x2276, 0x0338}, - { 0x2279, 0x2277, 0x0338}, - { 0x2280, 0x227A, 0x0338}, - { 0x2281, 0x227B, 0x0338}, - { 0x22E0, 0x227C, 0x0338}, - { 0x22E1, 0x227D, 0x0338}, - { 0x2284, 0x2282, 0x0338}, - { 0x2285, 0x2283, 0x0338}, - { 0x2288, 0x2286, 0x0338}, - { 0x2289, 0x2287, 0x0338}, - { 0x22E2, 0x2291, 0x0338}, - { 0x22E3, 0x2292, 0x0338}, - { 0x22AC, 0x22A2, 0x0338}, - { 0x22AD, 0x22A8, 0x0338}, - { 0x22AE, 0x22A9, 0x0338}, - { 0x22AF, 0x22AB, 0x0338}, - { 0x22EA, 0x22B2, 0x0338}, - { 0x22EB, 0x22B3, 0x0338}, - { 0x22EC, 0x22B4, 0x0338}, - { 0x22ED, 0x22B5, 0x0338}, - { 0x2ADC, 0x2ADD, 0x0338}, - { 0x3094, 0x3046, 0x3099}, - { 0x304C, 0x304B, 0x3099}, - { 0x304E, 0x304D, 0x3099}, - { 0x3050, 0x304F, 0x3099}, - { 0x3052, 0x3051, 0x3099}, - { 0x3054, 0x3053, 0x3099}, - { 0x3056, 0x3055, 0x3099}, - { 0x3058, 0x3057, 0x3099}, - { 0x305A, 0x3059, 0x3099}, - { 0x305C, 0x305B, 0x3099}, - { 0x305E, 0x305D, 0x3099}, - { 0x3060, 0x305F, 0x3099}, - { 0x3062, 0x3061, 0x3099}, - { 0x3065, 0x3064, 0x3099}, - { 0x3067, 0x3066, 0x3099}, - { 0x3069, 0x3068, 0x3099}, - { 0x3070, 0x306F, 0x3099}, - { 0x3071, 0x306F, 0x309A}, - { 0x3073, 0x3072, 0x3099}, - { 0x3074, 0x3072, 0x309A}, - { 0x3076, 0x3075, 0x3099}, - { 0x3077, 0x3075, 0x309A}, - { 0x3079, 0x3078, 0x3099}, - { 0x307A, 0x3078, 0x309A}, - { 0x307C, 0x307B, 0x3099}, - { 0x307D, 0x307B, 0x309A}, - { 0x309E, 0x309D, 0x3099}, - { 0x30F4, 0x30A6, 0x3099}, - { 0x30AC, 0x30AB, 0x3099}, - { 0x30AE, 0x30AD, 0x3099}, - { 0x30B0, 0x30AF, 0x3099}, - { 0x30B2, 0x30B1, 0x3099}, - { 0x30B4, 0x30B3, 0x3099}, - { 0x30B6, 0x30B5, 0x3099}, - { 0x30B8, 0x30B7, 0x3099}, - { 0x30BA, 0x30B9, 0x3099}, - { 0x30BC, 0x30BB, 0x3099}, - { 0x30BE, 0x30BD, 0x3099}, - { 0x30C0, 0x30BF, 0x3099}, - { 0x30C2, 0x30C1, 0x3099}, - { 0x30C5, 0x30C4, 0x3099}, - { 0x30C7, 0x30C6, 0x3099}, - { 0x30C9, 0x30C8, 0x3099}, - { 0x30D0, 0x30CF, 0x3099}, - { 0x30D1, 0x30CF, 0x309A}, - { 0x30D3, 0x30D2, 0x3099}, - { 0x30D4, 0x30D2, 0x309A}, - { 0x30D6, 0x30D5, 0x3099}, - { 0x30D7, 0x30D5, 0x309A}, - { 0x30D9, 0x30D8, 0x3099}, - { 0x30DA, 0x30D8, 0x309A}, - { 0x30DC, 0x30DB, 0x3099}, - { 0x30DD, 0x30DB, 0x309A}, - { 0x30F7, 0x30EF, 0x3099}, - { 0x30F8, 0x30F0, 0x3099}, - { 0x30F9, 0x30F1, 0x3099}, - { 0x30FA, 0x30F2, 0x3099}, - { 0x30FE, 0x30FD, 0x3099}, - { 0xFB2C, 0xFB49, 0x05C1}, - { 0xFB2D, 0xFB49, 0x05C2}, - }; - - private static final int UNICODE_SHIFT = 21; - - public static char precompose(char base, char comb) { - int min = 0; - int max = precompositions.length - 1; - int mid; - - long sought = base << UNICODE_SHIFT | comb; - long that; - - while (max >= min) { - mid = (min + max) / 2; - that = precompositions[mid][1] << UNICODE_SHIFT | precompositions[mid][2]; - if (that < sought) - min = mid + 1; - else if (that > sought) - max = mid - 1; - else - return precompositions[mid][0]; - } - - // No match; return character without combiner - return base; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUBuffer.java b/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUBuffer.java deleted file mode 100644 index 58cf20b..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUBuffer.java +++ /dev/null @@ -1,931 +0,0 @@ -/* - * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform". - * - * (c) Matthias L. Jugel, Marcus Mei�ner 1996-2005. All Rights Reserved. - * - * Please visit http://javatelnet.org/ for updates and contact. - * - * --LICENSE NOTICE-- - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * --LICENSE NOTICE-- - * - */ - -package de.mud.terminal; - -import java.util.Arrays; - -/** - * Implementation of a Video Display Unit (VDU) buffer. This class contains all methods to - * manipulate the buffer that stores characters and their attributes as well as the regions - * displayed. - * - * @author Matthias L. Jugel, Marcus Meißner - * @version $Id: VDUBuffer.java 503 2005-10-24 07:34:13Z marcus $ - */ -public class VDUBuffer { - - /** The current version id tag */ - public final static String ID = "$Id: VDUBuffer.java 503 2005-10-24 07:34:13Z marcus $"; - - /** Enable debug messages. */ - public final static int debug = 0; - - public int height, width; /* rows and columns */ - public boolean[] update; /* contains the lines that need update */ - public char[][] charArray; /* contains the characters */ - public int[][] charAttributes; /* contains character attrs */ - public int bufSize; - public int maxBufSize; /* buffer sizes */ - public int screenBase; /* the actual screen start */ - public int windowBase; /* where the start displaying */ - public int scrollMarker; /* marks the last line inserted */ - - private int topMargin; /* top scroll margin */ - private int bottomMargin; /* bottom scroll margin */ - - // cursor variables - protected boolean showcursor = true; - protected int cursorX, cursorY; - - /** Scroll up when inserting a line. */ - public final static boolean SCROLL_UP = false; - /** Scroll down when inserting a line. */ - public final static boolean SCROLL_DOWN = true; - - /* - * Attributes bit-field usage: - * - * 8421 8421 8421 8421 8421 8421 8421 8421 |||| |||| |||| |||| |||| |||| |||| |||`- Bold |||| |||| - * |||| |||| |||| |||| |||| ||`-- Underline |||| |||| |||| |||| |||| |||| |||| |`--- Invert |||| - * |||| |||| |||| |||| |||| |||| `---- Low |||| |||| |||| |||| |||| |||| |||`------ Invisible |||| - * |||| |||| |||| ||`+-++++-+++------- Foreground Color |||| |||| |`++-++++-++------------------ - * Background Color |||| |||| `----------------------------- Fullwidth character - * `+++-++++------------------------------- Reserved for future use - */ - - /** Make character normal. */ - public final static int NORMAL = 0x00; - /** Make character bold. */ - public final static int BOLD = 0x01; - /** Underline character. */ - public final static int UNDERLINE = 0x02; - /** Invert character. */ - public final static int INVERT = 0x04; - /** Lower intensity character. */ - public final static int LOW = 0x08; - /** Invisible character. */ - public final static int INVISIBLE = 0x10; - /** Unicode full-width character (CJK, et al.) */ - public final static int FULLWIDTH = 0x8000000; - - /** how much to left shift the foreground color */ - public final static int COLOR_FG_SHIFT = 5; - /** how much to left shift the background color */ - public final static int COLOR_BG_SHIFT = 14; - /** color mask */ - public final static int COLOR = 0x7fffe0; /* 0000 0000 0111 1111 1111 1111 1110 0000 */ - /** foreground color mask */ - public final static int COLOR_FG = 0x3fe0; /* 0000 0000 0000 0000 0011 1111 1110 0000 */ - /** background color mask */ - public final static int COLOR_BG = 0x7fc000; /* 0000 0000 0111 1111 1100 0000 0000 0000 */ - - /** - * Create a new video display buffer with the passed width and height in characters. - * - * @param width - * the length of the character lines - * @param height - * the amount of lines on the screen - */ - public VDUBuffer(int width, int height) { - // set the display screen size - setScreenSize(width, height, false); - } - - /** - * Create a standard video display buffer with 80 columns and 24 lines. - */ - public VDUBuffer() { - this(80, 24); - } - - /** - * Put a character on the screen with normal font and outline. The character previously on that - * position will be overwritten. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @param ch - * the character to show on the screen - * @see #insertChar - * @see #deleteChar - * @see #redraw - */ - public void putChar(int c, int l, char ch) { - putChar(c, l, ch, NORMAL); - } - - /** - * Put a character on the screen with specific font and outline. The character previously on that - * position will be overwritten. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @param ch - * the character to show on the screen - * @param attributes - * the character attributes - * @see #BOLD - * @see #UNDERLINE - * @see #INVERT - * @see #INVISIBLE - * @see #NORMAL - * @see #LOW - * @see #insertChar - * @see #deleteChar - * @see #redraw - */ - - public void putChar(int c, int l, char ch, int attributes) { - charArray[screenBase + l][c] = ch; - charAttributes[screenBase + l][c] = attributes; - if (l < height) { - update[l + 1] = true; - } - } - - /** - * Get the character at the specified position. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @see #putChar - */ - public char getChar(int c, int l) { - return charArray[screenBase + l][c]; - } - - /** - * Get the attributes for the specified position. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @see #putChar - */ - public int getAttributes(int c, int l) { - return charAttributes[screenBase + l][c]; - } - - /** - * Insert a character at a specific position on the screen. All character right to from this - * position will be moved one to the right. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @param ch - * the character to insert - * @param attributes - * the character attributes - * @see #BOLD - * @see #UNDERLINE - * @see #INVERT - * @see #INVISIBLE - * @see #NORMAL - * @see #LOW - * @see #putChar - * @see #deleteChar - * @see #redraw - */ - public void insertChar(int c, int l, char ch, int attributes) { - System.arraycopy(charArray[screenBase + l], c, charArray[screenBase + l], c + 1, width - c - 1); - System.arraycopy(charAttributes[screenBase + l], c, charAttributes[screenBase + l], c + 1, - width - c - 1); - putChar(c, l, ch, attributes); - } - - /** - * Delete a character at a given position on the screen. All characters right to the position will - * be moved one to the left. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @see #putChar - * @see #insertChar - * @see #redraw - */ - public void deleteChar(int c, int l) { - if (c < width - 1) { - System.arraycopy(charArray[screenBase + l], c + 1, charArray[screenBase + l], c, width - c - - 1); - System.arraycopy(charAttributes[screenBase + l], c + 1, charAttributes[screenBase + l], c, - width - c - 1); - } - putChar(width - 1, l, (char) 0); - } - - /** - * Put a String at a specific position. Any characters previously on that position will be - * overwritten. You need to call redraw() for screen update. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @param s - * the string to be shown on the screen - * @see #BOLD - * @see #UNDERLINE - * @see #INVERT - * @see #INVISIBLE - * @see #NORMAL - * @see #LOW - * @see #putChar - * @see #insertLine - * @see #deleteLine - * @see #redraw - */ - public void putString(int c, int l, String s) { - putString(c, l, s, NORMAL); - } - - /** - * Put a String at a specific position giving all characters the same attributes. Any characters - * previously on that position will be overwritten. You need to call redraw() to update the - * screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (line) - * @param s - * the string to be shown on the screen - * @param attributes - * character attributes - * @see #BOLD - * @see #UNDERLINE - * @see #INVERT - * @see #INVISIBLE - * @see #NORMAL - * @see #LOW - * @see #putChar - * @see #insertLine - * @see #deleteLine - * @see #redraw - */ - public void putString(int c, int l, String s, int attributes) { - for (int i = 0; i < s.length() && c + i < width; i++) { - putChar(c + i, l, s.charAt(i), attributes); - } - } - - /** - * Insert a blank line at a specific position. The current line and all previous lines are - * scrolled one line up. The top line is lost. You need to call redraw() to update the screen. - * - * @param l - * the y-coordinate to insert the line - * @see #deleteLine - * @see #redraw - */ - public void insertLine(int l) { - insertLine(l, 1, SCROLL_UP); - } - - /** - * Insert blank lines at a specific position. You need to call redraw() to update the screen - * - * @param l - * the y-coordinate to insert the line - * @param n - * amount of lines to be inserted - * @see #deleteLine - * @see #redraw - */ - public void insertLine(int l, int n) { - insertLine(l, n, SCROLL_UP); - } - - /** - * Insert a blank line at a specific position. Scroll text according to the argument. You need to - * call redraw() to update the screen - * - * @param l - * the y-coordinate to insert the line - * @param scrollDown - * scroll down - * @see #deleteLine - * @see #SCROLL_UP - * @see #SCROLL_DOWN - * @see #redraw - */ - public void insertLine(int l, boolean scrollDown) { - insertLine(l, 1, scrollDown); - } - - /** - * Insert blank lines at a specific position. The current line and all previous lines are scrolled - * one line up. The top line is lost. You need to call redraw() to update the screen. - * - * @param l - * the y-coordinate to insert the line - * @param n - * number of lines to be inserted - * @param scrollDown - * scroll down - * @see #deleteLine - * @see #SCROLL_UP - * @see #SCROLL_DOWN - * @see #redraw - */ - public synchronized void insertLine(int l, int n, boolean scrollDown) { - char cbuf[][] = null; - int abuf[][] = null; - int offset = 0; - int oldBase = screenBase; - - int newScreenBase = screenBase; - int newWindowBase = windowBase; - int newBufSize = bufSize; - - if (l > bottomMargin) { - return; - } - int top = - (l < topMargin ? 0 : (l > bottomMargin ? (bottomMargin + 1 < height ? bottomMargin + 1 - : height - 1) : topMargin)); - int bottom = - (l > bottomMargin ? height - 1 : (l < topMargin ? (topMargin > 0 ? topMargin - 1 : 0) - : bottomMargin)); - - // System.out.println("l is "+l+", top is "+top+", bottom is "+bottom+", bottomargin is "+bottomMargin+", topMargin is "+topMargin); - - if (scrollDown) { - if (n > (bottom - top)) { - n = (bottom - top); - } - int size = bottom - l - (n - 1); - if (size < 0) { - size = 0; - } - cbuf = new char[size][]; - abuf = new int[size][]; - - System.arraycopy(charArray, oldBase + l, cbuf, 0, bottom - l - (n - 1)); - System.arraycopy(charAttributes, oldBase + l, abuf, 0, bottom - l - (n - 1)); - System.arraycopy(cbuf, 0, charArray, oldBase + l + n, bottom - l - (n - 1)); - System.arraycopy(abuf, 0, charAttributes, oldBase + l + n, bottom - l - (n - 1)); - cbuf = charArray; - abuf = charAttributes; - } else { - try { - if (n > (bottom - top) + 1) { - n = (bottom - top) + 1; - } - if (bufSize < maxBufSize) { - if (bufSize + n > maxBufSize) { - offset = n - (maxBufSize - bufSize); - scrollMarker += offset; - newBufSize = maxBufSize; - newScreenBase = maxBufSize - height - 1; - newWindowBase = screenBase; - } else { - scrollMarker += n; - newScreenBase += n; - newWindowBase += n; - newBufSize += n; - } - - cbuf = new char[newBufSize][]; - abuf = new int[newBufSize][]; - } else { - offset = n; - cbuf = charArray; - abuf = charAttributes; - } - // copy anything from the top of the buffer (+offset) to the new top - // up to the screenBase. - if (oldBase > 0) { - System.arraycopy(charArray, offset, cbuf, 0, oldBase - offset); - System.arraycopy(charAttributes, offset, abuf, 0, oldBase - offset); - } - // copy anything from the top of the screen (screenBase) up to the - // topMargin to the new screen - if (top > 0) { - System.arraycopy(charArray, oldBase, cbuf, newScreenBase, top); - System.arraycopy(charAttributes, oldBase, abuf, newScreenBase, top); - } - // copy anything from the topMargin up to the amount of lines inserted - // to the gap left over between scrollback buffer and screenBase - if (oldBase >= 0) { - System.arraycopy(charArray, oldBase + top, cbuf, oldBase - offset, n); - System.arraycopy(charAttributes, oldBase + top, abuf, oldBase - offset, n); - } - // copy anything from topMargin + n up to the line linserted to the - // topMargin - System - .arraycopy(charArray, oldBase + top + n, cbuf, newScreenBase + top, l - top - (n - 1)); - System.arraycopy(charAttributes, oldBase + top + n, abuf, newScreenBase + top, l - top - - (n - 1)); - // - // copy the all lines next to the inserted to the new buffer - if (l < height - 1) { - System.arraycopy(charArray, oldBase + l + 1, cbuf, newScreenBase + l + 1, (height - 1) - - l); - System.arraycopy(charAttributes, oldBase + l + 1, abuf, newScreenBase + l + 1, - (height - 1) - l); - } - } catch (ArrayIndexOutOfBoundsException e) { - // this should not happen anymore, but I will leave the code - // here in case something happens anyway. That code above is - // so complex I always have a hard time understanding what - // I did, even though there are comments - System.err.println("*** Error while scrolling up:"); - System.err.println("--- BEGIN STACK TRACE ---"); - e.printStackTrace(); - System.err.println("--- END STACK TRACE ---"); - System.err.println("bufSize=" + bufSize + ", maxBufSize=" + maxBufSize); - System.err.println("top=" + top + ", bottom=" + bottom); - System.err.println("n=" + n + ", l=" + l); - System.err.println("screenBase=" + screenBase + ", windowBase=" + windowBase); - System.err.println("newScreenBase=" + newScreenBase + ", newWindowBase=" + newWindowBase); - System.err.println("oldBase=" + oldBase); - System.err.println("size.width=" + width + ", size.height=" + height); - System.err.println("abuf.length=" + abuf.length + ", cbuf.length=" + cbuf.length); - System.err.println("*** done dumping debug information"); - } - } - - // this is a little helper to mark the scrolling - scrollMarker -= n; - - for (int i = 0; i < n; i++) { - cbuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new char[width]; - Arrays.fill(cbuf[(newScreenBase + l) + (scrollDown ? i : -i)], ' '); - abuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new int[width]; - } - - charArray = cbuf; - charAttributes = abuf; - screenBase = newScreenBase; - windowBase = newWindowBase; - bufSize = newBufSize; - - if (scrollDown) { - markLine(l, bottom - l + 1); - } else { - markLine(top, l - top + 1); - } - - display.updateScrollBar(); - } - - /** - * Delete a line at a specific position. Subsequent lines will be scrolled up to fill the space - * and a blank line is inserted at the end of the screen. - * - * @param l - * the y-coordinate to insert the line - * @see #deleteLine - */ - public void deleteLine(int l) { - int bottom = (l > bottomMargin ? height - 1 : (l < topMargin ? topMargin : bottomMargin + 1)); - int numRows = bottom - l - 1; - - char[] discardedChars = charArray[screenBase + l]; - int[] discardedAttributes = charAttributes[screenBase + l]; - - if (numRows > 0) { - System.arraycopy(charArray, screenBase + l + 1, charArray, screenBase + l, numRows); - System.arraycopy(charAttributes, screenBase + l + 1, charAttributes, screenBase + l, numRows); - } - - int newBottomRow = screenBase + bottom - 1; - charArray[newBottomRow] = discardedChars; - charAttributes[newBottomRow] = discardedAttributes; - Arrays.fill(charArray[newBottomRow], ' '); - Arrays.fill(charAttributes[newBottomRow], 0); - - markLine(l, bottom - l); - } - - /** - * Delete a rectangular portion of the screen. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (row) - * @param w - * with of the area in characters - * @param h - * height of the area in characters - * @param curAttr - * attribute to fill - * @see #deleteChar - * @see #deleteLine - * @see #redraw - */ - public void deleteArea(int c, int l, int w, int h, int curAttr) { - int endColumn = c + w; - int targetRow = screenBase + l; - for (int i = 0; i < h && l + i < height; i++) { - Arrays.fill(charAttributes[targetRow], c, endColumn, curAttr); - Arrays.fill(charArray[targetRow], c, endColumn, ' '); - targetRow++; - } - markLine(l, h); - } - - /** - * Delete a rectangular portion of the screen. You need to call redraw() to update the screen. - * - * @param c - * x-coordinate (column) - * @param l - * y-coordinate (row) - * @param w - * with of the area in characters - * @param h - * height of the area in characters - * @see #deleteChar - * @see #deleteLine - * @see #redraw - */ - public void deleteArea(int c, int l, int w, int h) { - deleteArea(c, l, w, h, 0); - } - - /** - * Sets whether the cursor is visible or not. - * - * @param doshow - */ - public void showCursor(boolean doshow) { - showcursor = doshow; - } - - /** - * Check whether the cursor is currently visible. - * - * @return visibility - */ - public boolean isCursorVisible() { - return showcursor; - } - - /** - * Puts the cursor at the specified position. - * - * @param c - * column - * @param l - * line - */ - public void setCursorPosition(int c, int l) { - cursorX = c; - cursorY = l; - } - - /** - * Get the current column of the cursor position. - */ - public int getCursorColumn() { - return cursorX; - } - - /** - * Get the current line of the cursor position. - */ - public int getCursorRow() { - return cursorY; - } - - /** - * Set the current window base. This allows to view the scrollback buffer. - * - * @param line - * the line where the screen window starts - * @see #setBufferSize - * @see #getBufferSize - */ - public void setWindowBase(int line) { - if (line > screenBase) { - line = screenBase; - } else if (line < 0) { - line = 0; - } - windowBase = line; - update[0] = true; - redraw(); - } - - /** - * Get the current window base. - * - * @see #setWindowBase - */ - public int getWindowBase() { - return windowBase; - } - - /** - * Set the scroll margins simultaneously. If they're out of bounds, trim them. - * - * @param l1 - * line that is the top - * @param l2 - * line that is the bottom - */ - public void setMargins(int l1, int l2) { - if (l1 > l2) { - return; - } - - if (l1 < 0) { - l1 = 0; - } - if (l2 >= height) { - l2 = height - 1; - } - - topMargin = l1; - bottomMargin = l2; - } - - /** - * Set the top scroll margin for the screen. If the current bottom margin is smaller it will - * become the top margin and the line will become the bottom margin. - * - * @param l - * line that is the margin - */ - public void setTopMargin(int l) { - if (l > bottomMargin) { - topMargin = bottomMargin; - bottomMargin = l; - } else { - topMargin = l; - } - if (topMargin < 0) { - topMargin = 0; - } - if (bottomMargin >= height) { - bottomMargin = height - 1; - } - } - - /** - * Get the top scroll margin. - */ - public int getTopMargin() { - return topMargin; - } - - /** - * Set the bottom scroll margin for the screen. If the current top margin is bigger it will become - * the bottom margin and the line will become the top margin. - * - * @param l - * line that is the margin - */ - public void setBottomMargin(int l) { - if (l < topMargin) { - bottomMargin = topMargin; - topMargin = l; - } else { - bottomMargin = l; - } - if (topMargin < 0) { - topMargin = 0; - } - if (bottomMargin >= height) { - bottomMargin = height - 1; - } - } - - /** - * Get the bottom scroll margin. - */ - public int getBottomMargin() { - return bottomMargin; - } - - /** - * Set scrollback buffer size. - * - * @param amount - * new size of the buffer - */ - public void setBufferSize(int amount) { - if (amount < height) { - amount = height; - } - if (amount < maxBufSize) { - char cbuf[][] = new char[amount][width]; - int abuf[][] = new int[amount][width]; - int copyStart = bufSize - amount < 0 ? 0 : bufSize - amount; - int copyCount = bufSize - amount < 0 ? bufSize : amount; - if (charArray != null) { - System.arraycopy(charArray, copyStart, cbuf, 0, copyCount); - } - if (charAttributes != null) { - System.arraycopy(charAttributes, copyStart, abuf, 0, copyCount); - } - charArray = cbuf; - charAttributes = abuf; - bufSize = copyCount; - screenBase = bufSize - height; - windowBase = screenBase; - } - maxBufSize = amount; - - update[0] = true; - redraw(); - } - - /** - * Retrieve current scrollback buffer size. - * - * @see #setBufferSize - */ - public int getBufferSize() { - return bufSize; - } - - /** - * Retrieve maximum buffer Size. - * - * @see #getBufferSize - */ - public int getMaxBufferSize() { - return maxBufSize; - } - - /** - * Change the size of the screen. This will include adjustment of the scrollback buffer. - * - * @param w - * of the screen - * @param h - * of the screen - */ - @SuppressWarnings("unused") - public void setScreenSize(int w, int h, boolean broadcast) { - char cbuf[][]; - int abuf[][]; - int maxSize = bufSize; - - if (w < 1 || h < 1) { - return; - } - - if (debug > 0) { - System.err.println("VDU: screen size [" + w + "," + h + "]"); - } - - if (h > maxBufSize) { - maxBufSize = h; - } - - if (h > bufSize) { - bufSize = h; - screenBase = 0; - windowBase = 0; - } - - if (windowBase + h >= bufSize) { - windowBase = bufSize - h; - } - - if (screenBase + h >= bufSize) { - screenBase = bufSize - h; - } - - cbuf = new char[bufSize][w]; - abuf = new int[bufSize][w]; - - for (int i = 0; i < bufSize; i++) { - Arrays.fill(cbuf[i], ' '); - } - - if (bufSize < maxSize) { - maxSize = bufSize; - } - - int rowLength; - if (charArray != null && charAttributes != null) { - for (int i = 0; i < maxSize && charArray[i] != null; i++) { - rowLength = charArray[i].length; - System.arraycopy(charArray[i], 0, cbuf[i], 0, w < rowLength ? w : rowLength); - System.arraycopy(charAttributes[i], 0, abuf[i], 0, w < rowLength ? w : rowLength); - } - } - - int C = getCursorColumn(); - if (C < 0) { - C = 0; - } else if (C >= width) { - C = width - 1; - } - - int R = getCursorRow(); - if (R < 0) { - R = 0; - } else if (R >= height) { - R = height - 1; - } - - setCursorPosition(C, R); - - charArray = cbuf; - charAttributes = abuf; - width = w; - height = h; - topMargin = 0; - bottomMargin = h - 1; - update = new boolean[h + 1]; - update[0] = true; - /* - * FIXME: ??? if(resizeStrategy == RESIZE_FONT) setBounds(getBounds()); - */ - } - - /** - * Get amount of rows on the screen. - */ - public int getRows() { - return height; - } - - /** - * Get amount of columns on the screen. - */ - public int getColumns() { - return width; - } - - /** - * Mark lines to be updated with redraw(). - * - * @param l - * starting line - * @param n - * amount of lines to be updated - * @see #redraw - */ - public void markLine(int l, int n) { - for (int i = 0; (i < n) && (l + i < height); i++) { - update[l + i + 1] = true; - } - } - - // private static int checkBounds(int value, int lower, int upper) { - // if (value < lower) - // return lower; - // else if (value > upper) - // return upper; - // else - // return value; - // } - - /** a generic display that should redraw on demand */ - protected VDUDisplay display; - - public void setDisplay(VDUDisplay display) { - this.display = display; - } - - /** - * Trigger a redraw on the display. - */ - protected void redraw() { - if (display != null) { - display.redraw(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUDisplay.java b/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUDisplay.java deleted file mode 100644 index 0fe06f3..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUDisplay.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform". - * - * (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved. - * - * Please visit http://javatelnet.org/ for updates and contact. - * - * --LICENSE NOTICE-- - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * --LICENSE NOTICE-- - * - */ - -package de.mud.terminal; - -/** - * Generic display - */ -public interface VDUDisplay { - public void redraw(); - public void updateScrollBar(); - - public void setVDUBuffer(VDUBuffer buffer); - public VDUBuffer getVDUBuffer(); - - public void setColor(int index, int red, int green, int blue); - public void resetColors(); -} diff --git a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUInput.java b/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUInput.java deleted file mode 100644 index 43c88de..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/VDUInput.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform". - * - * (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved. - * - * Please visit http://javatelnet.org/ for updates and contact. - * - * --LICENSE NOTICE-- - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * --LICENSE NOTICE-- - * - */ -package de.mud.terminal; - -import java.util.Properties; - -/** - * An interface for a terminal that accepts input from keyboard and mouse. - * - * @author Matthias L. Jugel, Marcus Meißner - * @version $Id: VDUInput.java 499 2005-09-29 08:24:54Z leo $ - */ -public interface VDUInput { - - public final static int KEY_CONTROL = 0x01; - public final static int KEY_SHIFT = 0x02; - public final static int KEY_ALT = 0x04; - public final static int KEY_ACTION = 0x08; - - - - /** - * Direct access to writing data ... - * @param b - */ - void write(byte b[]); - - /** - * Terminal is mouse-aware and requires (x,y) coordinates of - * on the terminal (character coordinates) and the button clicked. - * @param x - * @param y - * @param modifiers - */ - void mousePressed(int x, int y, int modifiers); - - /** - * Terminal is mouse-aware and requires the coordinates and button - * of the release. - * @param x - * @param y - * @param modifiers - */ - void mouseReleased(int x, int y, int modifiers); - - /** - * Override the standard key codes used by the terminal emulation. - * @param codes a properties object containing key code definitions - */ - void setKeyCodes(Properties codes); - - /** - * main keytyping event handler... - * @param keyCode the key code - * @param keyChar the character represented by the key - * @param modifiers shift/alt/control modifiers - */ - void keyPressed(int keyCode, char keyChar, int modifiers); - - /** - * Handle key Typed events for the terminal, this will get - * all normal key types, but no shift/alt/control/numlock. - * @param keyCode the key code - * @param keyChar the character represented by the key - * @param modifiers shift/alt/control modifiers - */ - void keyTyped(int keyCode, char keyChar, int modifiers); -} diff --git a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/vt320.java b/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/vt320.java deleted file mode 100644 index b713228..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/de/mud/terminal/vt320.java +++ /dev/null @@ -1,3236 +0,0 @@ -/* - * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform". - * - * (c) Matthias L. Jugel, Marcus Meiner 1996-2005. All Rights Reserved. - * - * Please visit http://javatelnet.org/ for updates and contact. - * - * --LICENSE NOTICE-- - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * --LICENSE NOTICE-- - * - */ - -package de.mud.terminal; - -import java.util.Properties; - -/** - * Implementation of a VT terminal emulation plus ANSI compatible. - * <P> - * <B>Maintainer:</B> Marcus Meißner - * - * @version $Id: vt320.java 507 2005-10-25 10:14:52Z marcus $ - * @author Matthias L. Jugel, Marcus Meißner - */ -@SuppressWarnings("unused") -public abstract class vt320 extends VDUBuffer implements VDUInput { - - /** - * The current version id tag. - * <P> - * $Id: vt320.java 507 2005-10-25 10:14:52Z marcus $ - * - */ - public final static String ID = "$Id: vt320.java 507 2005-10-25 10:14:52Z marcus $"; - - /** the debug level */ - private final static int debug = 0; - private StringBuilder debugStr; - - public abstract void debug(String notice); - - /** - * Write an answer back to the remote host. This is needed to be able to send terminal answers - * requests like status and type information. - * - * @param b - * the array of bytes to be sent - */ - public abstract void write(byte[] b); - - /** - * Write an answer back to the remote host. This is needed to be able to send terminal answers - * requests like status and type information. - * - * @param b - * the array of bytes to be sent - */ - public abstract void write(int b); - - /** - * Play the beep sound ... - */ - public void beep() { /* do nothing by default */ - } - - /** - * Convenience function for putString(char[], int, int) - */ - public void putString(String s) { - int len = s.length(); - char[] tmp = new char[len]; - s.getChars(0, len, tmp, 0); - putString(tmp, null, 0, len); - } - - /** - * Put string at current cursor position. Moves cursor according to the String. Does NOT wrap. - * - * @param s - * character array - * @param start - * place to start in array - * @param len - * number of characters to process - */ - public void putString(char[] s, byte[] fullwidths, int start, int len) { - if (len > 0) { - // markLine(R, 1); - int lastChar = -1; - char c; - boolean isWide = false; - - for (int i = 0; i < len; i++) { - c = s[start + i]; - // Shortcut for my favorite ASCII - if (c <= 0x7F) { - if (lastChar != -1) { - putChar((char) lastChar, isWide, false); - } - lastChar = c; - isWide = false; - } else if (!Character.isLowSurrogate(c) && !Character.isHighSurrogate(c)) { - if (Character.getType(c) == Character.NON_SPACING_MARK) { - if (lastChar != -1) { - char nc = Precomposer.precompose((char) lastChar, c); - putChar(nc, isWide, false); - lastChar = -1; - } - } else { - if (lastChar != -1) { - putChar((char) lastChar, isWide, false); - } - lastChar = c; - if (fullwidths != null) { - isWide = fullwidths[i] == 1; - } - } - } - } - - if (lastChar != -1) { - putChar((char) lastChar, isWide, false); - } - - setCursorPosition(C, R); - redraw(); - } - } - - protected void sendTelnetCommand(byte cmd) { - - } - - /** - * Sent the changed window size from the terminal to all listeners. - */ - protected void setWindowSize(int c, int r) { - /* To be overridden by Terminal.java */ - } - - @Override - public void setScreenSize(int c, int r, boolean broadcast) { - // int oldrows = height; - - if (debug > 2) { - if (debugStr == null) { - debugStr = new StringBuilder(); - } - - debugStr.append("setscreensize (").append(c).append(',').append(r).append(',') - .append(broadcast).append(')'); - debug(debugStr.toString()); - debugStr.setLength(0); - } - - super.setScreenSize(c, r, false); - - boolean cursorChanged = false; - - // Don't let the cursor go off the screen. - if (C >= c) { - C = c - 1; - cursorChanged = true; - } - - if (R >= r) { - R = r - 1; - cursorChanged = true; - } - - if (cursorChanged) { - setCursorPosition(C, R); - redraw(); - } - - if (broadcast) { - setWindowSize(c, r); /* broadcast up */ - } - } - - /** - * Create a new vt320 terminal and intialize it with useful settings. - */ - public vt320(int width, int height) { - super(width, height); - - debugStr = new StringBuilder(); - - setVMS(false); - setIBMCharset(false); - setTerminalID("vt320"); - setBufferSize(100); - // setBorder(2, false); - - gx = new char[4]; - reset(); - - /* top row of numpad */ - PF1 = "\u001bOP"; - PF2 = "\u001bOQ"; - PF3 = "\u001bOR"; - PF4 = "\u001bOS"; - - /* the 3x2 keyblock on PC keyboards */ - Insert = new String[4]; - Remove = new String[4]; - KeyHome = new String[4]; - KeyEnd = new String[4]; - NextScn = new String[4]; - PrevScn = new String[4]; - Escape = new String[4]; - BackSpace = new String[4]; - TabKey = new String[4]; - Insert[0] = Insert[1] = Insert[2] = Insert[3] = "\u001b[2~"; - Remove[0] = Remove[1] = Remove[2] = Remove[3] = "\u001b[3~"; - PrevScn[0] = PrevScn[1] = PrevScn[2] = PrevScn[3] = "\u001b[5~"; - NextScn[0] = NextScn[1] = NextScn[2] = NextScn[3] = "\u001b[6~"; - KeyHome[0] = KeyHome[1] = KeyHome[2] = KeyHome[3] = "\u001b[H"; - KeyEnd[0] = KeyEnd[1] = KeyEnd[2] = KeyEnd[3] = "\u001b[F"; - Escape[0] = Escape[1] = Escape[2] = Escape[3] = "\u001b"; - if (vms) { - BackSpace[1] = "" + (char) 10; // VMS shift deletes word back - BackSpace[2] = "\u0018"; // VMS control deletes line back - BackSpace[0] = BackSpace[3] = "\u007f"; // VMS other is delete - } else { - // BackSpace[0] = BackSpace[1] = BackSpace[2] = BackSpace[3] = "\b"; - // ConnectBot modifications. - BackSpace[0] = "\b"; - BackSpace[1] = "\u007f"; - BackSpace[2] = "\u001b[3~"; - BackSpace[3] = "\u001b[2~"; - } - - /* some more VT100 keys */ - Find = "\u001b[1~"; - Select = "\u001b[4~"; - Help = "\u001b[28~"; - Do = "\u001b[29~"; - - FunctionKey = new String[21]; - FunctionKey[0] = ""; - FunctionKey[1] = PF1; - FunctionKey[2] = PF2; - FunctionKey[3] = PF3; - FunctionKey[4] = PF4; - /* following are defined differently for vt220 / vt132 ... */ - FunctionKey[5] = "\u001b[15~"; - FunctionKey[6] = "\u001b[17~"; - FunctionKey[7] = "\u001b[18~"; - FunctionKey[8] = "\u001b[19~"; - FunctionKey[9] = "\u001b[20~"; - FunctionKey[10] = "\u001b[21~"; - FunctionKey[11] = "\u001b[23~"; - FunctionKey[12] = "\u001b[24~"; - FunctionKey[13] = "\u001b[25~"; - FunctionKey[14] = "\u001b[26~"; - FunctionKey[15] = Help; - FunctionKey[16] = Do; - FunctionKey[17] = "\u001b[31~"; - FunctionKey[18] = "\u001b[32~"; - FunctionKey[19] = "\u001b[33~"; - FunctionKey[20] = "\u001b[34~"; - - FunctionKeyShift = new String[21]; - FunctionKeyAlt = new String[21]; - FunctionKeyCtrl = new String[21]; - - for (int i = 0; i < 20; i++) { - FunctionKeyShift[i] = ""; - FunctionKeyAlt[i] = ""; - FunctionKeyCtrl[i] = ""; - } - FunctionKeyShift[15] = Find; - FunctionKeyShift[16] = Select; - - TabKey[0] = "\u0009"; - TabKey[1] = "\u001bOP\u0009"; - TabKey[2] = TabKey[3] = ""; - - KeyUp = new String[4]; - KeyUp[0] = "\u001b[A"; - KeyDown = new String[4]; - KeyDown[0] = "\u001b[B"; - KeyRight = new String[4]; - KeyRight[0] = "\u001b[C"; - KeyLeft = new String[4]; - KeyLeft[0] = "\u001b[D"; - Numpad = new String[10]; - Numpad[0] = "\u001bOp"; - Numpad[1] = "\u001bOq"; - Numpad[2] = "\u001bOr"; - Numpad[3] = "\u001bOs"; - Numpad[4] = "\u001bOt"; - Numpad[5] = "\u001bOu"; - Numpad[6] = "\u001bOv"; - Numpad[7] = "\u001bOw"; - Numpad[8] = "\u001bOx"; - Numpad[9] = "\u001bOy"; - KPMinus = PF4; - KPComma = "\u001bOl"; - KPPeriod = "\u001bOn"; - KPEnter = "\u001bOM"; - - NUMPlus = new String[4]; - NUMPlus[0] = "+"; - NUMDot = new String[4]; - NUMDot[0] = "."; - } - - public void setBackspace(int type) { - switch (type) { - case DELETE_IS_DEL: - BackSpace[0] = "\u007f"; - BackSpace[1] = "\b"; - break; - case DELETE_IS_BACKSPACE: - BackSpace[0] = "\b"; - BackSpace[1] = "\u007f"; - break; - } - } - - /** - * Create a default vt320 terminal with 80 columns and 24 lines. - */ - public vt320() { - this(80, 24); - } - - /** - * Terminal is mouse-aware and requires (x,y) coordinates of on the terminal (character - * coordinates) and the button clicked. - * - * @param x - * @param y - * @param modifiers - */ - public void mousePressed(int x, int y, int modifiers) { - if (mouserpt == 0) { - return; - } - - int mods = modifiers; - mousebut = 3; - if ((mods & 16) == 16) { - mousebut = 0; - } - if ((mods & 8) == 8) { - mousebut = 1; - } - if ((mods & 4) == 4) { - mousebut = 2; - } - - int mousecode; - if (mouserpt == 9) { - mousecode = 0x20 | mousebut; - } else { - mousecode = mousebut | 0x20 | ((mods & 7) << 2); - } - - byte b[] = new byte[6]; - - b[0] = 27; - b[1] = (byte) '['; - b[2] = (byte) 'M'; - b[3] = (byte) mousecode; - b[4] = (byte) (0x20 + x + 1); - b[5] = (byte) (0x20 + y + 1); - - write(b); // FIXME: writeSpecial here - } - - /** - * Terminal is mouse-aware and requires the coordinates and button of the release. - * - * @param x - * @param y - * @param modifiers - */ - public void mouseReleased(int x, int y, int modifiers) { - if (mouserpt == 0) { - return; - } - - /* - * problem is tht modifiers still have the released button set in them. int mods = modifiers; - * mousebut = 3; if ((mods & 16)==16) mousebut=0; if ((mods & 8)==8 ) mousebut=1; if ((mods & - * 4)==4 ) mousebut=2; - */ - - int mousecode; - if (mouserpt == 9) { - mousecode = 0x20 + mousebut; /* same as press? appears so. */ - } else { - mousecode = '#'; - } - - byte b[] = new byte[6]; - b[0] = 27; - b[1] = (byte) '['; - b[2] = (byte) 'M'; - b[3] = (byte) mousecode; - b[4] = (byte) (0x20 + x + 1); - b[5] = (byte) (0x20 + y + 1); - write(b); // FIXME: writeSpecial here - mousebut = 0; - } - - /** we should do localecho (passed from other modules). false is default */ - private boolean localecho = false; - - /** - * Enable or disable the local echo property of the terminal. - * - * @param echo - * true if the terminal should echo locally - */ - public void setLocalEcho(boolean echo) { - localecho = echo; - } - - /** - * Enable the VMS mode of the terminal to handle some things differently for VMS hosts. - * - * @param vms - * true for vms mode, false for normal mode - */ - public void setVMS(boolean vms) { - this.vms = vms; - } - - /** - * Enable the usage of the IBM character set used by some BBS's. Special graphical character are - * available in this mode. - * - * @param ibm - * true to use the ibm character set - */ - public void setIBMCharset(boolean ibm) { - useibmcharset = ibm; - } - - /** - * Override the standard key codes used by the terminal emulation. - * - * @param codes - * a properties object containing key code definitions - */ - public void setKeyCodes(Properties codes) { - String res, prefixes[] = { "", "S", "C", "A" }; - int i; - - for (i = 0; i < 10; i++) { - res = codes.getProperty("NUMPAD" + i); - if (res != null) { - Numpad[i] = unEscape(res); - } - } - for (i = 1; i < 20; i++) { - res = codes.getProperty("F" + i); - if (res != null) { - FunctionKey[i] = unEscape(res); - } - res = codes.getProperty("SF" + i); - if (res != null) { - FunctionKeyShift[i] = unEscape(res); - } - res = codes.getProperty("CF" + i); - if (res != null) { - FunctionKeyCtrl[i] = unEscape(res); - } - res = codes.getProperty("AF" + i); - if (res != null) { - FunctionKeyAlt[i] = unEscape(res); - } - } - for (i = 0; i < 4; i++) { - res = codes.getProperty(prefixes[i] + "PGUP"); - if (res != null) { - PrevScn[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "PGDOWN"); - if (res != null) { - NextScn[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "END"); - if (res != null) { - KeyEnd[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "HOME"); - if (res != null) { - KeyHome[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "INSERT"); - if (res != null) { - Insert[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "REMOVE"); - if (res != null) { - Remove[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "UP"); - if (res != null) { - KeyUp[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "DOWN"); - if (res != null) { - KeyDown[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "LEFT"); - if (res != null) { - KeyLeft[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "RIGHT"); - if (res != null) { - KeyRight[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "ESCAPE"); - if (res != null) { - Escape[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "BACKSPACE"); - if (res != null) { - BackSpace[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "TAB"); - if (res != null) { - TabKey[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "NUMPLUS"); - if (res != null) { - NUMPlus[i] = unEscape(res); - } - res = codes.getProperty(prefixes[i] + "NUMDECIMAL"); - if (res != null) { - NUMDot[i] = unEscape(res); - } - } - } - - /** - * Set the terminal id used to identify this terminal. - * - * @param terminalID - * the id string - */ - public void setTerminalID(String terminalID) { - this.terminalID = terminalID; - - if (terminalID.equals("scoansi")) { - FunctionKey[1] = "\u001b[M"; - FunctionKey[2] = "\u001b[N"; - FunctionKey[3] = "\u001b[O"; - FunctionKey[4] = "\u001b[P"; - FunctionKey[5] = "\u001b[Q"; - FunctionKey[6] = "\u001b[R"; - FunctionKey[7] = "\u001b[S"; - FunctionKey[8] = "\u001b[T"; - FunctionKey[9] = "\u001b[U"; - FunctionKey[10] = "\u001b[V"; - FunctionKey[11] = "\u001b[W"; - FunctionKey[12] = "\u001b[X"; - FunctionKey[13] = "\u001b[Y"; - FunctionKey[14] = "?"; - FunctionKey[15] = "\u001b[a"; - FunctionKey[16] = "\u001b[b"; - FunctionKey[17] = "\u001b[c"; - FunctionKey[18] = "\u001b[d"; - FunctionKey[19] = "\u001b[e"; - FunctionKey[20] = "\u001b[f"; - PrevScn[0] = PrevScn[1] = PrevScn[2] = PrevScn[3] = "\u001b[I"; - NextScn[0] = NextScn[1] = NextScn[2] = NextScn[3] = "\u001b[G"; - // more theoretically. - } - } - - public void setAnswerBack(String ab) { - answerBack = unEscape(ab); - } - - /** - * Get the terminal id used to identify this terminal. - */ - public String getTerminalID() { - return terminalID; - } - - /** - * A small conveniance method thar converts the string to a byte array for sending. - * - * @param s - * the string to be sent - */ - private boolean write(String s, boolean doecho) { - if (debug > 2) { - debugStr.append("write(|").append(s).append("|,").append(doecho); - debug(debugStr.toString()); - debugStr.setLength(0); - } - if (s == null) { - return true; - /* - * NOTE: getBytes() honours some locale, it *CONVERTS* the string. However, we output only - * 7bit stuff towards the target, and *some* 8 bit control codes. We must not mess up the - * latter, so we do hand by hand copy. - */ - } - - byte arr[] = new byte[s.length()]; - for (int i = 0; i < s.length(); i++) { - arr[i] = (byte) s.charAt(i); - } - write(arr); - - if (doecho) { - putString(s); - } - return true; - } - - private boolean write(int s, boolean doecho) { - if (debug > 2) { - debugStr.append("write(|").append(s).append("|,").append(doecho); - debug(debugStr.toString()); - debugStr.setLength(0); - } - - write(s); - - // TODO check if character is wide - if (doecho) { - putChar((char) s, false, false); - } - return true; - } - - private boolean write(String s) { - return write(s, localecho); - } - - // =================================================================== - // the actual terminal emulation code comes here: - // =================================================================== - - private String terminalID = "vt320"; - private String answerBack = "Use Terminal.answerback to set ...\n"; - - // X - COLUMNS, Y - ROWS - int R, C; - int attributes = 0; - - int Sc, Sr, Sa, Stm, Sbm; - char Sgr, Sgl; - char Sgx[]; - - int insertmode = 0; - int statusmode = 0; - boolean vt52mode = false; - boolean keypadmode = false; /* false - numeric, true - application */ - boolean output8bit = false; - int normalcursor = 0; - boolean moveoutsidemargins = true; - boolean wraparound = true; - boolean sendcrlf = true; - boolean capslock = false; - boolean numlock = false; - int mouserpt = 0; - byte mousebut = 0; - - boolean useibmcharset = false; - - int lastwaslf = 0; - boolean usedcharsets = false; - - private final static char ESC = 27; - private final static char IND = 132; - private final static char NEL = 133; - private final static char RI = 141; - private final static char SS2 = 142; - private final static char SS3 = 143; - private final static char DCS = 144; - private final static char HTS = 136; - private final static char CSI = 155; - private final static char OSC = 157; - private final static int TSTATE_DATA = 0; - private final static int TSTATE_ESC = 1; /* ESC */ - private final static int TSTATE_CSI = 2; /* ESC [ */ - private final static int TSTATE_DCS = 3; /* ESC P */ - private final static int TSTATE_DCEQ = 4; /* ESC [? */ - private final static int TSTATE_ESCSQUARE = 5; /* ESC # */ - private final static int TSTATE_OSC = 6; /* ESC ] */ - private final static int TSTATE_SETG0 = 7; /* ESC (? */ - private final static int TSTATE_SETG1 = 8; /* ESC )? */ - private final static int TSTATE_SETG2 = 9; /* ESC *? */ - private final static int TSTATE_SETG3 = 10; /* ESC +? */ - private final static int TSTATE_CSI_DOLLAR = 11; /* ESC [ Pn $ */ - private final static int TSTATE_CSI_EX = 12; /* ESC [ ! */ - private final static int TSTATE_ESCSPACE = 13; /* ESC <space> */ - private final static int TSTATE_VT52X = 14; - private final static int TSTATE_VT52Y = 15; - private final static int TSTATE_CSI_TICKS = 16; - private final static int TSTATE_CSI_EQUAL = 17; /* ESC [ = */ - private final static int TSTATE_TITLE = 18; /* xterm title */ - - /* Keys we support */ - public final static int KEY_PAUSE = 1; - public final static int KEY_F1 = 2; - public final static int KEY_F2 = 3; - public final static int KEY_F3 = 4; - public final static int KEY_F4 = 5; - public final static int KEY_F5 = 6; - public final static int KEY_F6 = 7; - public final static int KEY_F7 = 8; - public final static int KEY_F8 = 9; - public final static int KEY_F9 = 10; - public final static int KEY_F10 = 11; - public final static int KEY_F11 = 12; - public final static int KEY_F12 = 13; - public final static int KEY_UP = 14; - public final static int KEY_DOWN = 15; - public final static int KEY_LEFT = 16; - public final static int KEY_RIGHT = 17; - public final static int KEY_PAGE_DOWN = 18; - public final static int KEY_PAGE_UP = 19; - public final static int KEY_INSERT = 20; - public final static int KEY_DELETE = 21; - public final static int KEY_BACK_SPACE = 22; - public final static int KEY_HOME = 23; - public final static int KEY_END = 24; - public final static int KEY_NUM_LOCK = 25; - public final static int KEY_CAPS_LOCK = 26; - public final static int KEY_SHIFT = 27; - public final static int KEY_CONTROL = 28; - public final static int KEY_ALT = 29; - public final static int KEY_ENTER = 30; - public final static int KEY_NUMPAD0 = 31; - public final static int KEY_NUMPAD1 = 32; - public final static int KEY_NUMPAD2 = 33; - public final static int KEY_NUMPAD3 = 34; - public final static int KEY_NUMPAD4 = 35; - public final static int KEY_NUMPAD5 = 36; - public final static int KEY_NUMPAD6 = 37; - public final static int KEY_NUMPAD7 = 38; - public final static int KEY_NUMPAD8 = 39; - public final static int KEY_NUMPAD9 = 40; - public final static int KEY_DECIMAL = 41; - public final static int KEY_ADD = 42; - public final static int KEY_ESCAPE = 43; - - public final static int DELETE_IS_DEL = 0; - public final static int DELETE_IS_BACKSPACE = 1; - - /* - * The graphics charsets B - default ASCII A - ISO Latin 1 0 - DEC SPECIAL < - User defined .... - */ - char gx[]; - char gl; // GL (left charset) - char gr; // GR (right charset) - int onegl; // single shift override for GL. - - // Map from scoansi linedrawing to DEC _and_ unicode (for the stuff which - // is not in linedrawing). Got from experimenting with scoadmin. - private final static String scoansi_acs = - "Tm7k3x4u?kZl@mYjEnB\u2566DqCtAvM\u2550:\u2551N\u2557I\u2554;\u2557H\u255a0a<\u255d"; - // array to store DEC Special -> Unicode mapping - // Unicode DEC Unicode name (DEC name) - private static char DECSPECIAL[] = { '\u0040', // 5f blank - '\u2666', // 60 black diamond - '\u2592', // 61 grey square - '\u2409', // 62 Horizontal tab (ht) pict. for control - '\u240c', // 63 Form Feed (ff) pict. for control - '\u240d', // 64 Carriage Return (cr) pict. for control - '\u240a', // 65 Line Feed (lf) pict. for control - '\u00ba', // 66 Masculine ordinal indicator - '\u00b1', // 67 Plus or minus sign - '\u2424', // 68 New Line (nl) pict. for control - '\u240b', // 69 Vertical Tab (vt) pict. for control - '\u2518', // 6a Forms light up and left - '\u2510', // 6b Forms light down and left - '\u250c', // 6c Forms light down and right - '\u2514', // 6d Forms light up and right - '\u253c', // 6e Forms light vertical and horizontal - '\u2594', // 6f Upper 1/8 block (Scan 1) - '\u2580', // 70 Upper 1/2 block (Scan 3) - '\u2500', // 71 Forms light horizontal or ?em dash? (Scan 5) - '\u25ac', // 72 \u25ac black rect. or \u2582 lower 1/4 (Scan 7) - '\u005f', // 73 \u005f underscore or \u2581 lower 1/8 (Scan 9) - '\u251c', // 74 Forms light vertical and right - '\u2524', // 75 Forms light vertical and left - '\u2534', // 76 Forms light up and horizontal - '\u252c', // 77 Forms light down and horizontal - '\u2502', // 78 vertical bar - '\u2264', // 79 less than or equal - '\u2265', // 7a greater than or equal - '\u00b6', // 7b paragraph - '\u2260', // 7c not equal - '\u00a3', // 7d Pound Sign (british) - '\u00b7' // 7e Middle Dot - }; - - /** Strings to send on function key pressing */ - private String Numpad[]; - private String FunctionKey[]; - private String FunctionKeyShift[]; - private String FunctionKeyCtrl[]; - private String FunctionKeyAlt[]; - private String TabKey[]; - private String KeyUp[], KeyDown[], KeyLeft[], KeyRight[]; - private String KPMinus, KPComma, KPPeriod, KPEnter; - private String PF1, PF2, PF3, PF4; - private String Help, Do, Find, Select; - - private String KeyHome[], KeyEnd[], Insert[], Remove[], PrevScn[], NextScn[]; - private String Escape[], BackSpace[], NUMDot[], NUMPlus[]; - - private String osc, dcs; /* to memorize OSC & DCS control sequence */ - - /** vt320 state variable (internal) */ - private int term_state = TSTATE_DATA; - /** in vms mode, set by Terminal.VMS property */ - private boolean vms = false; - /** Tabulators */ - private byte[] Tabs; - /** The list of integers as used by CSI */ - private int[] DCEvars = new int[30]; - private int DCEvar; - - /** - * Replace escape code characters (backslash + identifier) with their respective codes. - * - * @param tmp - * the string to be parsed - * @return a unescaped string - */ - static String unEscape(String tmp) { - int idx = 0, oldidx = 0; - String cmd; - // f.println("unescape("+tmp+")"); - cmd = ""; - while ((idx = tmp.indexOf('\\', oldidx)) >= 0 && ++idx <= tmp.length()) { - cmd += tmp.substring(oldidx, idx - 1); - if (idx == tmp.length()) { - return cmd; - } - switch (tmp.charAt(idx)) { - case 'b': - cmd += "\b"; - break; - case 'e': - cmd += "\u001b"; - break; - case 'n': - cmd += "\n"; - break; - case 'r': - cmd += "\r"; - break; - case 't': - cmd += "\t"; - break; - case 'v': - cmd += "\u000b"; - break; - case 'a': - cmd += "\u0012"; - break; - default: - if ((tmp.charAt(idx) >= '0') && (tmp.charAt(idx) <= '9')) { - int i; - for (i = idx; i < tmp.length(); i++) { - if ((tmp.charAt(i) < '0') || (tmp.charAt(i) > '9')) { - break; - } - } - cmd += (char) Integer.parseInt(tmp.substring(idx, i)); - idx = i - 1; - } else { - cmd += tmp.substring(idx, ++idx); - } - break; - } - oldidx = ++idx; - } - if (oldidx <= tmp.length()) { - cmd += tmp.substring(oldidx); - } - return cmd; - } - - /** - * A small conveniance method thar converts a 7bit string to the 8bit version depending on - * VT52/Output8Bit mode. - * - * @param s - * the string to be sent - */ - private boolean writeSpecial(String s) { - if (s == null) { - return true; - } - if (((s.length() >= 3) && (s.charAt(0) == 27) && (s.charAt(1) == 'O'))) { - if (vt52mode) { - if ((s.charAt(2) >= 'P') && (s.charAt(2) <= 'S')) { - s = "\u001b" + s.substring(2); /* ESC x */ - } else { - s = "\u001b?" + s.substring(2); /* ESC ? x */ - } - } else { - if (output8bit) { - s = "\u008f" + s.substring(2); /* SS3 x */ - } /* else keep string as it is */ - } - } - if (((s.length() >= 3) && (s.charAt(0) == 27) && (s.charAt(1) == '['))) { - if (output8bit) { - s = "\u009b" + s.substring(2); /* CSI ... */ - } /* else keep */ - } - return write(s, false); - } - - /** - * main keytyping event handler... - */ - public void keyPressed(int keyCode, char keyChar, int modifiers) { - boolean control = (modifiers & VDUInput.KEY_CONTROL) != 0; - boolean shift = (modifiers & VDUInput.KEY_SHIFT) != 0; - boolean alt = (modifiers & VDUInput.KEY_ALT) != 0; - - if (debug > 1) { - debugStr.append("keyPressed(").append(keyCode).append(", ").append((int) keyChar) - .append(", ").append(modifiers).append(')'); - debug(debugStr.toString()); - debugStr.setLength(0); - } - - int xind; - String fmap[]; - xind = 0; - fmap = FunctionKey; - if (shift) { - fmap = FunctionKeyShift; - xind = 1; - } - if (control) { - fmap = FunctionKeyCtrl; - xind = 2; - } - if (alt) { - fmap = FunctionKeyAlt; - xind = 3; - } - - switch (keyCode) { - case KEY_PAUSE: - if (shift || control) { - sendTelnetCommand((byte) 243); // BREAK - } - break; - case KEY_F1: - writeSpecial(fmap[1]); - break; - case KEY_F2: - writeSpecial(fmap[2]); - break; - case KEY_F3: - writeSpecial(fmap[3]); - break; - case KEY_F4: - writeSpecial(fmap[4]); - break; - case KEY_F5: - writeSpecial(fmap[5]); - break; - case KEY_F6: - writeSpecial(fmap[6]); - break; - case KEY_F7: - writeSpecial(fmap[7]); - break; - case KEY_F8: - writeSpecial(fmap[8]); - break; - case KEY_F9: - writeSpecial(fmap[9]); - break; - case KEY_F10: - writeSpecial(fmap[10]); - break; - case KEY_F11: - writeSpecial(fmap[11]); - break; - case KEY_F12: - writeSpecial(fmap[12]); - break; - case KEY_UP: - writeSpecial(KeyUp[xind]); - break; - case KEY_DOWN: - writeSpecial(KeyDown[xind]); - break; - case KEY_LEFT: - writeSpecial(KeyLeft[xind]); - break; - case KEY_RIGHT: - writeSpecial(KeyRight[xind]); - break; - case KEY_PAGE_DOWN: - writeSpecial(NextScn[xind]); - break; - case KEY_PAGE_UP: - writeSpecial(PrevScn[xind]); - break; - case KEY_INSERT: - writeSpecial(Insert[xind]); - break; - case KEY_DELETE: - writeSpecial(Remove[xind]); - break; - case KEY_BACK_SPACE: - writeSpecial(BackSpace[xind]); - if (localecho) { - if (BackSpace[xind] == "\b") { - putString("\b \b"); // make the last char 'deleted' - } else { - putString(BackSpace[xind]); // echo it - } - } - break; - case KEY_HOME: - writeSpecial(KeyHome[xind]); - break; - case KEY_END: - writeSpecial(KeyEnd[xind]); - break; - case KEY_NUM_LOCK: - if (vms && control) { - writeSpecial(PF1); - } - if (!control) { - numlock = !numlock; - } - break; - case KEY_CAPS_LOCK: - capslock = !capslock; - return; - case KEY_SHIFT: - case KEY_CONTROL: - case KEY_ALT: - return; - default: - break; - } - } - - /* - * public void keyReleased(KeyEvent evt) { if (debug > 1) debug("keyReleased("+evt+")"); // ignore - * } - */ - /** - * Handle key Typed events for the terminal, this will get all normal key types, but no - * shift/alt/control/numlock. - */ - public void keyTyped(int keyCode, char keyChar, int modifiers) { - boolean control = (modifiers & VDUInput.KEY_CONTROL) != 0; - boolean shift = (modifiers & VDUInput.KEY_SHIFT) != 0; - boolean alt = (modifiers & VDUInput.KEY_ALT) != 0; - - if (debug > 1) { - debug("keyTyped(" + keyCode + ", " + (int) keyChar + ", " + modifiers + ")"); - } - - if (keyChar == '\t') { - if (shift) { - write(TabKey[1], false); - } else { - if (control) { - write(TabKey[2], false); - } else { - if (alt) { - write(TabKey[3], false); - } else { - write(TabKey[0], false); - } - } - } - return; - } - if (alt) { - write(((char) (keyChar | 0x80))); - return; - } - - if (((keyCode == KEY_ENTER) || (keyChar == 10)) && !control) { - write('\r'); - if (localecho) { - putString("\r\n"); // bad hack - } - return; - } - - if ((keyCode == 10) && !control) { - debug("Sending \\r"); - write('\r'); - return; - } - - // FIXME: on german PC keyboards you have to use Alt-Ctrl-q to get an @, - // so we can't just use it here... will probably break some other VMS - // codes. -Marcus - // if(((!vms && keyChar == '2') || keyChar == '@' || keyChar == ' ') - // && control) - if (((!vms && keyChar == '2') || keyChar == ' ') && control) { - write(0); - } - - if (vms) { - if (keyChar == 127 && !control) { - if (shift) { - writeSpecial(Insert[0]); // VMS shift delete = insert - } else { - writeSpecial(Remove[0]); // VMS delete = remove - } - return; - } else if (control) { - switch (keyChar) { - case '0': - writeSpecial(Numpad[0]); - return; - case '1': - writeSpecial(Numpad[1]); - return; - case '2': - writeSpecial(Numpad[2]); - return; - case '3': - writeSpecial(Numpad[3]); - return; - case '4': - writeSpecial(Numpad[4]); - return; - case '5': - writeSpecial(Numpad[5]); - return; - case '6': - writeSpecial(Numpad[6]); - return; - case '7': - writeSpecial(Numpad[7]); - return; - case '8': - writeSpecial(Numpad[8]); - return; - case '9': - writeSpecial(Numpad[9]); - return; - case '.': - writeSpecial(KPPeriod); - return; - case '-': - case 31: - writeSpecial(KPMinus); - return; - case '+': - writeSpecial(KPComma); - return; - case 10: - writeSpecial(KPEnter); - return; - case '/': - writeSpecial(PF2); - return; - case '*': - writeSpecial(PF3); - return; - /* NUMLOCK handled in keyPressed */ - default: - break; - } - /* - * Now what does this do and how did it get here. -Marcus if (shift && keyChar < 32) { - * write(PF1+(char)(keyChar + 64)); return; } - */ - } - } - - // FIXME: not used? - // String fmap[]; - int xind; - xind = 0; - // fmap = FunctionKey; - if (shift) { - // fmap = FunctionKeyShift; - xind = 1; - } - if (control) { - // fmap = FunctionKeyCtrl; - xind = 2; - } - if (alt) { - // fmap = FunctionKeyAlt; - xind = 3; - } - - if (keyCode == KEY_ESCAPE) { - writeSpecial(Escape[xind]); - return; - } - - if ((modifiers & VDUInput.KEY_ACTION) != 0) { - switch (keyCode) { - case KEY_NUMPAD0: - writeSpecial(Numpad[0]); - return; - case KEY_NUMPAD1: - writeSpecial(Numpad[1]); - return; - case KEY_NUMPAD2: - writeSpecial(Numpad[2]); - return; - case KEY_NUMPAD3: - writeSpecial(Numpad[3]); - return; - case KEY_NUMPAD4: - writeSpecial(Numpad[4]); - return; - case KEY_NUMPAD5: - writeSpecial(Numpad[5]); - return; - case KEY_NUMPAD6: - writeSpecial(Numpad[6]); - return; - case KEY_NUMPAD7: - writeSpecial(Numpad[7]); - return; - case KEY_NUMPAD8: - writeSpecial(Numpad[8]); - return; - case KEY_NUMPAD9: - writeSpecial(Numpad[9]); - return; - case KEY_DECIMAL: - writeSpecial(NUMDot[xind]); - return; - case KEY_ADD: - writeSpecial(NUMPlus[xind]); - return; - } - } - - if (!((keyChar == 8) || (keyChar == 127) || (keyChar == '\r') || (keyChar == '\n'))) { - write(keyChar); - return; - } - } - - private void handle_dcs(String dcs) { - debugStr.append("DCS: ").append(dcs); - debug(debugStr.toString()); - debugStr.setLength(0); - } - - private void handle_osc(String osc) { - if (osc.length() > 2 && osc.substring(0, 2).equals("4;")) { - // Define color palette - String[] colorData = osc.split(";"); - - try { - int colorIndex = Integer.parseInt(colorData[1]); - - if ("rgb:".equals(colorData[2].substring(0, 4))) { - String[] rgb = colorData[2].substring(4).split("/"); - - int red = Integer.parseInt(rgb[0].substring(0, 2), 16) & 0xFF; - int green = Integer.parseInt(rgb[1].substring(0, 2), 16) & 0xFF; - int blue = Integer.parseInt(rgb[2].substring(0, 2), 16) & 0xFF; - display.setColor(colorIndex, red, green, blue); - } - } catch (Exception e) { - debugStr.append("OSC: invalid color sequence encountered: ").append(osc); - debug(debugStr.toString()); - debugStr.setLength(0); - } - } else { - debug("OSC: " + osc); - } - } - - private final static char unimap[] = { - // # - // # Name: cp437_DOSLatinUS to Unicode table - // # Unicode version: 1.1 - // # Table version: 1.1 - // # Table format: Format A - // # Date: 03/31/95 - // # Authors: Michel Suignard <michelsu@microsoft.com> - // # Lori Hoerth <lorih@microsoft.com> - // # General notes: none - // # - // # Format: Three tab-separated columns - // # Column #1 is the cp1255_WinHebrew code (in hex) - // # Column #2 is the Unicode (in hex as 0xXXXX) - // # Column #3 is the Unicode name (follows a comment sign, '#') - // # - // # The entries are in cp437_DOSLatinUS order - // # - - 0x0000, // #NULL - 0x0001, // #START OF HEADING - 0x0002, // #START OF TEXT - 0x0003, // #END OF TEXT - 0x0004, // #END OF TRANSMISSION - 0x0005, // #ENQUIRY - 0x0006, // #ACKNOWLEDGE - 0x0007, // #BELL - 0x0008, // #BACKSPACE - 0x0009, // #HORIZONTAL TABULATION - 0x000a, // #LINE FEED - 0x000b, // #VERTICAL TABULATION - 0x000c, // #FORM FEED - 0x000d, // #CARRIAGE RETURN - 0x000e, // #SHIFT OUT - 0x000f, // #SHIFT IN - 0x0010, // #DATA LINK ESCAPE - 0x0011, // #DEVICE CONTROL ONE - 0x0012, // #DEVICE CONTROL TWO - 0x0013, // #DEVICE CONTROL THREE - 0x0014, // #DEVICE CONTROL FOUR - 0x0015, // #NEGATIVE ACKNOWLEDGE - 0x0016, // #SYNCHRONOUS IDLE - 0x0017, // #END OF TRANSMISSION BLOCK - 0x0018, // #CANCEL - 0x0019, // #END OF MEDIUM - 0x001a, // #SUBSTITUTE - 0x001b, // #ESCAPE - 0x001c, // #FILE SEPARATOR - 0x001d, // #GROUP SEPARATOR - 0x001e, // #RECORD SEPARATOR - 0x001f, // #UNIT SEPARATOR - 0x0020, // #SPACE - 0x0021, // #EXCLAMATION MARK - 0x0022, // #QUOTATION MARK - 0x0023, // #NUMBER SIGN - 0x0024, // #DOLLAR SIGN - 0x0025, // #PERCENT SIGN - 0x0026, // #AMPERSAND - 0x0027, // #APOSTROPHE - 0x0028, // #LEFT PARENTHESIS - 0x0029, // #RIGHT PARENTHESIS - 0x002a, // #ASTERISK - 0x002b, // #PLUS SIGN - 0x002c, // #COMMA - 0x002d, // #HYPHEN-MINUS - 0x002e, // #FULL STOP - 0x002f, // #SOLIDUS - 0x0030, // #DIGIT ZERO - 0x0031, // #DIGIT ONE - 0x0032, // #DIGIT TWO - 0x0033, // #DIGIT THREE - 0x0034, // #DIGIT FOUR - 0x0035, // #DIGIT FIVE - 0x0036, // #DIGIT SIX - 0x0037, // #DIGIT SEVEN - 0x0038, // #DIGIT EIGHT - 0x0039, // #DIGIT NINE - 0x003a, // #COLON - 0x003b, // #SEMICOLON - 0x003c, // #LESS-THAN SIGN - 0x003d, // #EQUALS SIGN - 0x003e, // #GREATER-THAN SIGN - 0x003f, // #QUESTION MARK - 0x0040, // #COMMERCIAL AT - 0x0041, // #LATIN CAPITAL LETTER A - 0x0042, // #LATIN CAPITAL LETTER B - 0x0043, // #LATIN CAPITAL LETTER C - 0x0044, // #LATIN CAPITAL LETTER D - 0x0045, // #LATIN CAPITAL LETTER E - 0x0046, // #LATIN CAPITAL LETTER F - 0x0047, // #LATIN CAPITAL LETTER G - 0x0048, // #LATIN CAPITAL LETTER H - 0x0049, // #LATIN CAPITAL LETTER I - 0x004a, // #LATIN CAPITAL LETTER J - 0x004b, // #LATIN CAPITAL LETTER K - 0x004c, // #LATIN CAPITAL LETTER L - 0x004d, // #LATIN CAPITAL LETTER M - 0x004e, // #LATIN CAPITAL LETTER N - 0x004f, // #LATIN CAPITAL LETTER O - 0x0050, // #LATIN CAPITAL LETTER P - 0x0051, // #LATIN CAPITAL LETTER Q - 0x0052, // #LATIN CAPITAL LETTER R - 0x0053, // #LATIN CAPITAL LETTER S - 0x0054, // #LATIN CAPITAL LETTER T - 0x0055, // #LATIN CAPITAL LETTER U - 0x0056, // #LATIN CAPITAL LETTER V - 0x0057, // #LATIN CAPITAL LETTER W - 0x0058, // #LATIN CAPITAL LETTER X - 0x0059, // #LATIN CAPITAL LETTER Y - 0x005a, // #LATIN CAPITAL LETTER Z - 0x005b, // #LEFT SQUARE BRACKET - 0x005c, // #REVERSE SOLIDUS - 0x005d, // #RIGHT SQUARE BRACKET - 0x005e, // #CIRCUMFLEX ACCENT - 0x005f, // #LOW LINE - 0x0060, // #GRAVE ACCENT - 0x0061, // #LATIN SMALL LETTER A - 0x0062, // #LATIN SMALL LETTER B - 0x0063, // #LATIN SMALL LETTER C - 0x0064, // #LATIN SMALL LETTER D - 0x0065, // #LATIN SMALL LETTER E - 0x0066, // #LATIN SMALL LETTER F - 0x0067, // #LATIN SMALL LETTER G - 0x0068, // #LATIN SMALL LETTER H - 0x0069, // #LATIN SMALL LETTER I - 0x006a, // #LATIN SMALL LETTER J - 0x006b, // #LATIN SMALL LETTER K - 0x006c, // #LATIN SMALL LETTER L - 0x006d, // #LATIN SMALL LETTER M - 0x006e, // #LATIN SMALL LETTER N - 0x006f, // #LATIN SMALL LETTER O - 0x0070, // #LATIN SMALL LETTER P - 0x0071, // #LATIN SMALL LETTER Q - 0x0072, // #LATIN SMALL LETTER R - 0x0073, // #LATIN SMALL LETTER S - 0x0074, // #LATIN SMALL LETTER T - 0x0075, // #LATIN SMALL LETTER U - 0x0076, // #LATIN SMALL LETTER V - 0x0077, // #LATIN SMALL LETTER W - 0x0078, // #LATIN SMALL LETTER X - 0x0079, // #LATIN SMALL LETTER Y - 0x007a, // #LATIN SMALL LETTER Z - 0x007b, // #LEFT CURLY BRACKET - 0x007c, // #VERTICAL LINE - 0x007d, // #RIGHT CURLY BRACKET - 0x007e, // #TILDE - 0x007f, // #DELETE - 0x00c7, // #LATIN CAPITAL LETTER C WITH CEDILLA - 0x00fc, // #LATIN SMALL LETTER U WITH DIAERESIS - 0x00e9, // #LATIN SMALL LETTER E WITH ACUTE - 0x00e2, // #LATIN SMALL LETTER A WITH CIRCUMFLEX - 0x00e4, // #LATIN SMALL LETTER A WITH DIAERESIS - 0x00e0, // #LATIN SMALL LETTER A WITH GRAVE - 0x00e5, // #LATIN SMALL LETTER A WITH RING ABOVE - 0x00e7, // #LATIN SMALL LETTER C WITH CEDILLA - 0x00ea, // #LATIN SMALL LETTER E WITH CIRCUMFLEX - 0x00eb, // #LATIN SMALL LETTER E WITH DIAERESIS - 0x00e8, // #LATIN SMALL LETTER E WITH GRAVE - 0x00ef, // #LATIN SMALL LETTER I WITH DIAERESIS - 0x00ee, // #LATIN SMALL LETTER I WITH CIRCUMFLEX - 0x00ec, // #LATIN SMALL LETTER I WITH GRAVE - 0x00c4, // #LATIN CAPITAL LETTER A WITH DIAERESIS - 0x00c5, // #LATIN CAPITAL LETTER A WITH RING ABOVE - 0x00c9, // #LATIN CAPITAL LETTER E WITH ACUTE - 0x00e6, // #LATIN SMALL LIGATURE AE - 0x00c6, // #LATIN CAPITAL LIGATURE AE - 0x00f4, // #LATIN SMALL LETTER O WITH CIRCUMFLEX - 0x00f6, // #LATIN SMALL LETTER O WITH DIAERESIS - 0x00f2, // #LATIN SMALL LETTER O WITH GRAVE - 0x00fb, // #LATIN SMALL LETTER U WITH CIRCUMFLEX - 0x00f9, // #LATIN SMALL LETTER U WITH GRAVE - 0x00ff, // #LATIN SMALL LETTER Y WITH DIAERESIS - 0x00d6, // #LATIN CAPITAL LETTER O WITH DIAERESIS - 0x00dc, // #LATIN CAPITAL LETTER U WITH DIAERESIS - 0x00a2, // #CENT SIGN - 0x00a3, // #POUND SIGN - 0x00a5, // #YEN SIGN - 0x20a7, // #PESETA SIGN - 0x0192, // #LATIN SMALL LETTER F WITH HOOK - 0x00e1, // #LATIN SMALL LETTER A WITH ACUTE - 0x00ed, // #LATIN SMALL LETTER I WITH ACUTE - 0x00f3, // #LATIN SMALL LETTER O WITH ACUTE - 0x00fa, // #LATIN SMALL LETTER U WITH ACUTE - 0x00f1, // #LATIN SMALL LETTER N WITH TILDE - 0x00d1, // #LATIN CAPITAL LETTER N WITH TILDE - 0x00aa, // #FEMININE ORDINAL INDICATOR - 0x00ba, // #MASCULINE ORDINAL INDICATOR - 0x00bf, // #INVERTED QUESTION MARK - 0x2310, // #REVERSED NOT SIGN - 0x00ac, // #NOT SIGN - 0x00bd, // #VULGAR FRACTION ONE HALF - 0x00bc, // #VULGAR FRACTION ONE QUARTER - 0x00a1, // #INVERTED EXCLAMATION MARK - 0x00ab, // #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x00bb, // #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - 0x2591, // #LIGHT SHADE - 0x2592, // #MEDIUM SHADE - 0x2593, // #DARK SHADE - 0x2502, // #BOX DRAWINGS LIGHT VERTICAL - 0x2524, // #BOX DRAWINGS LIGHT VERTICAL AND LEFT - 0x2561, // #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - 0x2562, // #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - 0x2556, // #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - 0x2555, // #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - 0x2563, // #BOX DRAWINGS DOUBLE VERTICAL AND LEFT - 0x2551, // #BOX DRAWINGS DOUBLE VERTICAL - 0x2557, // #BOX DRAWINGS DOUBLE DOWN AND LEFT - 0x255d, // #BOX DRAWINGS DOUBLE UP AND LEFT - 0x255c, // #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - 0x255b, // #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - 0x2510, // #BOX DRAWINGS LIGHT DOWN AND LEFT - 0x2514, // #BOX DRAWINGS LIGHT UP AND RIGHT - 0x2534, // #BOX DRAWINGS LIGHT UP AND HORIZONTAL - 0x252c, // #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - 0x251c, // #BOX DRAWINGS LIGHT VERTICAL AND RIGHT - 0x2500, // #BOX DRAWINGS LIGHT HORIZONTAL - 0x253c, // #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - 0x255e, // #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - 0x255f, // #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - 0x255a, // #BOX DRAWINGS DOUBLE UP AND RIGHT - 0x2554, // #BOX DRAWINGS DOUBLE DOWN AND RIGHT - 0x2569, // #BOX DRAWINGS DOUBLE UP AND HORIZONTAL - 0x2566, // #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - 0x2560, // #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - 0x2550, // #BOX DRAWINGS DOUBLE HORIZONTAL - 0x256c, // #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - 0x2567, // #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - 0x2568, // #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - 0x2564, // #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - 0x2565, // #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - 0x2559, // #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - 0x2558, // #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - 0x2552, // #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - 0x2553, // #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - 0x256b, // #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - 0x256a, // #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - 0x2518, // #BOX DRAWINGS LIGHT UP AND LEFT - 0x250c, // #BOX DRAWINGS LIGHT DOWN AND RIGHT - 0x2588, // #FULL BLOCK - 0x2584, // #LOWER HALF BLOCK - 0x258c, // #LEFT HALF BLOCK - 0x2590, // #RIGHT HALF BLOCK - 0x2580, // #UPPER HALF BLOCK - 0x03b1, // #GREEK SMALL LETTER ALPHA - 0x00df, // #LATIN SMALL LETTER SHARP S - 0x0393, // #GREEK CAPITAL LETTER GAMMA - 0x03c0, // #GREEK SMALL LETTER PI - 0x03a3, // #GREEK CAPITAL LETTER SIGMA - 0x03c3, // #GREEK SMALL LETTER SIGMA - 0x00b5, // #MICRO SIGN - 0x03c4, // #GREEK SMALL LETTER TAU - 0x03a6, // #GREEK CAPITAL LETTER PHI - 0x0398, // #GREEK CAPITAL LETTER THETA - 0x03a9, // #GREEK CAPITAL LETTER OMEGA - 0x03b4, // #GREEK SMALL LETTER DELTA - 0x221e, // #INFINITY - 0x03c6, // #GREEK SMALL LETTER PHI - 0x03b5, // #GREEK SMALL LETTER EPSILON - 0x2229, // #INTERSECTION - 0x2261, // #IDENTICAL TO - 0x00b1, // #PLUS-MINUS SIGN - 0x2265, // #GREATER-THAN OR EQUAL TO - 0x2264, // #LESS-THAN OR EQUAL TO - 0x2320, // #TOP HALF INTEGRAL - 0x2321, // #BOTTOM HALF INTEGRAL - 0x00f7, // #DIVISION SIGN - 0x2248, // #ALMOST EQUAL TO - 0x00b0, // #DEGREE SIGN - 0x2219, // #BULLET OPERATOR - 0x00b7, // #MIDDLE DOT - 0x221a, // #SQUARE ROOT - 0x207f, // #SUPERSCRIPT LATIN SMALL LETTER N - 0x00b2, // #SUPERSCRIPT TWO - 0x25a0, // #BLACK SQUARE - 0x00a0, // #NO-BREAK SPACE - }; - - public char map_cp850_unicode(char x) { - if (x >= 0x100) { - return x; - } - return unimap[x]; - } - - private void _SetCursor(int row, int col) { - int maxr = height - 1; - int tm = getTopMargin(); - - R = (row < 0) ? 0 : row; - C = (col < 0) ? 0 : (col >= width) ? width - 1 : col; - - if (!moveoutsidemargins) { - R += tm; - maxr = getBottomMargin(); - } - if (R > maxr) { - R = maxr; - } - } - - private void putChar(char c, boolean isWide, boolean doshowcursor) { - int rows = height; // statusline - int columns = width; - // byte msg[]; - - // if (debug > 4) { - // debugStr.append("putChar(") - // .append(c) - // .append(" [") - // .append((int) c) - // .append("]) at R=") - // .append(R) - // .append(" , C=") - // .append(C) - // .append(", columns=") - // .append(columns) - // .append(", rows=") - // .append(rows); - // debug(debugStr.toString()); - // debugStr.setLength(0); - // } - // markLine(R, 1); - // if (c > 255) { - // if (debug > 0) - // debug("char > 255:" + (int) c); - // //return; - // } - - switch (term_state) { - case TSTATE_DATA: - /* - * FIXME: we shouldn't use chars with bit 8 set if ibmcharset. probably... but some BBS do - * anyway... - */ - if (!useibmcharset) { - boolean doneflag = true; - switch (c) { - case OSC: - osc = ""; - term_state = TSTATE_OSC; - break; - case RI: - if (R > getTopMargin()) { - R--; - } else { - insertLine(R, 1, SCROLL_DOWN); - } - if (debug > 1) { - debug("RI"); - } - break; - case IND: - if (debug > 2) { - debugStr.append("IND at ").append(R).append(", tm is ").append(getTopMargin()) - .append(", bm is ").append(getBottomMargin()); - debug(debugStr.toString()); - debugStr.setLength(0); - } - if (R == getBottomMargin() || R == rows - 1) { - insertLine(R, 1, SCROLL_UP); - } else { - R++; - } - if (debug > 1) { - debug("IND (at " + R + " )"); - } - break; - case NEL: - if (R == getBottomMargin() || R == rows - 1) { - insertLine(R, 1, SCROLL_UP); - } else { - R++; - } - C = 0; - if (debug > 1) { - debug("NEL (at " + R + " )"); - } - break; - case HTS: - Tabs[C] = 1; - if (debug > 1) { - debug("HTS"); - } - break; - case DCS: - dcs = ""; - term_state = TSTATE_DCS; - break; - default: - doneflag = false; - break; - } - if (doneflag) { - break; - } - } - switch (c) { - case SS3: - onegl = 3; - break; - case SS2: - onegl = 2; - break; - case CSI: // should be in the 8bit section, but some BBS use this - DCEvar = 0; - DCEvars[0] = 0; - DCEvars[1] = 0; - DCEvars[2] = 0; - DCEvars[3] = 0; - term_state = TSTATE_CSI; - break; - case ESC: - term_state = TSTATE_ESC; - lastwaslf = 0; - break; - case 5: /* ENQ */ - write(answerBack, false); - break; - case 12: - /* FormFeed, Home for the BBS world */ - deleteArea(0, 0, columns, rows, attributes); - C = R = 0; - break; - case '\b': /* 8 */ - C--; - if (C < 0) { - C = 0; - } - lastwaslf = 0; - break; - case '\t': - do { - // Don't overwrite or insert! TABS are not destructive, but movement! - C++; - } while (C < columns && (Tabs[C] == 0)); - lastwaslf = 0; - break; - case '\r': // 13 CR - C = 0; - break; - case '\n': // 10 LF - if (debug > 3) { - debug("R= " + R + ", bm " + getBottomMargin() + ", tm=" + getTopMargin() + ", rows=" - + rows); - } - if (!vms) { - if (lastwaslf != 0 && lastwaslf != c) { - break; - } - lastwaslf = c; - /* C = 0; */ - } - if (R == getBottomMargin() || R >= rows - 1) { - insertLine(R, 1, SCROLL_UP); - } else { - R++; - } - break; - case 7: - beep(); - break; - case '\016': /* SMACS , as */ - /* ^N, Shift out - Put G1 into GL */ - gl = 1; - usedcharsets = true; - break; - case '\017': /* RMACS , ae */ - /* ^O, Shift in - Put G0 into GL */ - gl = 0; - usedcharsets = true; - break; - default: { - int thisgl = gl; - - if (onegl >= 0) { - thisgl = onegl; - onegl = -1; - } - lastwaslf = 0; - if (c < 32) { - if (c != 0) { - if (debug > 0) { - debug("TSTATE_DATA char: " + ((int) c)); - } - } - /* break; some BBS really want those characters, like hearst etc. */ - if (c == 0) { - break; - } - } - if (C >= columns) { - if (wraparound) { - int bot = rows; - - // If we're in the scroll region, check against the bottom margin - if (R <= getBottomMargin() && R >= getTopMargin()) { - bot = getBottomMargin() + 1; - } - - if (R < bot - 1) { - R++; - } else { - if (debug > 3) { - debug("scrolling due to wrap at " + R); - } - insertLine(R, 1, SCROLL_UP); - } - C = 0; - } else { - // cursor stays on last character. - C = columns - 1; - } - } - - boolean mapped = false; - - // Mapping if DEC Special is chosen charset - if (usedcharsets) { - if (c >= '\u0020' && c <= '\u007f') { - switch (gx[thisgl]) { - case '0': - // Remap SCOANSI line drawing to VT100 line drawing chars - // for our SCO using customers. - if (terminalID.equals("scoansi") || terminalID.equals("ansi")) { - for (int i = 0; i < scoansi_acs.length(); i += 2) { - if (c == scoansi_acs.charAt(i)) { - c = scoansi_acs.charAt(i + 1); - break; - } - } - } - if (c >= '\u005f' && c <= '\u007e') { - c = DECSPECIAL[(short) c - 0x5f]; - mapped = true; - } - break; - case '<': // 'user preferred' is currently 'ISO Latin-1 suppl - c = (char) ((c & 0x7f) | 0x80); - mapped = true; - break; - case 'A': - case 'B': // Latin-1 , ASCII -> fall through - mapped = true; - break; - default: - debug("Unsupported GL mapping: " + gx[thisgl]); - break; - } - } - if (!mapped && (c >= '\u0080' && c <= '\u00ff')) { - switch (gx[gr]) { - case '0': - if (c >= '\u00df' && c <= '\u00fe') { - c = DECSPECIAL[c - '\u00df']; - mapped = true; - } - break; - case '<': - case 'A': - case 'B': - mapped = true; - break; - default: - debug("Unsupported GR mapping: " + gx[gr]); - break; - } - } - } - if (!mapped && useibmcharset) { - c = map_cp850_unicode(c); - } - - /* if(true || (statusmode == 0)) { */ - if (isWide) { - if (C >= columns - 1) { - if (wraparound) { - int bot = rows; - - // If we're in the scroll region, check against the bottom margin - if (R <= getBottomMargin() && R >= getTopMargin()) { - bot = getBottomMargin() + 1; - } - - if (R < bot - 1) { - R++; - } else { - if (debug > 3) { - debug("scrolling due to wrap at " + R); - } - insertLine(R, 1, SCROLL_UP); - } - C = 0; - } else { - // cursor stays on last wide character. - C = columns - 2; - } - } - } - - if (insertmode == 1) { - if (isWide) { - insertChar(C++, R, c, attributes | FULLWIDTH); - insertChar(C, R, ' ', attributes | FULLWIDTH); - } else { - insertChar(C, R, c, attributes); - } - } else { - if (isWide) { - putChar(C++, R, c, attributes | FULLWIDTH); - putChar(C, R, ' ', attributes | FULLWIDTH); - } else { - putChar(C, R, c, attributes); - } - } - - /* - * } else { if (insertmode==1) { insertChar(C, rows, c, attributes); } else { putChar(C, - * rows, c, attributes); } } - */ - C++; - break; - } - } /* switch(c) */ - break; - case TSTATE_OSC: - if ((c < 0x20) && (c != ESC)) {// NP - No printing character - handle_osc(osc); - term_state = TSTATE_DATA; - break; - } - // but check for vt102 ESC \ - if (c == '\\' && osc.charAt(osc.length() - 1) == ESC) { - handle_osc(osc); - term_state = TSTATE_DATA; - break; - } - osc = osc + c; - break; - case TSTATE_ESCSPACE: - term_state = TSTATE_DATA; - switch (c) { - case 'F': /* S7C1T, Disable output of 8-bit controls, use 7-bit */ - output8bit = false; - break; - case 'G': /* S8C1T, Enable output of 8-bit control codes */ - output8bit = true; - break; - default: - debug("ESC <space> " + c + " unhandled."); - } - break; - case TSTATE_ESC: - term_state = TSTATE_DATA; - switch (c) { - case ' ': - term_state = TSTATE_ESCSPACE; - break; - case '#': - term_state = TSTATE_ESCSQUARE; - break; - case 'c': - /* Hard terminal reset */ - reset(); - break; - case '[': - DCEvar = 0; - DCEvars[0] = 0; - DCEvars[1] = 0; - DCEvars[2] = 0; - DCEvars[3] = 0; - term_state = TSTATE_CSI; - break; - case ']': - osc = ""; - term_state = TSTATE_OSC; - break; - case 'P': - dcs = ""; - term_state = TSTATE_DCS; - break; - case 'A': /* CUU */ - R--; - if (R < 0) { - R = 0; - } - break; - case 'B': /* CUD */ - R++; - if (R >= rows) { - R = rows - 1; - } - break; - case 'C': - C++; - if (C >= columns) { - C = columns - 1; - } - break; - case 'I': // RI - insertLine(R, 1, SCROLL_DOWN); - break; - case 'E': /* NEL */ - if (R == getBottomMargin() || R == rows - 1) { - insertLine(R, 1, SCROLL_UP); - } else { - R++; - } - C = 0; - if (debug > 1) { - debug("ESC E (at " + R + ")"); - } - break; - case 'D': /* IND */ - if (R == getBottomMargin() || R == rows - 1) { - insertLine(R, 1, SCROLL_UP); - } else { - R++; - } - if (debug > 1) { - debug("ESC D (at " + R + " )"); - } - break; - case 'J': /* erase to end of screen */ - if (R < rows - 1) { - deleteArea(0, R + 1, columns, rows - R - 1, attributes); - } - if (C < columns - 1) { - deleteArea(C, R, columns - C, 1, attributes); - } - break; - case 'K': - if (C < columns - 1) { - deleteArea(C, R, columns - C, 1, attributes); - } - break; - case 'M': // RI - debug("ESC M : R is " + R + ", tm is " + getTopMargin() + ", bm is " + getBottomMargin()); - if (R > getTopMargin()) { // just go up 1 line. - R--; - } else { // scroll down - insertLine(R, 1, SCROLL_DOWN); - } - /* else do nothing ; */ - if (debug > 2) { - debug("ESC M "); - } - break; - case 'H': - if (debug > 1) { - debug("ESC H at " + C); - } - /* right border probably ... */ - if (C >= columns) { - C = columns - 1; - } - Tabs[C] = 1; - break; - case 'N': // SS2 - onegl = 2; - break; - case 'O': // SS3 - onegl = 3; - break; - case '=': - /* application keypad */ - if (debug > 0) { - debug("ESC ="); - } - keypadmode = true; - break; - case '<': /* vt52 mode off */ - vt52mode = false; - break; - case '>': /* normal keypad */ - if (debug > 0) { - debug("ESC >"); - } - keypadmode = false; - break; - case '7': /* DECSC: save cursor, attributes */ - Sc = C; - Sr = R; - Sgl = gl; - Sgr = gr; - Sa = attributes; - Sgx = new char[4]; - for (int i = 0; i < 4; i++) { - Sgx[i] = gx[i]; - } - if (debug > 1) { - debug("ESC 7"); - } - break; - case '8': /* DECRC: restore cursor, attributes */ - C = Sc; - R = Sr; - gl = Sgl; - gr = Sgr; - if (Sgx != null) { - for (int i = 0; i < 4; i++) { - gx[i] = Sgx[i]; - } - } - attributes = Sa; - if (debug > 1) { - debug("ESC 8"); - } - break; - case '(': /* Designate G0 Character set (ISO 2022) */ - term_state = TSTATE_SETG0; - usedcharsets = true; - break; - case ')': /* Designate G1 character set (ISO 2022) */ - term_state = TSTATE_SETG1; - usedcharsets = true; - break; - case '*': /* Designate G2 Character set (ISO 2022) */ - term_state = TSTATE_SETG2; - usedcharsets = true; - break; - case '+': /* Designate G3 Character set (ISO 2022) */ - term_state = TSTATE_SETG3; - usedcharsets = true; - break; - case '~': /* Locking Shift 1, right */ - gr = 1; - usedcharsets = true; - break; - case 'n': /* Locking Shift 2 */ - gl = 2; - usedcharsets = true; - break; - case '}': /* Locking Shift 2, right */ - gr = 2; - usedcharsets = true; - break; - case 'o': /* Locking Shift 3 */ - gl = 3; - usedcharsets = true; - break; - case '|': /* Locking Shift 3, right */ - gr = 3; - usedcharsets = true; - break; - case 'Y': /* vt52 cursor address mode , next chars are x,y */ - term_state = TSTATE_VT52Y; - break; - case '_': - term_state = TSTATE_TITLE; - break; - case '\\': - // TODO save title - term_state = TSTATE_DATA; - break; - default: - debug("ESC unknown letter: " + c + " (" + ((int) c) + ")"); - break; - } - break; - case TSTATE_VT52X: - C = c - 37; - if (C < 0) { - C = 0; - } else if (C >= width) { - C = width - 1; - } - term_state = TSTATE_VT52Y; - break; - case TSTATE_VT52Y: - R = c - 37; - if (R < 0) { - R = 0; - } else if (R >= height) { - R = height - 1; - } - term_state = TSTATE_DATA; - break; - case TSTATE_SETG0: - if (c != '0' && c != 'A' && c != 'B' && c != '<') { - debug("ESC ( " + c + ": G0 char set? (" + ((int) c) + ")"); - } else { - if (debug > 2) { - debug("ESC ( : G0 char set (" + c + " " + ((int) c) + ")"); - } - gx[0] = c; - } - term_state = TSTATE_DATA; - break; - case TSTATE_SETG1: - if (c != '0' && c != 'A' && c != 'B' && c != '<') { - debug("ESC ) " + c + " (" + ((int) c) + ") :G1 char set?"); - } else { - if (debug > 2) { - debug("ESC ) :G1 char set (" + c + " " + ((int) c) + ")"); - } - gx[1] = c; - } - term_state = TSTATE_DATA; - break; - case TSTATE_SETG2: - if (c != '0' && c != 'A' && c != 'B' && c != '<') { - debug("ESC*:G2 char set? (" + ((int) c) + ")"); - } else { - if (debug > 2) { - debug("ESC*:G2 char set (" + c + " " + ((int) c) + ")"); - } - gx[2] = c; - } - term_state = TSTATE_DATA; - break; - case TSTATE_SETG3: - if (c != '0' && c != 'A' && c != 'B' && c != '<') { - debug("ESC+:G3 char set? (" + ((int) c) + ")"); - } else { - if (debug > 2) { - debug("ESC+:G3 char set (" + c + " " + ((int) c) + ")"); - } - gx[3] = c; - } - term_state = TSTATE_DATA; - break; - case TSTATE_ESCSQUARE: - switch (c) { - case '8': - for (int i = 0; i < columns; i++) { - for (int j = 0; j < rows; j++) { - putChar(i, j, 'E', 0); - } - } - break; - default: - debug("ESC # " + c + " not supported."); - break; - } - term_state = TSTATE_DATA; - break; - case TSTATE_DCS: - if (c == '\\' && dcs.charAt(dcs.length() - 1) == ESC) { - handle_dcs(dcs); - term_state = TSTATE_DATA; - break; - } - dcs = dcs + c; - break; - - case TSTATE_DCEQ: - term_state = TSTATE_DATA; - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48; - term_state = TSTATE_DCEQ; - break; - case ';': - DCEvar++; - DCEvars[DCEvar] = 0; - term_state = TSTATE_DCEQ; - break; - case 's': // XTERM_SAVE missing! - if (true || debug > 1) { - debug("ESC [ ? " + DCEvars[0] + " s unimplemented!"); - } - break; - case 'r': // XTERM_RESTORE - if (true || debug > 1) { - debug("ESC [ ? " + DCEvars[0] + " r"); - } - /* DEC Mode reset */ - for (int i = 0; i <= DCEvar; i++) { - switch (DCEvars[i]) { - case 3: /* 80 columns */ - setScreenSize(80, height, true); - break; - case 4: /* scrolling mode, smooth */ - break; - case 5: /* light background */ - break; - case 6: /* DECOM (Origin Mode) move inside margins. */ - moveoutsidemargins = true; - break; - case 7: /* DECAWM: Autowrap Mode */ - wraparound = false; - break; - case 12:/* local echo off */ - break; - case 9: /* X10 mouse */ - case 1000: /* xterm style mouse report on */ - case 1001: - case 1002: - case 1003: - mouserpt = DCEvars[i]; - break; - default: - debug("ESC [ ? " + DCEvars[0] + " r, unimplemented!"); - } - } - break; - case 'h': // DECSET - if (debug > 0) { - debug("ESC [ ? " + DCEvars[0] + " h"); - } - /* DEC Mode set */ - for (int i = 0; i <= DCEvar; i++) { - switch (DCEvars[i]) { - case 1: /* Application cursor keys */ - KeyUp[0] = "\u001bOA"; - KeyDown[0] = "\u001bOB"; - KeyRight[0] = "\u001bOC"; - KeyLeft[0] = "\u001bOD"; - break; - case 2: /* DECANM */ - vt52mode = false; - break; - case 3: /* 132 columns */ - setScreenSize(132, height, true); - break; - case 6: /* DECOM: move inside margins. */ - moveoutsidemargins = false; - break; - case 7: /* DECAWM: Autowrap Mode */ - wraparound = true; - break; - case 25: /* turn cursor on */ - showCursor(true); - break; - case 9: /* X10 mouse */ - case 1000: /* xterm style mouse report on */ - case 1001: - case 1002: - case 1003: - mouserpt = DCEvars[i]; - break; - - /* unimplemented stuff, fall through */ - /* 4 - scrolling mode, smooth */ - /* 5 - light background */ - /* 12 - local echo off */ - /* 18 - DECPFF - Printer Form Feed Mode -> On */ - /* 19 - DECPEX - Printer Extent Mode -> Screen */ - default: - debug("ESC [ ? " + DCEvars[0] + " h, unsupported."); - break; - } - } - break; - case 'i': // DEC Printer Control, autoprint, echo screenchars to printer - // This is different to CSI i! - // Also: "Autoprint prints a final display line only when the - // cursor is moved off the line by an autowrap or LF, FF, or - // VT (otherwise do not print the line)." - switch (DCEvars[0]) { - case 1: - if (debug > 1) { - debug("CSI ? 1 i : Print line containing cursor"); - } - break; - case 4: - if (debug > 1) { - debug("CSI ? 4 i : Start passthrough printing"); - } - break; - case 5: - if (debug > 1) { - debug("CSI ? 4 i : Stop passthrough printing"); - } - break; - } - break; - case 'l': // DECRST - /* DEC Mode reset */ - if (debug > 0) { - debug("ESC [ ? " + DCEvars[0] + " l"); - } - for (int i = 0; i <= DCEvar; i++) { - switch (DCEvars[i]) { - case 1: /* Application cursor keys */ - KeyUp[0] = "\u001b[A"; - KeyDown[0] = "\u001b[B"; - KeyRight[0] = "\u001b[C"; - KeyLeft[0] = "\u001b[D"; - break; - case 2: /* DECANM */ - vt52mode = true; - break; - case 3: /* 80 columns */ - setScreenSize(80, height, true); - break; - case 6: /* DECOM: move outside margins. */ - moveoutsidemargins = true; - break; - case 7: /* DECAWM: Autowrap Mode OFF */ - wraparound = false; - break; - case 25: /* turn cursor off */ - showCursor(false); - break; - /* Unimplemented stuff: */ - /* 4 - scrolling mode, jump */ - /* 5 - dark background */ - /* 7 - DECAWM - no wrap around mode */ - /* 12 - local echo on */ - /* 18 - DECPFF - Printer Form Feed Mode -> Off */ - /* 19 - DECPEX - Printer Extent Mode -> Scrolling Region */ - case 9: /* X10 mouse */ - case 1000: /* xterm style mouse report OFF */ - case 1001: - case 1002: - case 1003: - mouserpt = 0; - break; - default: - debug("ESC [ ? " + DCEvars[0] + " l, unsupported."); - break; - } - } - break; - case 'n': - if (debug > 0) { - debug("ESC [ ? " + DCEvars[0] + " n"); - } - switch (DCEvars[0]) { - case 15: - /* printer? no printer. */ - write((ESC) + "[?13n", false); - debug("ESC[5n"); - break; - default: - debug("ESC [ ? " + DCEvars[0] + " n, unsupported."); - break; - } - break; - default: - debug("ESC [ ? " + DCEvars[0] + " " + c + ", unsupported."); - break; - } - break; - case TSTATE_CSI_EX: - term_state = TSTATE_DATA; - switch (c) { - case ESC: - term_state = TSTATE_ESC; - break; - default: - debug("Unknown character ESC[! character is " + (int) c); - break; - } - break; - case TSTATE_CSI_TICKS: - term_state = TSTATE_DATA; - switch (c) { - case 'p': - debug("Conformance level: " + DCEvars[0] + " (unsupported)," + DCEvars[1]); - if (DCEvars[0] == 61) { - output8bit = false; - break; - } - if (DCEvars[1] == 1) { - output8bit = false; - } else { - output8bit = true; /* 0 or 2 */ - } - break; - default: - debug("Unknown ESC [... \"" + c); - break; - } - break; - case TSTATE_CSI_EQUAL: - term_state = TSTATE_DATA; - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48; - term_state = TSTATE_CSI_EQUAL; - break; - case ';': - DCEvar++; - DCEvars[DCEvar] = 0; - term_state = TSTATE_CSI_EQUAL; - break; - - case 'F': /* SCO ANSI foreground */ - { - int newcolor; - - debug("ESC [ = " + DCEvars[0] + " F"); - - attributes &= ~COLOR_FG; - newcolor = ((DCEvars[0] & 1) << 2) | (DCEvars[0] & 2) | ((DCEvars[0] & 4) >> 2); - attributes |= (newcolor + 1) << COLOR_FG_SHIFT; - - break; - } - case 'G': /* SCO ANSI background */ - { - int newcolor; - - debug("ESC [ = " + DCEvars[0] + " G"); - - attributes &= ~COLOR_BG; - newcolor = ((DCEvars[0] & 1) << 2) | (DCEvars[0] & 2) | ((DCEvars[0] & 4) >> 2); - attributes |= (newcolor + 1) << COLOR_BG_SHIFT; - break; - } - - default: - debugStr.append("Unknown ESC [ = "); - for (int i = 0; i <= DCEvar; i++) { - debugStr.append(DCEvars[i]).append(','); - } - debugStr.append(c); - debug(debugStr.toString()); - debugStr.setLength(0); - break; - } - break; - case TSTATE_CSI_DOLLAR: - term_state = TSTATE_DATA; - switch (c) { - case '}': - debug("Active Status Display now " + DCEvars[0]); - statusmode = DCEvars[0]; - break; - /* - * bad documentation? case '-': debug("Set Status Display now "+DCEvars[0]); break; - */ - case '~': - debug("Status Line mode now " + DCEvars[0]); - break; - default: - debug("UNKNOWN Status Display code " + c + ", with Pn=" + DCEvars[0]); - break; - } - break; - case TSTATE_CSI: - term_state = TSTATE_DATA; - switch (c) { - case '"': - term_state = TSTATE_CSI_TICKS; - break; - case '$': - term_state = TSTATE_CSI_DOLLAR; - break; - case '=': - term_state = TSTATE_CSI_EQUAL; - break; - case '!': - term_state = TSTATE_CSI_EX; - break; - case '?': - DCEvar = 0; - DCEvars[0] = 0; - term_state = TSTATE_DCEQ; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - DCEvars[DCEvar] = DCEvars[DCEvar] * 10 + (c) - 48; - term_state = TSTATE_CSI; - break; - case ';': - DCEvar++; - DCEvars[DCEvar] = 0; - term_state = TSTATE_CSI; - break; - case 'c':/* send primary device attributes */ - /* send (ESC[?61c) */ - - String subcode = ""; - if (terminalID.equals("vt320")) { - subcode = "63;"; - } - if (terminalID.equals("vt220")) { - subcode = "62;"; - } - if (terminalID.equals("vt100")) { - subcode = "61;"; - } - write((ESC) + "[?" + subcode + "1;2c", false); - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " c"); - } - break; - case 'q': - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " q"); - } - break; - case 'g': - /* used for tabsets */ - switch (DCEvars[0]) { - case 3:/* clear them */ - Tabs = new byte[width]; - break; - case 0: - Tabs[C] = 0; - break; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " g"); - } - break; - case 'h': - switch (DCEvars[0]) { - case 4: - insertmode = 1; - break; - case 20: - debug("Setting CRLF to TRUE"); - sendcrlf = true; - break; - default: - debug("unsupported: ESC [ " + DCEvars[0] + " h"); - break; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " h"); - } - break; - case 'i': // Printer Controller mode. - // "Transparent printing sends all output, except the CSI 4 i - // termination string, to the printer and not the screen, - // uses an 8-bit channel if no parity so NUL and DEL will be - // seen by the printer and by the termination recognizer code, - // and all translation and character set selections are - // bypassed." - switch (DCEvars[0]) { - case 0: - if (debug > 1) { - debug("CSI 0 i: Print Screen, not implemented."); - } - break; - case 4: - if (debug > 1) { - debug("CSI 4 i: Enable Transparent Printing, not implemented."); - } - break; - case 5: - if (debug > 1) { - debug("CSI 4/5 i: Disable Transparent Printing, not implemented."); - } - break; - default: - debug("ESC [ " + DCEvars[0] + " i, unimplemented!"); - } - break; - case 'l': - switch (DCEvars[0]) { - case 4: - insertmode = 0; - break; - case 20: - debug("Setting CRLF to FALSE"); - sendcrlf = false; - break; - default: - debug("ESC [ " + DCEvars[0] + " l, unimplemented!"); - break; - } - break; - case 'A': // CUU - { - int limit; - /* FIXME: xterm only cares about 0 and topmargin */ - if (R >= getTopMargin()) { - limit = getTopMargin(); - } else { - limit = 0; - } - if (DCEvars[0] == 0) { - R--; - } else { - R -= DCEvars[0]; - } - if (R < limit) { - R = limit; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " A"); - } - break; - } - case 'B': // CUD - /* cursor down n (1) times */ - { - int limit; - if (R <= getBottomMargin()) { - limit = getBottomMargin(); - } else { - limit = rows - 1; - } - if (DCEvars[0] == 0) { - R++; - } else { - R += DCEvars[0]; - } - if (R > limit) { - R = limit; - } else { - if (debug > 2) { - debug("Not limited."); - } - } - if (debug > 2) { - debug("to: " + R); - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " B (at C=" + C + ")"); - } - break; - } - case 'C': - if (DCEvars[0] == 0) { - DCEvars[0] = 1; - } - while (DCEvars[0]-- > 0) { - C++; - } - if (C >= columns) { - C = columns - 1; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " C"); - } - break; - case 'd': // CVA - R = DCEvars[0]; - if (R < 0) { - R = 0; - } else if (R >= height) { - R = height - 1; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " d"); - } - break; - case 'D': - if (DCEvars[0] == 0) { - DCEvars[0] = 1; - } - while (DCEvars[0]-- > 0) { - C--; - } - if (C < 0) { - C = 0; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " D"); - } - break; - case 'r': // DECSTBM - if (DCEvar > 0) // Ray: Any argument is optional - { - R = DCEvars[1] - 1; - if (R < 0) { - R = rows - 1; - } else if (R >= rows) { - R = rows - 1; - } - } else { - R = rows - 1; - } - int bot = R; - if (R >= DCEvars[0]) { - R = DCEvars[0] - 1; - if (R < 0) { - R = 0; - } - } - setMargins(R, bot); - _SetCursor(0, 0); - if (debug > 1) { - debug("ESC [" + DCEvars[0] + " ; " + DCEvars[1] + " r"); - } - break; - case 'G': /* CUP / cursor absolute column */ - C = DCEvars[0]; - if (C < 0) { - C = 0; - } else if (C >= width) { - C = width - 1; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " G"); - } - break; - case 'H': /* CUP / cursor position */ - /* gets 2 arguments */ - _SetCursor(DCEvars[0] - 1, DCEvars[1] - 1); - if (debug > 2) { - debug("ESC [ " + DCEvars[0] + ";" + DCEvars[1] + " H, moveoutsidemargins " - + moveoutsidemargins); - debug(" -> R now " + R + ", C now " + C); - } - break; - case 'f': /* move cursor 2 */ - /* gets 2 arguments */ - R = DCEvars[0] - 1; - C = DCEvars[1] - 1; - if (C < 0) { - C = 0; - } else if (C >= width) { - C = width - 1; - } - if (R < 0) { - R = 0; - } else if (R >= height) { - R = height - 1; - } - if (debug > 2) { - debug("ESC [ " + DCEvars[0] + ";" + DCEvars[1] + " f"); - } - break; - case 'S': /* ind aka 'scroll forward' */ - if (DCEvars[0] == 0) { - insertLine(rows - 1, SCROLL_UP); - } else { - insertLine(rows - 1, DCEvars[0], SCROLL_UP); - } - break; - case 'L': - /* insert n lines */ - if (DCEvars[0] == 0) { - insertLine(R, SCROLL_DOWN); - } else { - insertLine(R, DCEvars[0], SCROLL_DOWN); - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + "" + (c) + " (at R " + R + ")"); - } - break; - case 'T': /* 'ri' aka scroll backward */ - if (DCEvars[0] == 0) { - insertLine(0, SCROLL_DOWN); - } else { - insertLine(0, DCEvars[0], SCROLL_DOWN); - } - break; - case 'M': - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + "" + (c) + " at R=" + R); - } - if (DCEvars[0] == 0) { - deleteLine(R); - } else { - for (int i = 0; i < DCEvars[0]; i++) { - deleteLine(R); - } - } - break; - case 'K': - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " K"); - } - /* clear in line */ - switch (DCEvars[0]) { - case 6: /* 97801 uses ESC[6K for delete to end of line */ - case 0:/* clear to right */ - if (C < columns - 1) { - deleteArea(C, R, columns - C, 1, attributes); - } - break; - case 1:/* clear to the left, including this */ - if (C > 0) { - deleteArea(0, R, C + 1, 1, attributes); - } - break; - case 2:/* clear whole line */ - deleteArea(0, R, columns, 1, attributes); - break; - } - break; - case 'J': - /* clear below current line */ - switch (DCEvars[0]) { - case 0: - if (R < rows - 1) { - deleteArea(0, R + 1, columns, rows - R - 1, attributes); - } - if (C < columns - 1) { - deleteArea(C, R, columns - C, 1, attributes); - } - break; - case 1: - if (R > 0) { - deleteArea(0, 0, columns, R, attributes); - } - if (C > 0) { - deleteArea(0, R, C + 1, 1, attributes);// include up to and including current - } - break; - case 2: - deleteArea(0, 0, columns, rows, attributes); - break; - } - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " J"); - } - break; - case '@': - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " @"); - } - for (int i = 0; i < DCEvars[0]; i++) { - insertChar(C, R, ' ', attributes); - } - break; - case 'X': { - int toerase = DCEvars[0]; - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " X, C=" + C + ",R=" + R); - } - if (toerase == 0) { - toerase = 1; - } - if (toerase + C > columns) { - toerase = columns - C; - } - deleteArea(C, R, toerase, 1, attributes); - // does not change cursor position - break; - } - case 'P': - if (debug > 1) { - debug("ESC [ " + DCEvars[0] + " P, C=" + C + ",R=" + R); - } - if (DCEvars[0] == 0) { - DCEvars[0] = 1; - } - for (int i = 0; i < DCEvars[0]; i++) { - deleteChar(C, R); - } - break; - case 'n': - switch (DCEvars[0]) { - case 5: /* malfunction? No malfunction. */ - writeSpecial((ESC) + "[0n"); - if (debug > 1) { - debug("ESC[5n"); - } - break; - case 6: - // DO NOT offset R and C by 1! (checked against /usr/X11R6/bin/resize - // FIXME check again. - // FIXME: but vttest thinks different??? - writeSpecial((ESC) + "[" + R + ";" + C + "R"); - if (debug > 1) { - debug("ESC[6n"); - } - break; - default: - if (debug > 0) { - debug("ESC [ " + DCEvars[0] + " n??"); - } - break; - } - break; - case 's': /* DECSC - save cursor */ - Sc = C; - Sr = R; - Sa = attributes; - if (debug > 3) { - debug("ESC[s"); - } - break; - case 'u': /* DECRC - restore cursor */ - C = Sc; - R = Sr; - attributes = Sa; - if (debug > 3) { - debug("ESC[u"); - } - break; - case 'm': /* attributes as color, bold , blink, */ - if (debug > 3) { - debug("ESC [ "); - } - if (DCEvar == 0 && DCEvars[0] == 0) { - attributes = 0; - } - for (int i = 0; i <= DCEvar; i++) { - switch (DCEvars[i]) { - case 0: - if (DCEvar > 0) { - if (terminalID.equals("scoansi")) { - attributes &= COLOR; /* Keeps color. Strange but true. */ - } else { - attributes = 0; - } - } - break; - case 1: - attributes |= BOLD; - attributes &= ~LOW; - break; - case 2: - /* SCO color hack mode */ - if (terminalID.equals("scoansi") && ((DCEvar - i) >= 2)) { - int ncolor; - attributes &= ~(COLOR | BOLD); - - ncolor = DCEvars[i + 1]; - if ((ncolor & 8) == 8) { - attributes |= BOLD; - } - ncolor = ((ncolor & 1) << 2) | (ncolor & 2) | ((ncolor & 4) >> 2); - attributes |= ((ncolor) + 1) << COLOR_FG_SHIFT; - ncolor = DCEvars[i + 2]; - ncolor = ((ncolor & 1) << 2) | (ncolor & 2) | ((ncolor & 4) >> 2); - attributes |= ((ncolor) + 1) << COLOR_BG_SHIFT; - i += 2; - } else { - attributes |= LOW; - } - break; - case 3: /* italics */ - attributes |= INVERT; - break; - case 4: - attributes |= UNDERLINE; - break; - case 7: - attributes |= INVERT; - break; - case 8: - attributes |= INVISIBLE; - break; - case 5: /* blink on */ - break; - /* - * 10 - ANSI X3.64-1979, select primary font, don't display control chars, don't set bit 8 - * on output - */ - case 10: - gl = 0; - usedcharsets = true; - break; - /* - * 11 - ANSI X3.64-1979, select second alt. font, display control chars, set bit 8 on - * output - */ - case 11: /* SMACS , as */ - case 12: - gl = 1; - usedcharsets = true; - break; - case 21: /* normal intensity */ - attributes &= ~(LOW | BOLD); - break; - case 23: /* italics off */ - attributes &= ~INVERT; - break; - case 25: /* blinking off */ - break; - case 27: - attributes &= ~INVERT; - break; - case 28: - attributes &= ~INVISIBLE; - break; - case 24: - attributes &= ~UNDERLINE; - break; - case 22: - attributes &= ~BOLD; - break; - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - attributes &= ~COLOR_FG; - attributes |= ((DCEvars[i] - 30) + 1) << COLOR_FG_SHIFT; - break; - case 38: - if (DCEvars[i + 1] == 5) { - attributes &= ~COLOR_FG; - attributes |= ((DCEvars[i + 2]) + 1) << COLOR_FG_SHIFT; - i += 2; - } - break; - case 39: - attributes &= ~COLOR_FG; - break; - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - attributes &= ~COLOR_BG; - attributes |= ((DCEvars[i] - 40) + 1) << COLOR_BG_SHIFT; - break; - case 48: - if (DCEvars[i + 1] == 5) { - attributes &= ~COLOR_BG; - attributes |= (DCEvars[i + 2] + 1) << COLOR_BG_SHIFT; - i += 2; - } - break; - case 49: - attributes &= ~COLOR_BG; - break; - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - attributes &= ~COLOR_FG; - attributes |= ((DCEvars[i] - 82) + 1) << COLOR_FG_SHIFT; - break; - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - attributes &= ~COLOR_BG; - attributes |= ((DCEvars[i] - 92) + 1) << COLOR_BG_SHIFT; - break; - - default: - debugStr.append("ESC [ ").append(DCEvars[i]).append(" m unknown..."); - debug(debugStr.toString()); - debugStr.setLength(0); - break; - } - if (debug > 3) { - debugStr.append(DCEvars[i]).append(';'); - debug(debugStr.toString()); - debugStr.setLength(0); - } - } - if (debug > 3) { - debugStr.append(" (attributes = ").append(attributes).append(")m"); - debug(debugStr.toString()); - debugStr.setLength(0); - } - break; - default: - debugStr.append("ESC [ unknown letter: ").append(c).append(" (").append((int) c) - .append(')'); - debug(debugStr.toString()); - debugStr.setLength(0); - break; - } - break; - case TSTATE_TITLE: - switch (c) { - case ESC: - term_state = TSTATE_ESC; - break; - default: - // TODO save title - break; - } - break; - default: - term_state = TSTATE_DATA; - break; - } - - setCursorPosition(C, R); - } - - /* hard reset the terminal */ - public void reset() { - gx[0] = 'B'; - gx[1] = 'B'; - gx[2] = 'B'; - gx[3] = 'B'; - - gl = 0; // default GL to G0 - gr = 2; // default GR to G2 - - onegl = -1; // Single shift override - - /* reset tabs */ - int nw = width; - if (nw < 132) { - nw = 132; - } - Tabs = new byte[nw]; - for (int i = 0; i < nw; i += 8) { - Tabs[i] = 1; - } - - deleteArea(0, 0, width, height, attributes); - setMargins(0, height); - C = R = 0; - _SetCursor(0, 0); - - if (display != null) { - display.resetColors(); - } - - showCursor(true); - /* FIXME: */ - term_state = TSTATE_DATA; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/apache/harmony/niochar/charset/additional/IBM437.java b/sl4a/ScriptingLayerForAndroid/src/org/apache/harmony/niochar/charset/additional/IBM437.java deleted file mode 100644 index 1f01579..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/apache/harmony/niochar/charset/additional/IBM437.java +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.apache.harmony.niochar.charset.additional; - -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CharsetEncoder; -import java.nio.charset.CoderResult; - -/* TODO: support direct byte buffers -import org.apache.harmony.nio.AddressUtil; -import org.apache.harmony.niochar.CharsetProviderImpl; -*/ - -public class IBM437 extends Charset { - - public IBM437(String csName, String[] aliases) { - super(csName, aliases); - } - - public boolean contains(Charset cs) { - return cs.name().equalsIgnoreCase("IBM367") || cs.name().equalsIgnoreCase("IBM437") || cs.name().equalsIgnoreCase("US-ASCII") ; - } - - public CharsetDecoder newDecoder() { - return new Decoder(this); - } - - public CharsetEncoder newEncoder() { - return new Encoder(this); - } - - private static final class Decoder extends CharsetDecoder{ - private Decoder(Charset cs){ - super(cs, 1, 1); - - } - - private native int nDecode(char[] array, int arrPosition, int remaining, long outAddr, int absolutePos); - - - protected CoderResult decodeLoop(ByteBuffer bb, CharBuffer cb){ - int cbRemaining = cb.remaining(); -/* TODO: support direct byte buffers - if(CharsetProviderImpl.hasLoadedNatives() && bb.isDirect() && bb.hasRemaining() && cb.hasArray()){ - int toProceed = bb.remaining(); - int cbPos = cb.position(); - int bbPos = bb.position(); - boolean throwOverflow = false; - if( cbRemaining < toProceed ) { - toProceed = cbRemaining; - throwOverflow = true; - } - int res = nDecode(cb.array(), cb.arrayOffset()+cbPos, toProceed, AddressUtil.getDirectBufferAddress(bb), bbPos); - bb.position(bbPos+res); - cb.position(cbPos+res); - if(throwOverflow) return CoderResult.OVERFLOW; - }else{ -*/ - if(bb.hasArray() && cb.hasArray()) { - int rem = bb.remaining(); - rem = cbRemaining >= rem ? rem : cbRemaining; - byte[] bArr = bb.array(); - char[] cArr = cb.array(); - int bStart = bb.position(); - int cStart = cb.position(); - int i; - for(i=bStart; i<bStart+rem; i++) { - char in = (char)(bArr[i] & 0xFF); - if(in >= 26){ - int index = (int)in - 26; - cArr[cStart++] = (char)arr[index]; - }else { - cArr[cStart++] = (char)(in & 0xFF); - } - } - bb.position(i); - cb.position(cStart); - if(rem == cbRemaining && bb.hasRemaining()) return CoderResult.OVERFLOW; - } else { - while(bb.hasRemaining()){ - if( cbRemaining == 0 ) return CoderResult.OVERFLOW; - char in = (char)(bb.get() & 0xFF); - if(in >= 26){ - int index = (int)in - 26; - cb.put(arr[index]); - }else { - cb.put((char)(in & 0xFF)); - } - cbRemaining--; - } -/* - } -*/ - } - return CoderResult.UNDERFLOW; - } - - final static char[] arr = { - 0x001C,0x001B,0x007F,0x001D,0x001E,0x001F, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027, - 0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0x002F, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037, - 0x0038,0x0039,0x003A,0x003B,0x003C,0x003D,0x003E,0x003F, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, - 0x0048,0x0049,0x004A,0x004B,0x004C,0x004D,0x004E,0x004F, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, - 0x0058,0x0059,0x005A,0x005B,0x005C,0x005D,0x005E,0x005F, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, - 0x0068,0x0069,0x006A,0x006B,0x006C,0x006D,0x006E,0x006F, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, - 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x001A, - 0x00C7,0x00FC,0x00E9,0x00E2,0x00E4,0x00E0,0x00E5,0x00E7, - 0x00EA,0x00EB,0x00E8,0x00EF,0x00EE,0x00EC,0x00C4,0x00C5, - 0x00C9,0x00E6,0x00C6,0x00F4,0x00F6,0x00F2,0x00FB,0x00F9, - 0x00FF,0x00D6,0x00DC,0x00A2,0x00A3,0x00A5,0x20A7,0x0192, - 0x00E1,0x00ED,0x00F3,0x00FA,0x00F1,0x00D1,0x00AA,0x00BA, - 0x00BF,0x2310,0x00AC,0x00BD,0x00BC,0x00A1,0x00AB,0x00BB, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556, - 0x2555,0x2563,0x2551,0x2557,0x255D,0x255C,0x255B,0x2510, - 0x2514,0x2534,0x252C,0x251C,0x2500,0x253C,0x255E,0x255F, - 0x255A,0x2554,0x2569,0x2566,0x2560,0x2550,0x256C,0x2567, - 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256B, - 0x256A,0x2518,0x250C,0x2588,0x2584,0x258C,0x2590,0x2580, - 0x03B1,0x00DF,0x0393,0x03C0,0x03A3,0x03C3,0x03BC,0x03C4, - 0x03A6,0x0398,0x03A9,0x03B4,0x221E,0x03C6,0x03B5,0x2229, - 0x2261,0x00B1,0x2265,0x2264,0x2320,0x2321,0x00F7,0x2248, - 0x00B0,0x2219,0x00B7,0x221A,0x207F,0x00B2,0x25A0,0x00A0 - }; - } - - private static final class Encoder extends CharsetEncoder{ - private Encoder(Charset cs){ - super(cs, 1, 1); - } - - private native void nEncode(long outAddr, int absolutePos, char[] array, int arrPosition, int[] res); - - protected CoderResult encodeLoop(CharBuffer cb, ByteBuffer bb){ - int bbRemaining = bb.remaining(); -/* TODO: support direct byte buffers - if(CharsetProviderImpl.hasLoadedNatives() && bb.isDirect() && cb.hasRemaining() && cb.hasArray()){ - int toProceed = cb.remaining(); - int cbPos = cb.position(); - int bbPos = bb.position(); - boolean throwOverflow = false; - if( bbRemaining < toProceed ) { - toProceed = bbRemaining; - throwOverflow = true; - } - int[] res = {toProceed, 0}; - nEncode(AddressUtil.getDirectBufferAddress(bb), bbPos, cb.array(), cb.arrayOffset()+cbPos, res); - if( res[0] <= 0 ) { - bb.position(bbPos-res[0]); - cb.position(cbPos-res[0]); - if(res[1]!=0) { - if(res[1] < 0) - return CoderResult.malformedForLength(-res[1]); - else - return CoderResult.unmappableForLength(res[1]); - } - }else{ - bb.position(bbPos+res[0]); - cb.position(cbPos+res[0]); - if(throwOverflow) return CoderResult.OVERFLOW; - } - }else{ -*/ - if(bb.hasArray() && cb.hasArray()) { - byte[] byteArr = bb.array(); - char[] charArr = cb.array(); - int rem = cb.remaining(); - int byteArrStart = bb.position(); - rem = bbRemaining <= rem ? bbRemaining : rem; - int x; - for(x = cb.position(); x < cb.position()+rem; x++) { - char c = charArr[x]; - if(c > (char)0x25A0){ - if (c >= 0xD800 && c <= 0xDFFF) { - if(x+1 < cb.limit()) { - char c1 = charArr[x+1]; - if(c1 >= 0xD800 && c1 <= 0xDFFF) { - cb.position(x); bb.position(byteArrStart); - return CoderResult.unmappableForLength(2); - } - } else { - cb.position(x); bb.position(byteArrStart); - return CoderResult.UNDERFLOW; - } - cb.position(x); bb.position(byteArrStart); - return CoderResult.malformedForLength(1); - } - cb.position(x); bb.position(byteArrStart); - return CoderResult.unmappableForLength(1); - }else{ - if(c < 0x1A) { - byteArr[byteArrStart++] = (byte)c; - } else { - int index = (int)c >> 8; - index = encodeIndex[index]; - if(index < 0) { - cb.position(x); bb.position(byteArrStart); - return CoderResult.unmappableForLength(1); - } - index <<= 8; - index += (int)c & 0xFF; - if((byte)arr[index] != 0){ - byteArr[byteArrStart++] = (byte)arr[index]; - }else{ - cb.position(x); bb.position(byteArrStart); - return CoderResult.unmappableForLength(1); - } - } - } - } - cb.position(x); - bb.position(byteArrStart); - if(rem == bbRemaining && cb.hasRemaining()) { - return CoderResult.OVERFLOW; - } - } else { - while(cb.hasRemaining()){ - if( bbRemaining == 0 ) return CoderResult.OVERFLOW; - char c = cb.get(); - if(c > (char)0x25A0){ - if (c >= 0xD800 && c <= 0xDFFF) { - if(cb.hasRemaining()) { - char c1 = cb.get(); - if(c1 >= 0xD800 && c1 <= 0xDFFF) { - cb.position(cb.position()-2); - return CoderResult.unmappableForLength(2); - } else { - cb.position(cb.position()-1); - } - } else { - cb.position(cb.position()-1); - return CoderResult.UNDERFLOW; - } - cb.position(cb.position()-1); - return CoderResult.malformedForLength(1); - } - cb.position(cb.position()-1); - return CoderResult.unmappableForLength(1); - }else{ - if(c < 0x1A) { - bb.put((byte)c); - } else { - int index = (int)c >> 8; - index = encodeIndex[index]; - if(index < 0) { - cb.position(cb.position()-1); - return CoderResult.unmappableForLength(1); - } - index <<= 8; - index += (int)c & 0xFF; - if((byte)arr[index] != 0){ - bb.put((byte)arr[index]); - }else{ - cb.position(cb.position()-1); - return CoderResult.unmappableForLength(1); - } - } - bbRemaining--; - } - } -/* TODO: support direct byte buffers - } -*/ - } - return CoderResult.UNDERFLOW; - } - - final static char arr[] = { - - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x7F,0x1B,0x1A,0x1D,0x1E,0x1F, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x1C, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xFF,0xAD,0x9B,0x9C,0x00,0x9D,0x00,0x00,0x00,0x00,0xA6,0xAE,0xAA,0x00,0x00,0x00, - 0xF8,0xF1,0xFD,0x00,0x00,0x00,0x00,0xFA,0x00,0x00,0xA7,0xAF,0xAC,0xAB,0x00,0xA8, - 0x00,0x00,0x00,0x00,0x8E,0x8F,0x92,0x80,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xA5,0x00,0x00,0x00,0x00,0x99,0x00,0x00,0x00,0x00,0x00,0x9A,0x00,0x00,0xE1, - 0x85,0xA0,0x83,0x00,0x84,0x86,0x91,0x87,0x8A,0x82,0x88,0x89,0x8D,0xA1,0x8C,0x8B, - 0x00,0xA4,0x95,0xA2,0x93,0x00,0x94,0xF6,0x00,0x97,0xA3,0x96,0x81,0x00,0x00,0x98, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x9F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE2,0x00,0x00,0x00,0x00,0xE9,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0xE4,0x00,0x00,0xE8,0x00,0x00,0xEA,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xE0,0x00,0x00,0xEB,0xEE,0x00,0x00,0x00,0x00,0x00,0x00,0xE6,0x00,0x00,0x00, - 0xE3,0x00,0x00,0xE5,0xE7,0x00,0xED,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF9,0xFB,0x00,0x00,0x00,0xEC,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEF,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF7,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xF0,0x00,0x00,0xF3,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xA9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xF4,0xF5,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - - 0xC4,0x00,0xB3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDA,0x00,0x00,0x00, - 0xBF,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0xD9,0x00,0x00,0x00,0xC3,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xB4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xC1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xCD,0xBA,0xD5,0xD6,0xC9,0xB8,0xB7,0xBB,0xD4,0xD3,0xC8,0xBE,0xBD,0xBC,0xC6,0xC7, - 0xCC,0xB5,0xB6,0xB9,0xD1,0xD2,0xCB,0xCF,0xD0,0xCA,0xD8,0xD7,0xCE,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xDF,0x00,0x00,0x00,0xDC,0x00,0x00,0x00,0xDB,0x00,0x00,0x00,0xDD,0x00,0x00,0x00, - 0xDE,0xB0,0xB1,0xB2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 - }; - - final static int[] encodeIndex = { - 0,1,-1,2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 3,-1,4,5,-1,6,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - }; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/ConsoleActivity.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/ConsoleActivity.java deleted file mode 100644 index bb4490a..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/ConsoleActivity.java +++ /dev/null @@ -1,985 +0,0 @@ -/* - * 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. - */ - -/** - * @author modified by raaar - * - */ - -package org.connectbot; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.SharedPreferences; -import android.content.pm.ActivityInfo; -import android.content.res.Configuration; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.Message; -import android.os.PowerManager; -import android.preference.PreferenceManager; -import android.text.ClipboardManager; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.GestureDetector; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnTouchListener; -import android.view.ViewConfiguration; -import android.view.WindowManager; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; -import android.widget.ViewFlipper; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.ScriptProcess; -import com.googlecode.android_scripting.activity.Preferences; -import com.googlecode.android_scripting.activity.ScriptingLayerService; - -import de.mud.terminal.VDUBuffer; -import de.mud.terminal.vt320; - -import org.connectbot.service.PromptHelper; -import org.connectbot.service.TerminalBridge; -import org.connectbot.service.TerminalManager; -import org.connectbot.util.PreferenceConstants; -import org.connectbot.util.SelectionArea; - -public class ConsoleActivity extends Activity { - - protected static final int REQUEST_EDIT = 1; - - private static final int CLICK_TIME = 250; - private static final float MAX_CLICK_DISTANCE = 25f; - private static final int KEYBOARD_DISPLAY_TIME = 1250; - - // Direction to shift the ViewFlipper - private static final int SHIFT_LEFT = 0; - private static final int SHIFT_RIGHT = 1; - - protected ViewFlipper flip = null; - protected TerminalManager manager = null; - protected ScriptingLayerService mService = null; - protected LayoutInflater inflater = null; - - private SharedPreferences prefs = null; - - private PowerManager.WakeLock wakelock = null; - - protected Integer processID; - - protected ClipboardManager clipboard; - - private RelativeLayout booleanPromptGroup; - private TextView booleanPrompt; - private Button booleanYes, booleanNo; - - private Animation slide_left_in, slide_left_out, slide_right_in, slide_right_out, - fade_stay_hidden, fade_out_delayed; - - private Animation keyboard_fade_in, keyboard_fade_out; - private ImageView keyboardButton; - private float lastX, lastY; - - private int mTouchSlopSquare; - - private InputMethodManager inputManager; - - protected TerminalBridge copySource = null; - private int lastTouchRow, lastTouchCol; - - private boolean forcedOrientation; - - private Handler handler = new Handler(); - - private static enum MenuId { - EDIT, PREFS, EMAIL, RESIZE, COPY, PASTE; - public int getId() { - return ordinal() + Menu.FIRST; - } - } - - private final ServiceConnection mConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - mService = ((ScriptingLayerService.LocalBinder) service).getService(); - manager = mService.getTerminalManager(); - // let manager know about our event handling services - manager.setDisconnectHandler(disconnectHandler); - - Log.d(String.format("Connected to TerminalManager and found bridges.size=%d", manager - .getBridgeList().size())); - - manager.setResizeAllowed(true); - - // clear out any existing bridges and record requested index - flip.removeAllViews(); - - int requestedIndex = 0; - - TerminalBridge requestedBridge = manager.getConnectedBridge(processID); - - // If we didn't find the requested connection, try opening it - if (processID != null && requestedBridge == null) { - try { - Log.d(String.format( - "We couldnt find an existing bridge with id = %d, so creating one now", processID)); - requestedBridge = manager.openConnection(processID); - } catch (Exception e) { - Log.e("Problem while trying to create new requested bridge", e); - } - } - - // create views for all bridges on this service - for (TerminalBridge bridge : manager.getBridgeList()) { - - final int currentIndex = addNewTerminalView(bridge); - - // check to see if this bridge was requested - if (bridge == requestedBridge) { - requestedIndex = currentIndex; - } - } - - setDisplayedTerminal(requestedIndex); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - manager = null; - mService = null; - } - }; - - protected Handler promptHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - // someone below us requested to display a prompt - updatePromptVisible(); - } - }; - - protected Handler disconnectHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - Log.d("Someone sending HANDLE_DISCONNECT to parentHandler"); - TerminalBridge bridge = (TerminalBridge) msg.obj; - closeBridge(bridge); - } - }; - - /** - * @param bridge - */ - private void closeBridge(final TerminalBridge bridge) { - synchronized (flip) { - final int flipIndex = getFlipIndex(bridge); - - if (flipIndex >= 0) { - if (flip.getDisplayedChild() == flipIndex) { - shiftCurrentTerminal(SHIFT_LEFT); - } - flip.removeViewAt(flipIndex); - - /* - * TODO Remove this workaround when ViewFlipper is fixed to listen to view removals. Android - * Issue 1784 - */ - final int numChildren = flip.getChildCount(); - if (flip.getDisplayedChild() >= numChildren && numChildren > 0) { - flip.setDisplayedChild(numChildren - 1); - } - } - - // If we just closed the last bridge, go back to the previous activity. - if (flip.getChildCount() == 0) { - finish(); - } - } - } - - protected View findCurrentView(int id) { - View view = flip.getCurrentView(); - if (view == null) { - return null; - } - return view.findViewById(id); - } - - protected PromptHelper getCurrentPromptHelper() { - View view = findCurrentView(R.id.console_flip); - if (!(view instanceof TerminalView)) { - return null; - } - return ((TerminalView) view).bridge.getPromptHelper(); - } - - protected void hideAllPrompts() { - booleanPromptGroup.setVisibility(View.GONE); - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - this.setContentView(R.layout.act_console); - - clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - prefs = PreferenceManager.getDefaultSharedPreferences(this); - - // hide status bar if requested by user - if (prefs.getBoolean(PreferenceConstants.FULLSCREEN, false)) { - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - } - - // TODO find proper way to disable volume key beep if it exists. - setVolumeControlStream(AudioManager.STREAM_MUSIC); - - PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE); - wakelock = manager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, getPackageName()); - - // handle requested console from incoming intent - int id = getIntent().getIntExtra(Constants.EXTRA_PROXY_PORT, -1); - - if (id > 0) { - processID = id; - } - - inflater = LayoutInflater.from(this); - - flip = (ViewFlipper) findViewById(R.id.console_flip); - booleanPromptGroup = (RelativeLayout) findViewById(R.id.console_boolean_group); - booleanPrompt = (TextView) findViewById(R.id.console_prompt); - - booleanYes = (Button) findViewById(R.id.console_prompt_yes); - booleanYes.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - PromptHelper helper = getCurrentPromptHelper(); - if (helper == null) { - return; - } - helper.setResponse(Boolean.TRUE); - updatePromptVisible(); - } - }); - - booleanNo = (Button) findViewById(R.id.console_prompt_no); - booleanNo.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - PromptHelper helper = getCurrentPromptHelper(); - if (helper == null) { - return; - } - helper.setResponse(Boolean.FALSE); - updatePromptVisible(); - } - }); - - // preload animations for terminal switching - slide_left_in = AnimationUtils.loadAnimation(this, R.anim.slide_left_in); - slide_left_out = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); - slide_right_in = AnimationUtils.loadAnimation(this, R.anim.slide_right_in); - slide_right_out = AnimationUtils.loadAnimation(this, R.anim.slide_right_out); - - fade_out_delayed = AnimationUtils.loadAnimation(this, R.anim.fade_out_delayed); - fade_stay_hidden = AnimationUtils.loadAnimation(this, R.anim.fade_stay_hidden); - - // Preload animation for keyboard button - keyboard_fade_in = AnimationUtils.loadAnimation(this, R.anim.keyboard_fade_in); - keyboard_fade_out = AnimationUtils.loadAnimation(this, R.anim.keyboard_fade_out); - - inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - keyboardButton = (ImageView) findViewById(R.id.keyboard_button); - keyboardButton.setOnClickListener(new OnClickListener() { - public void onClick(View view) { - View flip = findCurrentView(R.id.console_flip); - if (flip == null) { - return; - } - - inputManager.showSoftInput(flip, InputMethodManager.SHOW_FORCED); - keyboardButton.setVisibility(View.GONE); - } - }); - if (prefs.getBoolean(PreferenceConstants.HIDE_KEYBOARD, false)) { - // Force hidden keyboard. - getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN - | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - } - final ViewConfiguration configuration = ViewConfiguration.get(this); - int touchSlop = configuration.getScaledTouchSlop(); - mTouchSlopSquare = touchSlop * touchSlop; - - // detect fling gestures to switch between terminals - final GestureDetector detect = - new GestureDetector(new GestureDetector.SimpleOnGestureListener() { - private float totalY = 0; - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - - final float distx = e2.getRawX() - e1.getRawX(); - final float disty = e2.getRawY() - e1.getRawY(); - final int goalwidth = flip.getWidth() / 2; - - // need to slide across half of display to trigger console change - // make sure user kept a steady hand horizontally - if (Math.abs(disty) < (flip.getHeight() / 4)) { - if (distx > goalwidth) { - shiftCurrentTerminal(SHIFT_RIGHT); - return true; - } - - if (distx < -goalwidth) { - shiftCurrentTerminal(SHIFT_LEFT); - return true; - } - - } - - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - - // if copying, then ignore - if (copySource != null && copySource.isSelectingForCopy()) { - return false; - } - - if (e1 == null || e2 == null) { - return false; - } - - // if releasing then reset total scroll - if (e2.getAction() == MotionEvent.ACTION_UP) { - totalY = 0; - } - - // activate consider if within x tolerance - if (Math.abs(e1.getX() - e2.getX()) < ViewConfiguration.getTouchSlop() * 4) { - - View flip = findCurrentView(R.id.console_flip); - if (flip == null) { - return false; - } - TerminalView terminal = (TerminalView) flip; - - // estimate how many rows we have scrolled through - // accumulate distance that doesn't trigger immediate scroll - totalY += distanceY; - final int moved = (int) (totalY / terminal.bridge.charHeight); - - VDUBuffer buffer = terminal.bridge.getVDUBuffer(); - - // consume as scrollback only if towards right half of screen - if (e2.getX() > flip.getWidth() / 2) { - if (moved != 0) { - int base = buffer.getWindowBase(); - buffer.setWindowBase(base + moved); - totalY = 0; - return true; - } - } else { - // otherwise consume as pgup/pgdown for every 5 lines - if (moved > 5) { - ((vt320) buffer).keyPressed(vt320.KEY_PAGE_DOWN, ' ', 0); - terminal.bridge.tryKeyVibrate(); - totalY = 0; - return true; - } else if (moved < -5) { - ((vt320) buffer).keyPressed(vt320.KEY_PAGE_UP, ' ', 0); - terminal.bridge.tryKeyVibrate(); - totalY = 0; - return true; - } - - } - - } - - return false; - } - - }); - - flip.setOnCreateContextMenuListener(this); - - flip.setOnTouchListener(new OnTouchListener() { - - public boolean onTouch(View v, MotionEvent event) { - - // when copying, highlight the area - if (copySource != null && copySource.isSelectingForCopy()) { - int row = (int) Math.floor(event.getY() / copySource.charHeight); - int col = (int) Math.floor(event.getX() / copySource.charWidth); - - SelectionArea area = copySource.getSelectionArea(); - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // recording starting area - if (area.isSelectingOrigin()) { - area.setRow(row); - area.setColumn(col); - lastTouchRow = row; - lastTouchCol = col; - copySource.redraw(); - } - return true; - case MotionEvent.ACTION_MOVE: - /* - * ignore when user hasn't moved since last time so we can fine-tune with directional - * pad - */ - if (row == lastTouchRow && col == lastTouchCol) { - return true; - } - // if the user moves, start the selection for other corner - area.finishSelectingOrigin(); - - // update selected area - area.setRow(row); - area.setColumn(col); - lastTouchRow = row; - lastTouchCol = col; - copySource.redraw(); - return true; - case MotionEvent.ACTION_UP: - /* - * If they didn't move their finger, maybe they meant to select the rest of the text - * with the directional pad. - */ - if (area.getLeft() == area.getRight() && area.getTop() == area.getBottom()) { - return true; - } - - // copy selected area to clipboard - String copiedText = area.copyFrom(copySource.getVDUBuffer()); - - clipboard.setText(copiedText); - Toast.makeText(ConsoleActivity.this, - getString(R.string.terminal_copy_done, copiedText.length()), Toast.LENGTH_LONG) - .show(); - // fall through to clear state - - case MotionEvent.ACTION_CANCEL: - // make sure we clear any highlighted area - area.reset(); - copySource.setSelectingForCopy(false); - copySource.redraw(); - return true; - } - } - - Configuration config = getResources().getConfiguration(); - - if (event.getAction() == MotionEvent.ACTION_DOWN) { - lastX = event.getX(); - lastY = event.getY(); - } else if (event.getAction() == MotionEvent.ACTION_MOVE) { - final int deltaX = (int) (lastX - event.getX()); - final int deltaY = (int) (lastY - event.getY()); - int distance = (deltaX * deltaX) + (deltaY * deltaY); - if (distance > mTouchSlopSquare) { - // If currently scheduled long press event is not canceled here, - // GestureDetector.onScroll is executed, which takes a while, and by the time we are - // back in the view's dispatchTouchEvent - // mPendingCheckForLongPress is already executed - flip.cancelLongPress(); - } - } else if (event.getAction() == MotionEvent.ACTION_UP) { - // Same as above, except now GestureDetector.onFling is called. - flip.cancelLongPress(); - if (config.hardKeyboardHidden != Configuration.KEYBOARDHIDDEN_NO - && keyboardButton.getVisibility() == View.GONE - && event.getEventTime() - event.getDownTime() < CLICK_TIME - && Math.abs(event.getX() - lastX) < MAX_CLICK_DISTANCE - && Math.abs(event.getY() - lastY) < MAX_CLICK_DISTANCE) { - keyboardButton.startAnimation(keyboard_fade_in); - keyboardButton.setVisibility(View.VISIBLE); - - handler.postDelayed(new Runnable() { - public void run() { - if (keyboardButton.getVisibility() == View.GONE) { - return; - } - - keyboardButton.startAnimation(keyboard_fade_out); - keyboardButton.setVisibility(View.GONE); - } - }, KEYBOARD_DISPLAY_TIME); - - return false; - } - } - // pass any touch events back to detector - return detect.onTouchEvent(event); - } - - }); - - } - - private void configureOrientation() { - String rotateDefault; - if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_NOKEYS) { - rotateDefault = PreferenceConstants.ROTATION_PORTRAIT; - } else { - rotateDefault = PreferenceConstants.ROTATION_LANDSCAPE; - } - - String rotate = prefs.getString(PreferenceConstants.ROTATION, rotateDefault); - if (PreferenceConstants.ROTATION_DEFAULT.equals(rotate)) { - rotate = rotateDefault; - } - - // request a forced orientation if requested by user - if (PreferenceConstants.ROTATION_LANDSCAPE.equals(rotate)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - forcedOrientation = true; - } else if (PreferenceConstants.ROTATION_PORTRAIT.equals(rotate)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - forcedOrientation = true; - } else { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - forcedOrientation = false; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - getMenuInflater().inflate(R.menu.terminal, menu); - menu.setQwertyMode(true); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - setVolumeControlStream(AudioManager.STREAM_NOTIFICATION); - TerminalBridge bridge = ((TerminalView) findCurrentView(R.id.console_flip)).bridge; - boolean sessionOpen = bridge.isSessionOpen(); - menu.findItem(R.id.terminal_menu_resize).setEnabled(sessionOpen); - if (bridge.getProcess() instanceof ScriptProcess) { - menu.findItem(R.id.terminal_menu_exit_and_edit).setEnabled(true); - } - bridge.onPrepareOptionsMenu(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == R.id.terminal_menu_resize) { - doResize(); - } else if (item.getItemId() == R.id.terminal_menu_preferences) { - doPreferences(); - } else if (item.getItemId() == R.id.terminal_menu_send_email) { - doEmailTranscript(); - } else if (item.getItemId() == R.id.terminal_menu_exit_and_edit) { - TerminalView terminalView = (TerminalView) findCurrentView(R.id.console_flip); - TerminalBridge bridge = terminalView.bridge; - if (manager != null) { - manager.closeConnection(bridge, true); - } else { - Intent intent = new Intent(this, ScriptingLayerService.class); - intent.setAction(Constants.ACTION_KILL_PROCESS); - intent.putExtra(Constants.EXTRA_PROXY_PORT, bridge.getId()); - startService(intent); - Message.obtain(disconnectHandler, -1, bridge).sendToTarget(); - } - Intent intent = new Intent(Constants.ACTION_EDIT_SCRIPT); - ScriptProcess process = (ScriptProcess) bridge.getProcess(); - intent.putExtra(Constants.EXTRA_SCRIPT_PATH, process.getPath()); - startActivity(intent); - finish(); - } - return super.onOptionsItemSelected(item); - } - - @Override - public void onOptionsMenuClosed(Menu menu) { - super.onOptionsMenuClosed(menu); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - } - - private void doResize() { - closeOptionsMenu(); - final TerminalView terminalView = (TerminalView) findCurrentView(R.id.console_flip); - final View resizeView = inflater.inflate(R.layout.dia_resize, null, false); - new AlertDialog.Builder(ConsoleActivity.this).setView(resizeView) - .setPositiveButton(R.string.button_resize, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - int width, height; - try { - width = - Integer.parseInt(((EditText) resizeView.findViewById(R.id.width)).getText() - .toString()); - height = - Integer.parseInt(((EditText) resizeView.findViewById(R.id.height)).getText() - .toString()); - } catch (NumberFormatException nfe) { - return; - } - terminalView.forceSize(width, height); - } - }).setNegativeButton(android.R.string.cancel, null).create().show(); - } - - private void doPreferences() { - startActivity(new Intent(this, Preferences.class)); - } - - private void doEmailTranscript() { - // Don't really want to supply an address, but currently it's required, - // otherwise we get an exception. - TerminalView terminalView = (TerminalView) findCurrentView(R.id.console_flip); - TerminalBridge bridge = terminalView.bridge; - // TODO(raaar): Replace with process log. - VDUBuffer buffer = bridge.getVDUBuffer(); - int height = buffer.getRows(); - int width = buffer.getColumns(); - StringBuilder string = new StringBuilder(); - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - string.append(buffer.getChar(j, i)); - } - } - String addr = "user@example.com"; - Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + addr)); - intent.putExtra("body", string.toString().trim()); - startActivity(intent); - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { - TerminalBridge bridge = ((TerminalView) findCurrentView(R.id.console_flip)).bridge; - boolean sessionOpen = bridge.isSessionOpen(); - menu.add(Menu.NONE, MenuId.COPY.getId(), Menu.NONE, R.string.terminal_menu_copy); - if (clipboard.hasText() && sessionOpen) { - menu.add(Menu.NONE, MenuId.PASTE.getId(), Menu.NONE, R.string.terminal_menu_paste); - } - bridge.onCreateContextMenu(menu, view, menuInfo); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - int itemId = item.getItemId(); - if (itemId == MenuId.COPY.getId()) { - TerminalView terminalView = (TerminalView) findCurrentView(R.id.console_flip); - copySource = terminalView.bridge; - SelectionArea area = copySource.getSelectionArea(); - area.reset(); - area.setBounds(copySource.getVDUBuffer().getColumns(), copySource.getVDUBuffer().getRows()); - copySource.setSelectingForCopy(true); - // Make sure we show the initial selection - copySource.redraw(); - Toast.makeText(ConsoleActivity.this, getString(R.string.terminal_copy_start), - Toast.LENGTH_LONG).show(); - return true; - } else if (itemId == MenuId.PASTE.getId()) { - TerminalView terminalView = (TerminalView) findCurrentView(R.id.console_flip); - TerminalBridge bridge = terminalView.bridge; - // pull string from clipboard and generate all events to force down - String clip = clipboard.getText().toString(); - bridge.injectString(clip); - return true; - } - return false; - } - - @Override - public void onStart() { - super.onStart(); - // connect with manager service to find all bridges - // when connected it will insert all views - bindService(new Intent(this, ScriptingLayerService.class), mConnection, 0); - } - - @Override - public void onPause() { - super.onPause(); - Log.d("onPause called"); - - // Allow the screen to dim and fall asleep. - if (wakelock != null && wakelock.isHeld()) { - wakelock.release(); - } - - if (forcedOrientation && manager != null) { - manager.setResizeAllowed(false); - } - } - - @Override - public void onResume() { - super.onResume(); - Log.d("onResume called"); - - // Make sure we don't let the screen fall asleep. - // This also keeps the Wi-Fi chipset from disconnecting us. - if (wakelock != null && prefs.getBoolean(PreferenceConstants.KEEP_ALIVE, true)) { - wakelock.acquire(); - } - - configureOrientation(); - - if (forcedOrientation && manager != null) { - manager.setResizeAllowed(true); - } - } - - /* - * (non-Javadoc) - * - * @see android.app.Activity#onNewIntent(android.content.Intent) - */ - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - - Log.d("onNewIntent called"); - - int id = intent.getIntExtra(Constants.EXTRA_PROXY_PORT, -1); - - if (id > 0) { - processID = id; - } - - if (processID == null) { - Log.e("Got null intent data in onNewIntent()"); - return; - } - - if (manager == null) { - Log.e("We're not bound in onNewIntent()"); - return; - } - - TerminalBridge requestedBridge = manager.getConnectedBridge(processID); - int requestedIndex = 0; - - synchronized (flip) { - if (requestedBridge == null) { - // If we didn't find the requested connection, try opening it - - try { - Log.d(String.format("We couldnt find an existing bridge with id = %d," - + "so creating one now", processID)); - requestedBridge = manager.openConnection(processID); - } catch (Exception e) { - Log.e("Problem while trying to create new requested bridge", e); - } - - requestedIndex = addNewTerminalView(requestedBridge); - } else { - final int flipIndex = getFlipIndex(requestedBridge); - if (flipIndex > requestedIndex) { - requestedIndex = flipIndex; - } - } - - setDisplayedTerminal(requestedIndex); - } - } - - @Override - public void onStop() { - super.onStop(); - unbindService(mConnection); - } - - protected void shiftCurrentTerminal(final int direction) { - View overlay; - synchronized (flip) { - boolean shouldAnimate = flip.getChildCount() > 1; - - // Only show animation if there is something else to go to. - if (shouldAnimate) { - // keep current overlay from popping up again - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) { - overlay.startAnimation(fade_stay_hidden); - } - - if (direction == SHIFT_LEFT) { - flip.setInAnimation(slide_left_in); - flip.setOutAnimation(slide_left_out); - flip.showNext(); - } else if (direction == SHIFT_RIGHT) { - flip.setInAnimation(slide_right_in); - flip.setOutAnimation(slide_right_out); - flip.showPrevious(); - } - } - - if (shouldAnimate) { - // show overlay on new slide and start fade - overlay = findCurrentView(R.id.terminal_overlay); - if (overlay != null) { - overlay.startAnimation(fade_out_delayed); - } - } - - updatePromptVisible(); - } - } - - /** - * Show any prompts requested by the currently visible {@link TerminalView}. - */ - protected void updatePromptVisible() { - // check if our currently-visible terminalbridge is requesting any prompt services - View view = findCurrentView(R.id.console_flip); - - // Hide all the prompts in case a prompt request was canceled - hideAllPrompts(); - - if (!(view instanceof TerminalView)) { - // we dont have an active view, so hide any prompts - return; - } - - PromptHelper prompt = ((TerminalView) view).bridge.getPromptHelper(); - - if (Boolean.class.equals(prompt.promptRequested)) { - booleanPromptGroup.setVisibility(View.VISIBLE); - booleanPrompt.setText(prompt.promptHint); - booleanYes.requestFocus(); - } else { - hideAllPrompts(); - view.requestFocus(); - } - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - - Log.d(String.format( - "onConfigurationChanged; requestedOrientation=%d, newConfig.orientation=%d", - getRequestedOrientation(), newConfig.orientation)); - if (manager != null) { - if (forcedOrientation - && (newConfig.orientation != Configuration.ORIENTATION_LANDSCAPE && getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) - || (newConfig.orientation != Configuration.ORIENTATION_PORTRAIT && getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)) { - manager.setResizeAllowed(false); - } else { - manager.setResizeAllowed(true); - } - - manager - .setHardKeyboardHidden(newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES); - } - } - - /** - * Adds a new TerminalBridge to the current set of views in our ViewFlipper. - * - * @param bridge - * TerminalBridge to add to our ViewFlipper - * @return the child index of the new view in the ViewFlipper - */ - private int addNewTerminalView(TerminalBridge bridge) { - // let them know about our prompt handler services - bridge.getPromptHelper().setHandler(promptHandler); - - // inflate each terminal view - RelativeLayout view = (RelativeLayout) inflater.inflate(R.layout.item_terminal, flip, false); - - // set the terminal overlay text - TextView overlay = (TextView) view.findViewById(R.id.terminal_overlay); - overlay.setText(bridge.getName()); - - // and add our terminal view control, using index to place behind overlay - TerminalView terminal = new TerminalView(ConsoleActivity.this, bridge); - terminal.setId(R.id.console_flip); - view.addView(terminal, 0); - - synchronized (flip) { - // finally attach to the flipper - flip.addView(view); - return flip.getChildCount() - 1; - } - } - - private int getFlipIndex(TerminalBridge bridge) { - synchronized (flip) { - final int children = flip.getChildCount(); - for (int i = 0; i < children; i++) { - final View view = flip.getChildAt(i).findViewById(R.id.console_flip); - - if (view == null || !(view instanceof TerminalView)) { - // How did that happen? - continue; - } - - final TerminalView tv = (TerminalView) view; - - if (tv.bridge == bridge) { - return i; - } - } - } - - return -1; - } - - /** - * Displays the child in the ViewFlipper at the requestedIndex and updates the prompts. - * - * @param requestedIndex - * the index of the terminal view to display - */ - private void setDisplayedTerminal(int requestedIndex) { - synchronized (flip) { - try { - // show the requested bridge if found, also fade out overlay - flip.setDisplayedChild(requestedIndex); - flip.getCurrentView().findViewById(R.id.terminal_overlay).startAnimation(fade_out_delayed); - } catch (NullPointerException npe) { - Log.d("View went away when we were about to display it", npe); - } - updatePromptVisible(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpActivity.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpActivity.java deleted file mode 100644 index 0ec485e..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpActivity.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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; - -import android.app.Activity; -import android.content.Intent; -import android.content.res.AssetManager; -import android.os.Bundle; -import android.text.method.LinkMovementMethod; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.Version; - -import java.io.IOException; - -/** - * @author Kenny Root - * - */ -public class HelpActivity extends Activity { - public final static String TAG = "ConnectBot.HelpActivity"; - - public final static String HELPDIR = "help"; - public final static String SUFFIX = ".html"; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.act_help); - - this.setTitle(String.format("%s: %s", getResources().getText(R.string.application_nice_title), - getResources().getText(R.string.title_help))); - - TextView subtitle = (TextView) findViewById(R.id.version); - subtitle.setText(getText(R.string.application_title) + " r" - + Version.getVersion(getApplication())); - - ((TextView) findViewById(R.id.help_acks_text)).setMovementMethod(LinkMovementMethod - .getInstance()); - - AssetManager am = getAssets(); - LinearLayout content = (LinearLayout) findViewById(R.id.topics); - - try { - for (String name : am.list(HELPDIR)) { - if (name.endsWith(SUFFIX)) { - Button button = new Button(this); - final String topic = name.substring(0, name.length() - SUFFIX.length()); - button.setText(topic); - - button.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - Intent intent = new Intent(HelpActivity.this, HelpTopicActivity.class); - intent.putExtra(Intent.EXTRA_TITLE, topic); - HelpActivity.this.startActivity(intent); - } - }); - - content.addView(button); - } - } - } catch (IOException e) { - // TODO Auto-generated catch block - Log.e("couldn't get list of help assets", e); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpTopicActivity.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpTopicActivity.java deleted file mode 100644 index 6453607..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/HelpTopicActivity.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; - -import com.googlecode.android_scripting.R; - -import org.connectbot.util.HelpTopicView; - -/** - * @author Kenny Root - * - */ -public class HelpTopicActivity extends Activity { - public final static String TAG = "ConnectBot.HelpActivity"; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - setContentView(R.layout.act_help_topic); - - String topic = getIntent().getStringExtra(Intent.EXTRA_TITLE); - - this.setTitle(String.format("%s: %s - %s", getResources().getText(R.string.application_title), - getResources().getText(R.string.title_help), topic)); - - HelpTopicView helpTopic = (HelpTopicView) findViewById(R.id.topic_text); - - helpTopic.setTopic(topic); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/TerminalView.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/TerminalView.java deleted file mode 100644 index dfe231b..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/TerminalView.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * 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; - -import android.app.Activity; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PixelXorXfermode; -import android.graphics.RectF; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.widget.Toast; -import de.mud.terminal.VDUBuffer; - -import org.connectbot.service.FontSizeChangedListener; -import org.connectbot.service.TerminalBridge; -import org.connectbot.service.TerminalKeyListener; -import org.connectbot.util.SelectionArea; - -/** - * User interface {@link View} for showing a TerminalBridge in an {@link Activity}. Handles drawing - * bitmap updates and passing keystrokes down to terminal. - * @author jsharkey - */ -public class TerminalView extends View implements FontSizeChangedListener { - - private final Context context; - public final TerminalBridge bridge; - private final Paint paint; - private final Paint cursorPaint; - private final Paint cursorStrokePaint; - - // Cursor paints to distinguish modes - private Path ctrlCursor, altCursor, shiftCursor; - private RectF tempSrc, tempDst; - private Matrix scaleMatrix; - private static final Matrix.ScaleToFit scaleType = Matrix.ScaleToFit.FILL; - - private Toast notification = null; - private String lastNotification = null; - private volatile boolean notifications = true; - - public TerminalView(Context context, TerminalBridge bridge) { - super(context); - - this.context = context; - this.bridge = bridge; - paint = new Paint(); - - setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); - setFocusable(true); - setFocusableInTouchMode(true); - - cursorPaint = new Paint(); - cursorPaint.setColor(bridge.getForegroundColor()); - cursorPaint.setXfermode(new PixelXorXfermode(bridge.getBackgroundColor())); - cursorPaint.setAntiAlias(true); - - cursorStrokePaint = new Paint(cursorPaint); - cursorStrokePaint.setStrokeWidth(0.1f); - cursorStrokePaint.setStyle(Paint.Style.STROKE); - - /* - * Set up our cursor indicators on a 1x1 Path object which we can later transform to our - * character width and height - */ - // TODO make this into a resource somehow - shiftCursor = new Path(); - shiftCursor.lineTo(0.5f, 0.33f); - shiftCursor.lineTo(1.0f, 0.0f); - - altCursor = new Path(); - altCursor.moveTo(0.0f, 1.0f); - altCursor.lineTo(0.5f, 0.66f); - altCursor.lineTo(1.0f, 1.0f); - - ctrlCursor = new Path(); - ctrlCursor.moveTo(0.0f, 0.25f); - ctrlCursor.lineTo(1.0f, 0.5f); - ctrlCursor.lineTo(0.0f, 0.75f); - - // For creating the transform when the terminal resizes - tempSrc = new RectF(); - tempSrc.set(0.0f, 0.0f, 1.0f, 1.0f); - tempDst = new RectF(); - scaleMatrix = new Matrix(); - - bridge.addFontSizeChangedListener(this); - - // connect our view up to the bridge - setOnKeyListener(bridge.getKeyHandler()); - } - - public void destroy() { - // tell bridge to destroy its bitmap - bridge.parentDestroyed(); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - bridge.parentChanged(this); - - scaleCursors(); - } - - public void onFontSizeChanged(float size) { - scaleCursors(); - } - - private void scaleCursors() { - // Create a scale matrix to scale our 1x1 representation of the cursor - tempDst.set(0.0f, 0.0f, bridge.charWidth, bridge.charHeight); - scaleMatrix.setRectToRect(tempSrc, tempDst, scaleType); - } - - @Override - public void onDraw(Canvas canvas) { - if (bridge.getBitmap() != null) { - // draw the bitmap - bridge.onDraw(); - - // draw the bridge bitmap if it exists - canvas.drawBitmap(bridge.getBitmap(), 0, 0, paint); - - VDUBuffer buffer = bridge.getVDUBuffer(); - - // also draw cursor if visible - if (buffer.isCursorVisible()) { - - int cursorColumn = buffer.getCursorColumn(); - final int cursorRow = buffer.getCursorRow(); - - final int columns = buffer.getColumns(); - - if (cursorColumn == columns) { - cursorColumn = columns - 1; - } - - if (cursorColumn < 0 || cursorRow < 0) { - return; - } - - int currentAttribute = buffer.getAttributes(cursorColumn, cursorRow); - boolean onWideCharacter = (currentAttribute & VDUBuffer.FULLWIDTH) != 0; - - int x = cursorColumn * bridge.charWidth; - int y = (buffer.getCursorRow() + buffer.screenBase - buffer.windowBase) * bridge.charHeight; - - // Save the current clip and translation - canvas.save(); - - canvas.translate(x, y); - canvas.clipRect(0, 0, bridge.charWidth * (onWideCharacter ? 2 : 1), bridge.charHeight); - canvas.drawPaint(cursorPaint); - - // Make sure we scale our decorations to the correct size. - canvas.concat(scaleMatrix); - - int metaState = bridge.getKeyHandler().getMetaState(); - - if ((metaState & TerminalKeyListener.META_SHIFT_ON) != 0) { - canvas.drawPath(shiftCursor, cursorStrokePaint); - } else if ((metaState & TerminalKeyListener.META_SHIFT_LOCK) != 0) { - canvas.drawPath(shiftCursor, cursorPaint); - } - - if ((metaState & TerminalKeyListener.META_ALT_ON) != 0) { - canvas.drawPath(altCursor, cursorStrokePaint); - } else if ((metaState & TerminalKeyListener.META_ALT_LOCK) != 0) { - canvas.drawPath(altCursor, cursorPaint); - } - - if ((metaState & TerminalKeyListener.META_CTRL_ON) != 0) { - canvas.drawPath(ctrlCursor, cursorStrokePaint); - } else if ((metaState & TerminalKeyListener.META_CTRL_LOCK) != 0) { - canvas.drawPath(ctrlCursor, cursorPaint); - } - - // Restore previous clip region - canvas.restore(); - } - - // draw any highlighted area - if (bridge.isSelectingForCopy()) { - SelectionArea area = bridge.getSelectionArea(); - canvas.save(Canvas.CLIP_SAVE_FLAG); - canvas.clipRect(area.getLeft() * bridge.charWidth, area.getTop() * bridge.charHeight, (area - .getRight() + 1) - * bridge.charWidth, (area.getBottom() + 1) * bridge.charHeight); - canvas.drawPaint(cursorPaint); - canvas.restore(); - } - } - } - - public void notifyUser(String message) { - if (!notifications) { - return; - } - - if (notification != null) { - // Don't keep telling the user the same thing. - if (lastNotification != null && lastNotification.equals(message)) { - return; - } - - notification.setText(message); - notification.show(); - } else { - notification = Toast.makeText(context, message, Toast.LENGTH_SHORT); - notification.show(); - } - - lastNotification = message; - } - - /** - * Ask the {@link TerminalBridge} we're connected to to resize to a specific size. - * @param width - * @param height - */ - public void forceSize(int width, int height) { - bridge.resizeComputed(width, height, getWidth(), getHeight()); - } - - /** - * Sets the ability for the TerminalView to display Toast notifications to the user. - * @param value - * whether to enable notifications or not - */ - public void setNotifications(boolean value) { - notifications = value; - } - - @Override - public boolean onCheckIsTextEditor() { - return true; - } - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - outAttrs.imeOptions |= - EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_FLAG_NO_ENTER_ACTION - | EditorInfo.IME_ACTION_NONE; - outAttrs.inputType = EditorInfo.TYPE_NULL; - return new BaseInputConnection(this, false); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/FontSizeChangedListener.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/FontSizeChangedListener.java deleted file mode 100644 index eb1c33d..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/FontSizeChangedListener.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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; - -/** - * @author Kenny Root - * - */ -public interface FontSizeChangedListener { - - /** - * @param size - * new font size - */ - void onFontSizeChanged(float size); -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/PromptHelper.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/PromptHelper.java deleted file mode 100644 index f0a37be..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/PromptHelper.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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; - promptRequested = null; - promptInstructions = null; - promptHint = null; - 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(); - - 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(); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/Relay.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/Relay.java deleted file mode 100644 index 0925321..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/Relay.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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 com.googlecode.android_scripting.Log; - -import de.mud.terminal.vt320; - -import org.apache.harmony.niochar.charset.additional.IBM437; -import org.connectbot.transport.AbsTransport; -import org.connectbot.util.EastAsianWidth; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.nio.charset.CharsetDecoder; -import java.nio.charset.CoderResult; -import java.nio.charset.CodingErrorAction; - -/** - * @author Kenny Root - */ -public class Relay implements Runnable { - - private static final int BUFFER_SIZE = 4096; - - private static boolean useJNI = true; - - private TerminalBridge bridge; - - private Charset currentCharset; - private CharsetDecoder decoder; - private boolean isLegacyEastAsian = false; - - private AbsTransport transport; - - private vt320 buffer; - - private ByteBuffer byteBuffer; - private CharBuffer charBuffer; - - private byte[] byteArray; - private char[] charArray; - - static { - useJNI = EastAsianWidth.useJNI; - } - - public Relay(TerminalBridge bridge, AbsTransport transport, vt320 buffer, String encoding) { - setCharset(encoding); - this.bridge = bridge; - this.transport = transport; - this.buffer = buffer; - } - - public void setCharset(String encoding) { - Log.d("changing charset to " + encoding); - Charset charset; - if (encoding.equals("CP437")) { - charset = new IBM437("IBM437", new String[] { "IBM437", "CP437" }); - } else { - charset = Charset.forName(encoding); - } - - if (charset == currentCharset || charset == null) { - return; - } - - CharsetDecoder newCd = charset.newDecoder(); - newCd.onUnmappableCharacter(CodingErrorAction.REPLACE); - newCd.onMalformedInput(CodingErrorAction.REPLACE); - - currentCharset = charset; - synchronized (this) { - decoder = newCd; - } - } - - public void run() { - byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); - charBuffer = CharBuffer.allocate(BUFFER_SIZE); - - /* for both JNI and non-JNI method */ - byte[] wideAttribute = new byte[BUFFER_SIZE]; - - /* non-JNI fallback method */ - float[] widths = null; - - if (!useJNI) { - widths = new float[BUFFER_SIZE]; - } - - byteArray = byteBuffer.array(); - charArray = charBuffer.array(); - - CoderResult result; - - int bytesRead = 0; - byteBuffer.limit(0); - int bytesToRead; - int offset; - int charWidth; - - try { - while (true) { - charWidth = bridge.charWidth; - bytesToRead = byteBuffer.capacity() - byteBuffer.limit(); - offset = byteBuffer.arrayOffset() + byteBuffer.limit(); - bytesRead = transport.read(byteArray, offset, bytesToRead); - - if (bytesRead > 0) { - byteBuffer.limit(byteBuffer.limit() + bytesRead); - - synchronized (this) { - result = decoder.decode(byteBuffer, charBuffer, false); - } - - if (result.isUnderflow() && byteBuffer.limit() == byteBuffer.capacity()) { - byteBuffer.compact(); - byteBuffer.limit(byteBuffer.position()); - byteBuffer.position(0); - } - - offset = charBuffer.position(); - - if (!useJNI) { - bridge.getPaint().getTextWidths(charArray, 0, offset, widths); - for (int i = 0; i < offset; i++) { - wideAttribute[i] = (byte) (((int) widths[i] != charWidth) ? 1 : 0); - } - } else { - EastAsianWidth.measure(charArray, 0, charBuffer.position(), wideAttribute, - isLegacyEastAsian); - } - buffer.putString(charArray, wideAttribute, 0, charBuffer.position()); - charBuffer.clear(); - bridge.redraw(); - } - } - } catch (IOException e) { - Log.e("Problem while handling incoming data in relay thread", e); - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalBridge.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalBridge.java deleted file mode 100644 index 9a5936b..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalBridge.java +++ /dev/null @@ -1,889 +0,0 @@ -/* - * 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 android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Typeface; -import android.graphics.Bitmap.Config; -import android.graphics.Paint.FontMetrics; -import android.text.ClipboardManager; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.View; -import android.view.ContextMenu.ContextMenuInfo; - -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.facade.ui.UiFacade; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; -import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; - -import de.mud.terminal.VDUBuffer; -import de.mud.terminal.VDUDisplay; -import de.mud.terminal.vt320; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.LinkedList; -import java.util.List; - -import org.connectbot.TerminalView; -import org.connectbot.transport.AbsTransport; -import org.connectbot.util.Colors; -import org.connectbot.util.PreferenceConstants; -import org.connectbot.util.SelectionArea; - -/** - * Provides a bridge between a MUD terminal buffer and a possible TerminalView. This separation - * allows us to keep the TerminalBridge running in a background service. A TerminalView shares down - * a bitmap that we can use for rendering when available. - * - * @author ConnectBot Dev Team - * @author raaar - * - */ -public class TerminalBridge implements VDUDisplay, OnSharedPreferenceChangeListener { - - private final static int FONT_SIZE_STEP = 2; - - private final int[] color = new int[Colors.defaults.length]; - - private final TerminalManager manager; - - private final InterpreterProcess mProcess; - - private int mDefaultFgColor; - private int mDefaultBgColor; - - private int scrollback; - - private String delKey; - private String encoding; - - private AbsTransport transport; - - private final Paint defaultPaint; - - private Relay relay; - - private Bitmap bitmap = null; - private final VDUBuffer buffer; - - private TerminalView parent = null; - private final Canvas canvas = new Canvas(); - - private boolean forcedSize = false; - private int columns; - private int rows; - - private final TerminalKeyListener keyListener; - - private boolean selectingForCopy = false; - private final SelectionArea selectionArea; - private ClipboardManager clipboard; - - public int charWidth = -1; - public int charHeight = -1; - private int charTop = -1; - - private float fontSize = -1; - - private final List<FontSizeChangedListener> fontSizeChangedListeners; - - /** - * Flag indicating if we should perform a full-screen redraw during our next rendering pass. - */ - private boolean fullRedraw = false; - - private final PromptHelper promptHelper; - - /** - * Create a new terminal bridge suitable for unit testing. - */ - public TerminalBridge() { - buffer = new vt320() { - @Override - public void write(byte[] b) { - } - - @Override - public void write(int b) { - } - - @Override - public void sendTelnetCommand(byte cmd) { - } - - @Override - public void setWindowSize(int c, int r) { - } - - @Override - public void debug(String s) { - } - }; - - manager = null; - - defaultPaint = new Paint(); - - selectionArea = new SelectionArea(); - scrollback = 1; - - fontSizeChangedListeners = new LinkedList<FontSizeChangedListener>(); - - transport = null; - - keyListener = new TerminalKeyListener(manager, this, buffer, null); - - mProcess = null; - - mDefaultFgColor = 0; - mDefaultBgColor = 0; - promptHelper = null; - - updateCharset(); - } - - /** - * Create new terminal bridge with following parameters. - */ - public TerminalBridge(final TerminalManager manager, InterpreterProcess process, AbsTransport t) - throws IOException { - this.manager = manager; - transport = t; - mProcess = process; - - String string = manager.getStringParameter(PreferenceConstants.SCROLLBACK, null); - if (string != null) { - scrollback = Integer.parseInt(string); - } else { - scrollback = PreferenceConstants.DEFAULT_SCROLLBACK; - } - - string = manager.getStringParameter(PreferenceConstants.FONTSIZE, null); - if (string != null) { - fontSize = Float.parseFloat(string); - } else { - fontSize = PreferenceConstants.DEFAULT_FONT_SIZE; - } - - mDefaultFgColor = - manager.getIntParameter(PreferenceConstants.COLOR_FG, PreferenceConstants.DEFAULT_FG_COLOR); - mDefaultBgColor = - manager.getIntParameter(PreferenceConstants.COLOR_BG, PreferenceConstants.DEFAULT_BG_COLOR); - - delKey = manager.getStringParameter(PreferenceConstants.DELKEY, PreferenceConstants.DELKEY_DEL); - - // create prompt helper to relay password and hostkey requests up to gui - promptHelper = new PromptHelper(this); - - // create our default paint - defaultPaint = new Paint(); - defaultPaint.setAntiAlias(true); - defaultPaint.setTypeface(Typeface.MONOSPACE); - defaultPaint.setFakeBoldText(true); // more readable? - - fontSizeChangedListeners = new LinkedList<FontSizeChangedListener>(); - - setFontSize(fontSize); - - // create terminal buffer and handle outgoing data - // this is probably status reply information - buffer = new vt320() { - @Override - public void debug(String s) { - Log.d(s); - } - - @Override - public void write(byte[] b) { - try { - if (b != null && transport != null) { - transport.write(b); - } - } catch (IOException e) { - Log.e("Problem writing outgoing data in vt320() thread", e); - } - } - - @Override - public void write(int b) { - try { - if (transport != null) { - transport.write(b); - } - } catch (IOException e) { - Log.e("Problem writing outgoing data in vt320() thread", e); - } - } - - // We don't use telnet sequences. - @Override - public void sendTelnetCommand(byte cmd) { - } - - // We don't want remote to resize our window. - @Override - public void setWindowSize(int c, int r) { - } - - @Override - public void beep() { - if (parent.isShown()) { - manager.playBeep(); - } - } - }; - - // Don't keep any scrollback if a session is not being opened. - - buffer.setBufferSize(scrollback); - - resetColors(); - buffer.setDisplay(this); - - selectionArea = new SelectionArea(); - - keyListener = new TerminalKeyListener(manager, this, buffer, encoding); - - updateCharset(); - - manager.registerOnSharedPreferenceChangeListener(this); - - } - - /** - * Spawn thread to open connection and start login process. - */ - protected void connect() { - transport.setBridge(this); - transport.setManager(manager); - transport.connect(); - - ((vt320) buffer).reset(); - - // previously tried vt100 and xterm for emulation modes - // "screen" works the best for color and escape codes - ((vt320) buffer).setAnswerBack("screen"); - - if (PreferenceConstants.DELKEY_BACKSPACE.equals(delKey)) { - ((vt320) buffer).setBackspace(vt320.DELETE_IS_BACKSPACE); - } else { - ((vt320) buffer).setBackspace(vt320.DELETE_IS_DEL); - } - - // create thread to relay incoming connection data to buffer - relay = new Relay(this, transport, (vt320) buffer, encoding); - Thread relayThread = new Thread(relay); - relayThread.setDaemon(true); - relayThread.setName("Relay"); - relayThread.start(); - - // force font-size to make sure we resizePTY as needed - setFontSize(fontSize); - - } - - private void updateCharset() { - encoding = - manager.getStringParameter(PreferenceConstants.ENCODING, Charset.defaultCharset().name()); - if (relay != null) { - relay.setCharset(encoding); - } - keyListener.setCharset(encoding); - } - - /** - * Inject a specific string into this terminal. Used for post-login strings and pasting clipboard. - */ - public void injectString(final String string) { - if (string == null || string.length() == 0) { - return; - } - - Thread injectStringThread = new Thread(new Runnable() { - public void run() { - try { - transport.write(string.getBytes(encoding)); - } catch (Exception e) { - Log.e("Couldn't inject string to remote host: ", e); - } - } - }); - injectStringThread.setName("InjectString"); - injectStringThread.start(); - } - - /** - * @return whether a session is open or not - */ - public boolean isSessionOpen() { - if (transport != null) { - return transport.isSessionOpen(); - } - return false; - } - - /** - * Force disconnection of this terminal bridge. - */ - public void dispatchDisconnect(boolean immediate) { - - // Cancel any pending prompts. - promptHelper.cancelPrompt(); - - if (immediate) { - manager.closeConnection(TerminalBridge.this, true); - } else { - Thread disconnectPromptThread = new Thread(new Runnable() { - public void run() { - String prompt = null; - if (transport != null && transport.isConnected()) { - prompt = manager.getResources().getString(R.string.prompt_confirm_exit); - } else { - prompt = manager.getResources().getString(R.string.prompt_process_exited); - } - Boolean result = promptHelper.requestBooleanPrompt(null, prompt); - - if (transport != null && transport.isConnected()) { - manager.closeConnection(TerminalBridge.this, result != null && result.booleanValue()); - } else if (result != null && result.booleanValue()) { - manager.closeConnection(TerminalBridge.this, false); - } - } - }); - disconnectPromptThread.setName("DisconnectPrompt"); - disconnectPromptThread.setDaemon(true); - disconnectPromptThread.start(); - } - } - - public void setSelectingForCopy(boolean selectingForCopy) { - this.selectingForCopy = selectingForCopy; - } - - public boolean isSelectingForCopy() { - return selectingForCopy; - } - - public SelectionArea getSelectionArea() { - return selectionArea; - } - - public synchronized void tryKeyVibrate() { - manager.tryKeyVibrate(); - } - - /** - * Request a different font size. Will make call to parentChanged() to make sure we resize PTY if - * needed. - */ - /* package */final void setFontSize(float size) { - if (size <= 0.0) { - return; - } - - defaultPaint.setTextSize(size); - fontSize = size; - - // read new metrics to get exact pixel dimensions - FontMetrics fm = defaultPaint.getFontMetrics(); - charTop = (int) Math.ceil(fm.top); - - float[] widths = new float[1]; - defaultPaint.getTextWidths("X", widths); - charWidth = (int) Math.ceil(widths[0]); - charHeight = (int) Math.ceil(fm.descent - fm.top); - - // refresh any bitmap with new font size - if (parent != null) { - parentChanged(parent); - } - - for (FontSizeChangedListener ofscl : fontSizeChangedListeners) { - ofscl.onFontSizeChanged(size); - } - forcedSize = false; - } - - /** - * Add an {@link FontSizeChangedListener} to the list of listeners for this bridge. - * - * @param listener - * listener to add - */ - public void addFontSizeChangedListener(FontSizeChangedListener listener) { - fontSizeChangedListeners.add(listener); - } - - /** - * Remove an {@link FontSizeChangedListener} from the list of listeners for this bridge. - * - * @param listener - */ - public void removeFontSizeChangedListener(FontSizeChangedListener listener) { - fontSizeChangedListeners.remove(listener); - } - - /** - * Something changed in our parent {@link TerminalView}, maybe it's a new parent, or maybe it's an - * updated font size. We should recalculate terminal size information and request a PTY resize. - */ - public final synchronized void parentChanged(TerminalView parent) { - if (manager != null && !manager.isResizeAllowed()) { - Log.d("Resize is not allowed now"); - return; - } - - this.parent = parent; - final int width = parent.getWidth(); - final int height = parent.getHeight(); - - // Something has gone wrong with our layout; we're 0 width or height! - if (width <= 0 || height <= 0) { - return; - } - - clipboard = (ClipboardManager) parent.getContext().getSystemService(Context.CLIPBOARD_SERVICE); - keyListener.setClipboardManager(clipboard); - - if (!forcedSize) { - // recalculate buffer size - int newColumns, newRows; - - newColumns = width / charWidth; - newRows = height / charHeight; - - // If nothing has changed in the terminal dimensions and not an intial - // draw then don't blow away scroll regions and such. - if (newColumns == columns && newRows == rows) { - return; - } - - columns = newColumns; - rows = newRows; - } - - // reallocate new bitmap if needed - boolean newBitmap = (bitmap == null); - if (bitmap != null) { - newBitmap = (bitmap.getWidth() != width || bitmap.getHeight() != height); - } - - if (newBitmap) { - discardBitmap(); - bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); - canvas.setBitmap(bitmap); - } - - // clear out any old buffer information - defaultPaint.setColor(Color.BLACK); - canvas.drawPaint(defaultPaint); - - // Stroke the border of the terminal if the size is being forced; - if (forcedSize) { - int borderX = (columns * charWidth) + 1; - int borderY = (rows * charHeight) + 1; - - defaultPaint.setColor(Color.GRAY); - defaultPaint.setStrokeWidth(0.0f); - if (width >= borderX) { - canvas.drawLine(borderX, 0, borderX, borderY + 1, defaultPaint); - } - if (height >= borderY) { - canvas.drawLine(0, borderY, borderX + 1, borderY, defaultPaint); - } - } - - try { - // request a terminal pty resize - synchronized (buffer) { - buffer.setScreenSize(columns, rows, true); - } - - if (transport != null) { - transport.setDimensions(columns, rows, width, height); - } - } catch (Exception e) { - Log.e("Problem while trying to resize screen or PTY", e); - } - - // force full redraw with new buffer size - fullRedraw = true; - redraw(); - - parent.notifyUser(String.format("%d x %d", columns, rows)); - - Log.i(String.format("parentChanged() now width=%d, height=%d", columns, rows)); - } - - /** - * Somehow our parent {@link TerminalView} was destroyed. Now we don't need to redraw anywhere, - * and we can recycle our internal bitmap. - */ - public synchronized void parentDestroyed() { - parent = null; - discardBitmap(); - } - - private void discardBitmap() { - if (bitmap != null) { - bitmap.recycle(); - } - bitmap = null; - } - - public void onDraw() { - int fg, bg; - synchronized (buffer) { - boolean entireDirty = buffer.update[0] || fullRedraw; - boolean isWideCharacter = false; - - // walk through all lines in the buffer - for (int l = 0; l < buffer.height; l++) { - - // check if this line is dirty and needs to be repainted - // also check for entire-buffer dirty flags - if (!entireDirty && !buffer.update[l + 1]) { - continue; - } - - // reset dirty flag for this line - buffer.update[l + 1] = false; - - // walk through all characters in this line - for (int c = 0; c < buffer.width; c++) { - int addr = 0; - int currAttr = buffer.charAttributes[buffer.windowBase + l][c]; - // check if foreground color attribute is set - if ((currAttr & VDUBuffer.COLOR_FG) != 0) { - int fgcolor = ((currAttr & VDUBuffer.COLOR_FG) >> VDUBuffer.COLOR_FG_SHIFT) - 1; - if (fgcolor < 8 && (currAttr & VDUBuffer.BOLD) != 0) { - fg = color[fgcolor + 8]; - } else { - fg = color[fgcolor]; - } - } else { - fg = mDefaultFgColor; - } - - // check if background color attribute is set - if ((currAttr & VDUBuffer.COLOR_BG) != 0) { - bg = color[((currAttr & VDUBuffer.COLOR_BG) >> VDUBuffer.COLOR_BG_SHIFT) - 1]; - } else { - bg = mDefaultBgColor; - } - - // support character inversion by swapping background and foreground color - if ((currAttr & VDUBuffer.INVERT) != 0) { - int swapc = bg; - bg = fg; - fg = swapc; - } - - // set underlined attributes if requested - defaultPaint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0); - - isWideCharacter = (currAttr & VDUBuffer.FULLWIDTH) != 0; - - if (isWideCharacter) { - addr++; - } else { - // determine the amount of continuous characters with the same settings and print them - // all at once - while (c + addr < buffer.width - && buffer.charAttributes[buffer.windowBase + l][c + addr] == currAttr) { - addr++; - } - } - - // Save the current clip region - canvas.save(Canvas.CLIP_SAVE_FLAG); - - // clear this dirty area with background color - defaultPaint.setColor(bg); - if (isWideCharacter) { - canvas.clipRect(c * charWidth, l * charHeight, (c + 2) * charWidth, (l + 1) - * charHeight); - } else { - canvas.clipRect(c * charWidth, l * charHeight, (c + addr) * charWidth, (l + 1) - * charHeight); - } - canvas.drawPaint(defaultPaint); - - // write the text string starting at 'c' for 'addr' number of characters - defaultPaint.setColor(fg); - if ((currAttr & VDUBuffer.INVISIBLE) == 0) { - canvas.drawText(buffer.charArray[buffer.windowBase + l], c, addr, c * charWidth, - (l * charHeight) - charTop, defaultPaint); - } - - // Restore the previous clip region - canvas.restore(); - - // advance to the next text block with different characteristics - c += addr - 1; - if (isWideCharacter) { - c++; - } - } - } - - // reset entire-buffer flags - buffer.update[0] = false; - } - fullRedraw = false; - } - - public void redraw() { - if (parent != null) { - parent.postInvalidate(); - } - } - - // We don't have a scroll bar. - public void updateScrollBar() { - } - - /** - * Resize terminal to fit [rows]x[cols] in screen of size [width]x[height] - * - * @param rows - * @param cols - * @param width - * @param height - */ - public synchronized void resizeComputed(int cols, int rows, int width, int height) { - float size = 8.0f; - float step = 8.0f; - float limit = 0.125f; - - int direction; - - while ((direction = fontSizeCompare(size, cols, rows, width, height)) < 0) { - size += step; - } - - if (direction == 0) { - Log.d(String.format("Fontsize: found match at %f", size)); - return; - } - - step /= 2.0f; - size -= step; - - while ((direction = fontSizeCompare(size, cols, rows, width, height)) != 0 && step >= limit) { - step /= 2.0f; - if (direction > 0) { - size -= step; - } else { - size += step; - } - } - - if (direction > 0) { - size -= step; - } - - columns = cols; - this.rows = rows; - setFontSize(size); - forcedSize = true; - } - - private int fontSizeCompare(float size, int cols, int rows, int width, int height) { - // read new metrics to get exact pixel dimensions - defaultPaint.setTextSize(size); - FontMetrics fm = defaultPaint.getFontMetrics(); - - float[] widths = new float[1]; - defaultPaint.getTextWidths("X", widths); - int termWidth = (int) widths[0] * cols; - int termHeight = (int) Math.ceil(fm.descent - fm.top) * rows; - - Log.d(String.format("Fontsize: font size %f resulted in %d x %d", size, termWidth, termHeight)); - - // Check to see if it fits in resolution specified. - if (termWidth > width || termHeight > height) { - return 1; - } - - if (termWidth == width || termHeight == height) { - return 0; - } - - return -1; - } - - /* - * (non-Javadoc) - * - * @see de.mud.terminal.VDUDisplay#setVDUBuffer(de.mud.terminal.VDUBuffer) - */ - @Override - public void setVDUBuffer(VDUBuffer buffer) { - } - - /* - * (non-Javadoc) - * - * @see de.mud.terminal.VDUDisplay#setColor(byte, byte, byte, byte) - */ - public void setColor(int index, int red, int green, int blue) { - // Don't allow the system colors to be overwritten for now. May violate specs. - if (index < color.length && index >= 16) { - color[index] = 0xff000000 | red << 16 | green << 8 | blue; - } - } - - public final void resetColors() { - System.arraycopy(Colors.defaults, 0, color, 0, Colors.defaults.length); - } - - public TerminalKeyListener getKeyHandler() { - return keyListener; - } - - public void resetScrollPosition() { - // if we're in scrollback, scroll to bottom of window on input - if (buffer.windowBase != buffer.screenBase) { - buffer.setWindowBase(buffer.screenBase); - } - } - - public void increaseFontSize() { - setFontSize(fontSize + FONT_SIZE_STEP); - } - - public void decreaseFontSize() { - setFontSize(fontSize - FONT_SIZE_STEP); - } - - public int getId() { - return mProcess.getPort(); - } - - public String getName() { - return mProcess.getName(); - } - - public InterpreterProcess getProcess() { - return mProcess; - } - - public int getForegroundColor() { - return mDefaultFgColor; - } - - public int getBackgroundColor() { - return mDefaultBgColor; - } - - public VDUBuffer getVDUBuffer() { - return buffer; - } - - public PromptHelper getPromptHelper() { - return promptHelper; - } - - public Bitmap getBitmap() { - return bitmap; - } - - public AbsTransport getTransport() { - return transport; - } - - public Paint getPaint() { - return defaultPaint; - } - - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - if (mProcess.isAlive()) { - RpcReceiverManagerFactory rpcReceiverManagerFactory = mProcess.getRpcReceiverManagerFactory(); - for (RpcReceiverManager manager : rpcReceiverManagerFactory.getRpcReceiverManagers().values()) { - UiFacade facade = manager.getReceiver(UiFacade.class); - facade.onCreateContextMenu(menu, v, menuInfo); - } - } - } - - public boolean onPrepareOptionsMenu(Menu menu) { - boolean returnValue = false; - if (mProcess.isAlive()) { - RpcReceiverManagerFactory rpcReceiverManagerFactory = mProcess.getRpcReceiverManagerFactory(); - for (RpcReceiverManager manager : rpcReceiverManagerFactory.getRpcReceiverManagers().values()) { - UiFacade facade = manager.getReceiver(UiFacade.class); - returnValue = returnValue || facade.onPrepareOptionsMenu(menu); - } - return returnValue; - } - return false; - } - - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PreferenceConstants.ENCODING.equals(key)) { - updateCharset(); - } else if (PreferenceConstants.FONTSIZE.equals(key)) { - String string = manager.getStringParameter(PreferenceConstants.FONTSIZE, null); - if (string != null) { - fontSize = Float.parseFloat(string); - } else { - fontSize = PreferenceConstants.DEFAULT_FONT_SIZE; - } - setFontSize(fontSize); - fullRedraw = true; - } else if (PreferenceConstants.SCROLLBACK.equals(key)) { - String string = manager.getStringParameter(PreferenceConstants.SCROLLBACK, null); - if (string != null) { - scrollback = Integer.parseInt(string); - } else { - scrollback = PreferenceConstants.DEFAULT_SCROLLBACK; - } - buffer.setBufferSize(scrollback); - } else if (PreferenceConstants.COLOR_FG.equals(key)) { - mDefaultFgColor = - manager.getIntParameter(PreferenceConstants.COLOR_FG, - PreferenceConstants.DEFAULT_FG_COLOR); - fullRedraw = true; - } else if (PreferenceConstants.COLOR_BG.equals(key)) { - mDefaultBgColor = - manager.getIntParameter(PreferenceConstants.COLOR_BG, - PreferenceConstants.DEFAULT_BG_COLOR); - fullRedraw = true; - } - if (PreferenceConstants.DELKEY.equals(key)) { - delKey = - manager.getStringParameter(PreferenceConstants.DELKEY, PreferenceConstants.DELKEY_DEL); - if (PreferenceConstants.DELKEY_BACKSPACE.equals(delKey)) { - ((vt320) buffer).setBackspace(vt320.DELETE_IS_BACKSPACE); - } else { - ((vt320) buffer).setBackspace(vt320.DELETE_IS_DEL); - } - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalKeyListener.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalKeyListener.java deleted file mode 100644 index 9fce1e8..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalKeyListener.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * ConnectBot: simple, powerful, open-source SSH client for Android - * Copyright 2010 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 android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Configuration; -import android.text.ClipboardManager; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.View; -import android.view.View.OnKeyListener; - -import com.googlecode.android_scripting.Log; - -import de.mud.terminal.VDUBuffer; -import de.mud.terminal.vt320; - -import java.io.IOException; - -import org.connectbot.TerminalView; -import org.connectbot.transport.AbsTransport; -import org.connectbot.util.PreferenceConstants; -import org.connectbot.util.SelectionArea; - -/** - * @author kenny - * @author modified by raaar - */ -public class TerminalKeyListener implements OnKeyListener, OnSharedPreferenceChangeListener { - - public final static int META_CTRL_ON = 0x01; - public final static int META_CTRL_LOCK = 0x02; - public final static int META_ALT_ON = 0x04; - public final static int META_ALT_LOCK = 0x08; - public final static int META_SHIFT_ON = 0x10; - public final static int META_SHIFT_LOCK = 0x20; - public final static int META_SLASH = 0x40; - public final static int META_TAB = 0x80; - - // The bit mask of momentary and lock states for each - public final static int META_CTRL_MASK = META_CTRL_ON | META_CTRL_LOCK; - public final static int META_ALT_MASK = META_ALT_ON | META_ALT_LOCK; - public final static int META_SHIFT_MASK = META_SHIFT_ON | META_SHIFT_LOCK; - - // All the transient key codes - public final static int META_TRANSIENT = META_CTRL_ON | META_ALT_ON | META_SHIFT_ON; - - public final static int KEYBOARD_META_CTRL_ON = 0x1000; // Ctrl key mask for API 11+ - private final TerminalManager manager; - private final TerminalBridge bridge; - private final VDUBuffer buffer; - - protected KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD); - - private String keymode = null; - private boolean hardKeyboard = false; - - private int metaState = 0; - - private ClipboardManager clipboard = null; - private boolean selectingForCopy = false; - private final SelectionArea selectionArea; - - private String encoding; - - public TerminalKeyListener(TerminalManager manager, TerminalBridge bridge, VDUBuffer buffer, - String encoding) { - this.manager = manager; - this.bridge = bridge; - this.buffer = buffer; - this.encoding = encoding; - - selectionArea = new SelectionArea(); - - manager.registerOnSharedPreferenceChangeListener(this); - - hardKeyboard = - (manager.getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY); - - updateKeymode(); - } - - /** - * Handle onKey() events coming down from a {@link TerminalView} above us. Modify the keys to make - * more sense to a host then pass it to the transport. - */ - public boolean onKey(View v, int keyCode, KeyEvent event) { - try { - final boolean hardKeyboardHidden = manager.isHardKeyboardHidden(); - - AbsTransport transport = bridge.getTransport(); - - // Ignore all key-up events except for the special keys - if (event.getAction() == KeyEvent.ACTION_UP) { - // There's nothing here for virtual keyboard users. - if (!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) { - return false; - } - - // skip keys if we aren't connected yet or have been disconnected - if (transport == null || !transport.isSessionOpen()) { - return false; - } - - if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { - if (keyCode == KeyEvent.KEYCODE_ALT_RIGHT && (metaState & META_SLASH) != 0) { - metaState &= ~(META_SLASH | META_TRANSIENT); - transport.write('/'); - return true; - } else if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT && (metaState & META_TAB) != 0) { - metaState &= ~(META_TAB | META_TRANSIENT); - transport.write(0x09); - return true; - } - } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { - if (keyCode == KeyEvent.KEYCODE_ALT_LEFT && (metaState & META_SLASH) != 0) { - metaState &= ~(META_SLASH | META_TRANSIENT); - transport.write('/'); - return true; - } else if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT && (metaState & META_TAB) != 0) { - metaState &= ~(META_TAB | META_TRANSIENT); - transport.write(0x09); - return true; - } - } - - return false; - } - - if (keyCode == KeyEvent.KEYCODE_BACK && transport != null) { - bridge.dispatchDisconnect(!transport.isSessionOpen()); - return true; - } - - // check for terminal resizing keys - if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { - bridge.increaseFontSize(); - return true; - } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { - bridge.decreaseFontSize(); - return true; - } - - // skip keys if we aren't connected yet or have been disconnected - if (transport == null || !transport.isSessionOpen()) { - return false; - } - - bridge.resetScrollPosition(); - - boolean printing = (keymap.isPrintingKey(keyCode) || keyCode == KeyEvent.KEYCODE_SPACE); - - // otherwise pass through to existing session - // print normal keys - if (printing) { - int curMetaState = event.getMetaState(); - - metaState &= ~(META_SLASH | META_TAB); - - if ((metaState & META_SHIFT_MASK) != 0) { - curMetaState |= KeyEvent.META_SHIFT_ON; - metaState &= ~META_SHIFT_ON; - bridge.redraw(); - } - - if ((metaState & META_ALT_MASK) != 0) { - curMetaState |= KeyEvent.META_ALT_ON; - metaState &= ~META_ALT_ON; - bridge.redraw(); - } - - int key = keymap.get(keyCode, curMetaState); - if ((curMetaState & KEYBOARD_META_CTRL_ON) != 0) { - metaState |= META_CTRL_ON; - key = keymap.get(keyCode, 0); - } - - if ((metaState & META_CTRL_MASK) != 0) { - metaState &= ~META_CTRL_ON; - bridge.redraw(); - - if ((!hardKeyboard || (hardKeyboard && hardKeyboardHidden)) && sendFunctionKey(keyCode)) { - return true; - } - - // Support CTRL-a through CTRL-z - if (key >= 0x61 && key <= 0x7A) { - key -= 0x60; - } else if (key >= 0x41 && key <= 0x5F) { - key -= 0x40; - } else if (key == 0x20) { - key = 0x00; - } else if (key == 0x3F) { - key = 0x7F; - } - } - - // handle pressing f-keys - // Doesn't work properly with asus keyboards... may never have worked. RM 09-Apr-2012 - /* - * if ((hardKeyboard && !hardKeyboardHidden) && (curMetaState & KeyEvent.META_SHIFT_ON) != 0 - * && sendFunctionKey(keyCode)) { return true; } - */ - - if (key < 0x80) { - transport.write(key); - } else { - // TODO write encoding routine that doesn't allocate each time - transport.write(new String(Character.toChars(key)).getBytes(encoding)); - } - - return true; - } - - if (keyCode == KeyEvent.KEYCODE_UNKNOWN && event.getAction() == KeyEvent.ACTION_MULTIPLE) { - byte[] input = event.getCharacters().getBytes(encoding); - transport.write(input); - return true; - } - - // try handling keymode shortcuts - if (hardKeyboard && !hardKeyboardHidden && event.getRepeatCount() == 0) { - if (PreferenceConstants.KEYMODE_RIGHT.equals(keymode)) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_RIGHT: - metaState |= META_SLASH; - return true; - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaState |= META_TAB; - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - metaPress(META_SHIFT_ON); - return true; - case KeyEvent.KEYCODE_ALT_LEFT: - metaPress(META_ALT_ON); - return true; - } - } else if (PreferenceConstants.KEYMODE_LEFT.equals(keymode)) { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - metaState |= META_SLASH; - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - metaState |= META_TAB; - return true; - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaPress(META_SHIFT_ON); - return true; - case KeyEvent.KEYCODE_ALT_RIGHT: - metaPress(META_ALT_ON); - return true; - } - } else { - switch (keyCode) { - case KeyEvent.KEYCODE_ALT_LEFT: - case KeyEvent.KEYCODE_ALT_RIGHT: - metaPress(META_ALT_ON); - return true; - case KeyEvent.KEYCODE_SHIFT_LEFT: - case KeyEvent.KEYCODE_SHIFT_RIGHT: - metaPress(META_SHIFT_ON); - return true; - } - } - } - - // look for special chars - switch (keyCode) { - case KeyEvent.KEYCODE_CAMERA: - - // check to see which shortcut the camera button triggers - String camera = - manager.getStringParameter(PreferenceConstants.CAMERA, - PreferenceConstants.CAMERA_CTRLA_SPACE); - if (PreferenceConstants.CAMERA_CTRLA_SPACE.equals(camera)) { - transport.write(0x01); - transport.write(' '); - } else if (PreferenceConstants.CAMERA_CTRLA.equals(camera)) { - transport.write(0x01); - } else if (PreferenceConstants.CAMERA_ESC.equals(camera)) { - ((vt320) buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); - } else if (PreferenceConstants.CAMERA_ESC_A.equals(camera)) { - ((vt320) buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); - transport.write('a'); - } - - break; - - case KeyEvent.KEYCODE_DEL: - ((vt320) buffer).keyPressed(vt320.KEY_BACK_SPACE, ' ', getStateForBuffer()); - metaState &= ~META_TRANSIENT; - return true; - case KeyEvent.KEYCODE_ENTER: - ((vt320) buffer).keyTyped(vt320.KEY_ENTER, ' ', 0); - metaState &= ~META_TRANSIENT; - return true; - - case KeyEvent.KEYCODE_DPAD_LEFT: - if (selectingForCopy) { - selectionArea.decrementColumn(); - bridge.redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_LEFT, ' ', getStateForBuffer()); - metaState &= ~META_TRANSIENT; - bridge.tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_UP: - if (selectingForCopy) { - selectionArea.decrementRow(); - bridge.redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_UP, ' ', getStateForBuffer()); - metaState &= ~META_TRANSIENT; - bridge.tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_DOWN: - if (selectingForCopy) { - selectionArea.incrementRow(); - bridge.redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_DOWN, ' ', getStateForBuffer()); - metaState &= ~META_TRANSIENT; - bridge.tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_RIGHT: - if (selectingForCopy) { - selectionArea.incrementColumn(); - bridge.redraw(); - } else { - ((vt320) buffer).keyPressed(vt320.KEY_RIGHT, ' ', getStateForBuffer()); - metaState &= ~META_TRANSIENT; - bridge.tryKeyVibrate(); - } - return true; - - case KeyEvent.KEYCODE_DPAD_CENTER: - if (selectingForCopy) { - if (selectionArea.isSelectingOrigin()) { - selectionArea.finishSelectingOrigin(); - } else { - if (clipboard != null) { - // copy selected area to clipboard - String copiedText = selectionArea.copyFrom(buffer); - - clipboard.setText(copiedText); - // XXX STOPSHIP - // manager.notifyUser(manager.getString( - // R.string.console_copy_done, - // copiedText.length())); - - selectingForCopy = false; - selectionArea.reset(); - } - } - } else { - if ((metaState & META_CTRL_ON) != 0) { - ((vt320) buffer).keyTyped(vt320.KEY_ESCAPE, ' ', 0); - metaState &= ~META_CTRL_ON; - } else { - metaState |= META_CTRL_ON; - } - } - - bridge.redraw(); - - return true; - } - - } catch (IOException e) { - Log.e("Problem while trying to handle an onKey() event", e); - try { - bridge.getTransport().flush(); - } catch (IOException ioe) { - Log.d("Our transport was closed, dispatching disconnect event"); - bridge.dispatchDisconnect(false); - } - } catch (NullPointerException npe) { - Log.d("Input before connection established ignored."); - return true; - } - - return false; - } - - /** - * @param keyCode - * @return successful - */ - private boolean sendFunctionKey(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_1: - ((vt320) buffer).keyPressed(vt320.KEY_F1, ' ', 0); - return true; - case KeyEvent.KEYCODE_2: - ((vt320) buffer).keyPressed(vt320.KEY_F2, ' ', 0); - return true; - case KeyEvent.KEYCODE_3: - ((vt320) buffer).keyPressed(vt320.KEY_F3, ' ', 0); - return true; - case KeyEvent.KEYCODE_4: - ((vt320) buffer).keyPressed(vt320.KEY_F4, ' ', 0); - return true; - case KeyEvent.KEYCODE_5: - ((vt320) buffer).keyPressed(vt320.KEY_F5, ' ', 0); - return true; - case KeyEvent.KEYCODE_6: - ((vt320) buffer).keyPressed(vt320.KEY_F6, ' ', 0); - return true; - case KeyEvent.KEYCODE_7: - ((vt320) buffer).keyPressed(vt320.KEY_F7, ' ', 0); - return true; - case KeyEvent.KEYCODE_8: - ((vt320) buffer).keyPressed(vt320.KEY_F8, ' ', 0); - return true; - case KeyEvent.KEYCODE_9: - ((vt320) buffer).keyPressed(vt320.KEY_F9, ' ', 0); - return true; - case KeyEvent.KEYCODE_0: - ((vt320) buffer).keyPressed(vt320.KEY_F10, ' ', 0); - return true; - default: - return false; - } - } - - /** - * Handle meta key presses where the key can be locked on. - * <p> - * 1st press: next key to have meta state<br /> - * 2nd press: meta state is locked on<br /> - * 3rd press: disable meta state - * - * @param code - */ - private void metaPress(int code) { - if ((metaState & (code << 1)) != 0) { - metaState &= ~(code << 1); - } else if ((metaState & code) != 0) { - metaState &= ~code; - metaState |= code << 1; - } else { - metaState |= code; - } - bridge.redraw(); - } - - public void setTerminalKeyMode(String keymode) { - this.keymode = keymode; - } - - private int getStateForBuffer() { - int bufferState = 0; - - if ((metaState & META_CTRL_MASK) != 0) { - bufferState |= vt320.KEY_CONTROL; - } - if ((metaState & META_SHIFT_MASK) != 0) { - bufferState |= vt320.KEY_SHIFT; - } - if ((metaState & META_ALT_MASK) != 0) { - bufferState |= vt320.KEY_ALT; - } - - return bufferState; - } - - public int getMetaState() { - return metaState; - } - - public void setClipboardManager(ClipboardManager clipboard) { - this.clipboard = clipboard; - } - - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PreferenceConstants.KEYMODE.equals(key)) { - updateKeymode(); - } - } - - private void updateKeymode() { - keymode = - manager.getStringParameter(PreferenceConstants.KEYMODE, PreferenceConstants.KEYMODE_RIGHT); - } - - public void setCharset(String encoding) { - this.encoding = encoding; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalManager.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalManager.java deleted file mode 100644 index bc83a92..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/service/TerminalManager.java +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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 android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.AssetFileDescriptor; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.media.AudioManager; -import android.media.MediaPlayer; -import android.media.MediaPlayer.OnCompletionListener; -import android.os.Handler; -import android.os.Message; -import android.os.Vibrator; -import android.preference.PreferenceManager; - -import com.googlecode.android_scripting.Constants; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.R; -import com.googlecode.android_scripting.activity.ScriptingLayerService; -import com.googlecode.android_scripting.exception.Sl4aException; -import com.googlecode.android_scripting.interpreter.InterpreterProcess; - -import org.connectbot.transport.ProcessTransport; -import org.connectbot.util.PreferenceConstants; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * Manager for SSH connections that runs as a background service. This service holds a list of - * currently connected SSH bridges that are ready for connection up to a GUI if needed. - * - * @author jsharkey - * @author modified by raaar - */ -public class TerminalManager implements OnSharedPreferenceChangeListener { - - private static final long VIBRATE_DURATION = 30; - - private final List<TerminalBridge> bridges = new CopyOnWriteArrayList<TerminalBridge>(); - - private final Map<Integer, WeakReference<TerminalBridge>> mHostBridgeMap = - new ConcurrentHashMap<Integer, WeakReference<TerminalBridge>>(); - - private Handler mDisconnectHandler = null; - - private final Resources mResources; - - private final SharedPreferences mPreferences; - - private boolean hardKeyboardHidden; - - private Vibrator vibrator; - private boolean wantKeyVibration; - private boolean wantBellVibration; - private boolean wantAudible; - private boolean resizeAllowed = false; - private MediaPlayer mediaPlayer; - - private final ScriptingLayerService mService; - - public TerminalManager(ScriptingLayerService service) { - mService = service; - mPreferences = PreferenceManager.getDefaultSharedPreferences(mService); - registerOnSharedPreferenceChangeListener(this); - mResources = mService.getResources(); - hardKeyboardHidden = - (mResources.getConfiguration().hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES); - vibrator = (Vibrator) mService.getSystemService(Context.VIBRATOR_SERVICE); - wantKeyVibration = mPreferences.getBoolean(PreferenceConstants.BUMPY_ARROWS, true); - wantBellVibration = mPreferences.getBoolean(PreferenceConstants.BELL_VIBRATE, true); - wantAudible = mPreferences.getBoolean(PreferenceConstants.BELL, true); - if (wantAudible) { - enableMediaPlayer(); - } - } - - /** - * Disconnect all currently connected bridges. - */ - private void disconnectAll() { - TerminalBridge[] bridgesArray = null; - if (bridges.size() > 0) { - bridgesArray = bridges.toArray(new TerminalBridge[bridges.size()]); - } - if (bridgesArray != null) { - // disconnect and dispose of any existing bridges - for (TerminalBridge bridge : bridgesArray) { - bridge.dispatchDisconnect(true); - } - } - } - - /** - * Open a new session using the given parameters. - * - * @throws InterruptedException - * @throws Sl4aException - */ - public TerminalBridge openConnection(int id) throws IllegalArgumentException, IOException, - InterruptedException, Sl4aException { - // throw exception if terminal already open - if (getConnectedBridge(id) != null) { - throw new IllegalArgumentException("Connection already open"); - } - - InterpreterProcess process = mService.getProcess(id); - - TerminalBridge bridge = new TerminalBridge(this, process, new ProcessTransport(process)); - bridge.connect(); - - WeakReference<TerminalBridge> wr = new WeakReference<TerminalBridge>(bridge); - bridges.add(bridge); - mHostBridgeMap.put(id, wr); - - return bridge; - } - - /** - * Find a connected {@link TerminalBridge} with the given HostBean. - * - * @param id - * the HostBean to search for - * @return TerminalBridge that uses the HostBean - */ - public TerminalBridge getConnectedBridge(int id) { - WeakReference<TerminalBridge> wr = mHostBridgeMap.get(id); - if (wr != null) { - return wr.get(); - } else { - return null; - } - } - - /** - * Called by child bridge when somehow it's been disconnected. - */ - public void closeConnection(TerminalBridge bridge, boolean killProcess) { - if (killProcess) { - bridges.remove(bridge); - mHostBridgeMap.remove(bridge.getId()); - if (mService.getProcess(bridge.getId()).isAlive()) { - Intent intent = new Intent(mService, mService.getClass()); - intent.setAction(Constants.ACTION_KILL_PROCESS); - intent.putExtra(Constants.EXTRA_PROXY_PORT, bridge.getId()); - mService.startService(intent); - } - } - if (mDisconnectHandler != null) { - Message.obtain(mDisconnectHandler, -1, bridge).sendToTarget(); - } - } - - /** - * Allow {@link TerminalBridge} to resize when the parent has changed. - * - * @param resizeAllowed - */ - public void setResizeAllowed(boolean resizeAllowed) { - this.resizeAllowed = resizeAllowed; - } - - public boolean isResizeAllowed() { - return resizeAllowed; - } - - public void stop() { - resizeAllowed = false; - disconnectAll(); - disableMediaPlayer(); - } - - public int getIntParameter(String key, int defValue) { - return mPreferences.getInt(key, defValue); - } - - public String getStringParameter(String key, String defValue) { - return mPreferences.getString(key, defValue); - } - - public void tryKeyVibrate() { - if (wantKeyVibration) { - vibrate(); - } - } - - private void vibrate() { - if (vibrator != null) { - vibrator.vibrate(VIBRATE_DURATION); - } - } - - private void enableMediaPlayer() { - mediaPlayer = new MediaPlayer(); - - float volume = - mPreferences.getFloat(PreferenceConstants.BELL_VOLUME, - PreferenceConstants.DEFAULT_BELL_VOLUME); - - mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); - mediaPlayer.setOnCompletionListener(new BeepListener()); - - AssetFileDescriptor file = mResources.openRawResourceFd(R.raw.bell); - try { - mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength()); - file.close(); - mediaPlayer.setVolume(volume, volume); - mediaPlayer.prepare(); - } catch (IOException e) { - Log.e("Error setting up bell media player", e); - } - } - - private void disableMediaPlayer() { - if (mediaPlayer != null) { - mediaPlayer.release(); - mediaPlayer = null; - } - } - - public void playBeep() { - if (mediaPlayer != null) { - mediaPlayer.start(); - } - if (wantBellVibration) { - vibrate(); - } - } - - private static class BeepListener implements OnCompletionListener { - public void onCompletion(MediaPlayer mp) { - mp.seekTo(0); - } - } - - public boolean isHardKeyboardHidden() { - return hardKeyboardHidden; - } - - public void setHardKeyboardHidden(boolean b) { - hardKeyboardHidden = b; - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PreferenceConstants.BELL.equals(key)) { - wantAudible = sharedPreferences.getBoolean(PreferenceConstants.BELL, true); - if (wantAudible && mediaPlayer == null) { - enableMediaPlayer(); - } else if (!wantAudible && mediaPlayer != null) { - disableMediaPlayer(); - } - } else if (PreferenceConstants.BELL_VOLUME.equals(key)) { - if (mediaPlayer != null) { - float volume = - sharedPreferences.getFloat(PreferenceConstants.BELL_VOLUME, - PreferenceConstants.DEFAULT_BELL_VOLUME); - mediaPlayer.setVolume(volume, volume); - } - } else if (PreferenceConstants.BELL_VIBRATE.equals(key)) { - wantBellVibration = sharedPreferences.getBoolean(PreferenceConstants.BELL_VIBRATE, true); - } else if (PreferenceConstants.BUMPY_ARROWS.equals(key)) { - wantKeyVibration = sharedPreferences.getBoolean(PreferenceConstants.BUMPY_ARROWS, true); - } - } - - public void setDisconnectHandler(Handler disconnectHandler) { - mDisconnectHandler = disconnectHandler; - } - - public List<TerminalBridge> getBridgeList() { - return bridges; - } - - public Resources getResources() { - return mResources; - } - - public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) { - mPreferences.registerOnSharedPreferenceChangeListener(listener); - } - -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/AbsTransport.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/AbsTransport.java deleted file mode 100644 index 3d8c943..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/AbsTransport.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.transport; - -import org.connectbot.service.TerminalBridge; -import org.connectbot.service.TerminalManager; - -import java.io.IOException; - -/** - * @author Kenny Root - * @author modified by raaar - */ -public abstract class AbsTransport { - - TerminalBridge bridge; - TerminalManager manager; - - /** - * Causes transport to connect to the target host. After connecting but before a session is - * started, must call back to {@link TerminalBridge#onConnected()}. After that call a session may - * be opened. - */ - public abstract void connect(); - - /** - * Reads from the transport. Transport must support reading into a the byte array - * <code>buffer</code> at the start of <code>offset</code> and a maximum of <code>length</code> - * bytes. If the remote host disconnects, throw an {@link IOException}. - * - * @param buffer - * byte buffer to store read bytes into - * @param offset - * where to start writing in the buffer - * @param length - * maximum number of bytes to read - * @return number of bytes read - * @throws IOException - * when remote host disconnects - */ - public abstract int read(byte[] buffer, int offset, int length) throws IOException; - - /** - * Writes to the transport. If the host is not yet connected, simply return without doing - * anything. An {@link IOException} should be thrown if there is an error after connection. - * - * @param buffer - * bytes to write to transport - * @throws IOException - * when there is a problem writing after connection - */ - public abstract void write(byte[] buffer) throws IOException; - - /** - * Writes to the transport. See {@link #write(byte[])} for behavior details. - * - * @param c - * character to write to the transport - * @throws IOException - * when there is a problem writing after connection - */ - public abstract void write(int c) throws IOException; - - /** - * Flushes the write commands to the transport. - * - * @throws IOException - * when there is a problem writing after connection - */ - public abstract void flush() throws IOException; - - /** - * Closes the connection to the terminal. Note that the resulting failure to read should call - * {@link TerminalBridge#dispatchDisconnect(boolean)}. - */ - public abstract void close(); - - /** - * Tells the transport what dimensions the display is currently - * - * @param columns - * columns of text - * @param rows - * rows of text - * @param width - * width in pixels - * @param height - * height in pixels - */ - public abstract void setDimensions(int columns, int rows, int width, int height); - - public void setBridge(TerminalBridge bridge) { - this.bridge = bridge; - } - - public void setManager(TerminalManager manager) { - this.manager = manager; - } - - public abstract boolean isConnected(); - - public abstract boolean isSessionOpen(); - -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/ProcessTransport.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/ProcessTransport.java deleted file mode 100644 index ff894f0..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/transport/ProcessTransport.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.transport; - -import com.googlecode.android_scripting.Exec; -import com.googlecode.android_scripting.Log; -import com.googlecode.android_scripting.Process; - -import java.io.FileDescriptor; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class ProcessTransport extends AbsTransport { - - private FileDescriptor shellFd; - private final Process mProcess; - private InputStream is; - private OutputStream os; - private boolean mConnected = false; - - public ProcessTransport(Process process) { - mProcess = process; - shellFd = process.getFd(); - is = process.getIn(); - os = process.getOut(); - } - - @Override - public void close() { - mProcess.kill(); - } - - @Override - public void connect() { - mConnected = true; - } - - @Override - public void flush() throws IOException { - os.flush(); - } - - @Override - public boolean isConnected() { - return mConnected && mProcess.isAlive(); - } - - @Override - public boolean isSessionOpen() { - return mProcess.isAlive(); - } - - @Override - public int read(byte[] buffer, int start, int len) throws IOException { - if (is == null) { - mConnected = false; - bridge.dispatchDisconnect(false); - throw new IOException("session closed"); - } - try { - return is.read(buffer, start, len); - } catch (IOException e) { - mConnected = false; - bridge.dispatchDisconnect(false); - throw new IOException("session closed"); - } - } - - @Override - public void setDimensions(int columns, int rows, int width, int height) { - try { - Exec.setPtyWindowSize(shellFd, rows, columns, width, height); - } catch (Exception e) { - Log.e("Couldn't resize pty", e); - } - } - - @Override - public void write(byte[] buffer) throws IOException { - if (os != null) { - os.write(buffer); - } - } - - @Override - public void write(int c) throws IOException { - if (os != null) { - os.write(c); - } - } - -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/Colors.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/Colors.java deleted file mode 100644 index 13310e2..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/Colors.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.util; - -/** - * @author Kenny Root - * - */ -public class Colors { - public final static int[] defaults = - new int[] { - 0xff000000, // black - 0xffcc0000, // red - 0xff00cc00, // green - 0xffcccc00, // brown - 0xff0000cc, // blue - 0xffcc00cc, // purple - 0xff00cccc, // cyan - 0xffcccccc, // light grey - 0xff444444, // dark grey - 0xffff4444, // light red - 0xff44ff44, // light green - 0xffffff44, // yellow - 0xff4444ff, // light blue - 0xffff44ff, // light purple - 0xff44ffff, // light cyan - 0xffffffff, // white - 0xff000000, 0xff00005f, 0xff000087, 0xff0000af, 0xff0000d7, 0xff0000ff, 0xff005f00, - 0xff005f5f, 0xff005f87, 0xff005faf, 0xff005fd7, 0xff005fff, 0xff008700, 0xff00875f, - 0xff008787, 0xff0087af, 0xff0087d7, 0xff0087ff, 0xff00af00, 0xff00af5f, 0xff00af87, - 0xff00afaf, 0xff00afd7, 0xff00afff, 0xff00d700, 0xff00d75f, 0xff00d787, 0xff00d7af, - 0xff00d7d7, 0xff00d7ff, 0xff00ff00, 0xff00ff5f, 0xff00ff87, 0xff00ffaf, 0xff00ffd7, - 0xff00ffff, 0xff5f0000, 0xff5f005f, 0xff5f0087, 0xff5f00af, 0xff5f00d7, 0xff5f00ff, - 0xff5f5f00, 0xff5f5f5f, 0xff5f5f87, 0xff5f5faf, 0xff5f5fd7, 0xff5f5fff, 0xff5f8700, - 0xff5f875f, 0xff5f8787, 0xff5f87af, 0xff5f87d7, 0xff5f87ff, 0xff5faf00, 0xff5faf5f, - 0xff5faf87, 0xff5fafaf, 0xff5fafd7, 0xff5fafff, 0xff5fd700, 0xff5fd75f, 0xff5fd787, - 0xff5fd7af, 0xff5fd7d7, 0xff5fd7ff, 0xff5fff00, 0xff5fff5f, 0xff5fff87, 0xff5fffaf, - 0xff5fffd7, 0xff5fffff, 0xff870000, 0xff87005f, 0xff870087, 0xff8700af, 0xff8700d7, - 0xff8700ff, 0xff875f00, 0xff875f5f, 0xff875f87, 0xff875faf, 0xff875fd7, 0xff875fff, - 0xff878700, 0xff87875f, 0xff878787, 0xff8787af, 0xff8787d7, 0xff8787ff, 0xff87af00, - 0xff87af5f, 0xff87af87, 0xff87afaf, 0xff87afd7, 0xff87afff, 0xff87d700, 0xff87d75f, - 0xff87d787, 0xff87d7af, 0xff87d7d7, 0xff87d7ff, 0xff87ff00, 0xff87ff5f, 0xff87ff87, - 0xff87ffaf, 0xff87ffd7, 0xff87ffff, 0xffaf0000, 0xffaf005f, 0xffaf0087, 0xffaf00af, - 0xffaf00d7, 0xffaf00ff, 0xffaf5f00, 0xffaf5f5f, 0xffaf5f87, 0xffaf5faf, 0xffaf5fd7, - 0xffaf5fff, 0xffaf8700, 0xffaf875f, 0xffaf8787, 0xffaf87af, 0xffaf87d7, 0xffaf87ff, - 0xffafaf00, 0xffafaf5f, 0xffafaf87, 0xffafafaf, 0xffafafd7, 0xffafafff, 0xffafd700, - 0xffafd75f, 0xffafd787, 0xffafd7af, 0xffafd7d7, 0xffafd7ff, 0xffafff00, 0xffafff5f, - 0xffafff87, 0xffafffaf, 0xffafffd7, 0xffafffff, 0xffd70000, 0xffd7005f, 0xffd70087, - 0xffd700af, 0xffd700d7, 0xffd700ff, 0xffd75f00, 0xffd75f5f, 0xffd75f87, 0xffd75faf, - 0xffd75fd7, 0xffd75fff, 0xffd78700, 0xffd7875f, 0xffd78787, 0xffd787af, 0xffd787d7, - 0xffd787ff, 0xffd7af00, 0xffd7af5f, 0xffd7af87, 0xffd7afaf, 0xffd7afd7, 0xffd7afff, - 0xffd7d700, 0xffd7d75f, 0xffd7d787, 0xffd7d7af, 0xffd7d7d7, 0xffd7d7ff, 0xffd7ff00, - 0xffd7ff5f, 0xffd7ff87, 0xffd7ffaf, 0xffd7ffd7, 0xffd7ffff, 0xffff0000, 0xffff005f, - 0xffff0087, 0xffff00af, 0xffff00d7, 0xffff00ff, 0xffff5f00, 0xffff5f5f, 0xffff5f87, - 0xffff5faf, 0xffff5fd7, 0xffff5fff, 0xffff8700, 0xffff875f, 0xffff8787, 0xffff87af, - 0xffff87d7, 0xffff87ff, 0xffffaf00, 0xffffaf5f, 0xffffaf87, 0xffffafaf, 0xffffafd7, - 0xffffafff, 0xffffd700, 0xffffd75f, 0xffffd787, 0xffffd7af, 0xffffd7d7, 0xffffd7ff, - 0xffffff00, 0xffffff5f, 0xffffff87, 0xffffffaf, 0xffffffd7, 0xffffffff, 0xff080808, - 0xff121212, 0xff1c1c1c, 0xff262626, 0xff303030, 0xff3a3a3a, 0xff444444, 0xff4e4e4e, - 0xff585858, 0xff626262, 0xff6c6c6c, 0xff767676, 0xff808080, 0xff8a8a8a, 0xff949494, - 0xff9e9e9e, 0xffa8a8a8, 0xffb2b2b2, 0xffbcbcbc, 0xffc6c6c6, 0xffd0d0d0, 0xffdadada, - 0xffe4e4e4, 0xffeeeeee, }; -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/ColorsActivity.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/ColorsActivity.java deleted file mode 100644 index 532da35..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/ColorsActivity.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.connectbot.util; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.MenuItem.OnMenuItemClickListener; -import android.view.ViewGroup.LayoutParams; -import android.widget.AdapterView; -import android.widget.BaseAdapter; -import android.widget.GridView; -import android.widget.LinearLayout; -import android.widget.AdapterView.OnItemClickListener; - -import com.googlecode.android_scripting.R; - -import org.connectbot.util.UberColorPickerDialog.OnColorChangedListener; - -/** - * @author modified by raaar - */ -public class ColorsActivity extends Activity implements OnItemClickListener, OnColorChangedListener { - - private SharedPreferences mPreferences; - - private static int sLayoutLanscapeWidth = 400; - private static int sLayoutPortraitWidth = 210; - - private GridView mColorGrid; - private LinearLayout mLayout; - - private int mFgColor; - private int mBgColor; - - private int mCurrentColor = 0; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); - - mFgColor = - mPreferences.getInt(PreferenceConstants.COLOR_FG, PreferenceConstants.DEFAULT_FG_COLOR); - mBgColor = - mPreferences.getInt(PreferenceConstants.COLOR_BG, PreferenceConstants.DEFAULT_BG_COLOR); - - setContentView(R.layout.act_colors); - - this.setTitle("Terminal Colors"); - - mLayout = (LinearLayout) findViewById(R.id.color_layout); - - mColorGrid = (GridView) findViewById(R.id.color_grid); - mColorGrid.setOnItemClickListener(this); - mColorGrid.setSelection(0); - - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { - mColorGrid.setNumColumns(2); - LayoutParams params = mLayout.getLayoutParams(); - params.height = params.width; - params.width = LayoutParams.WRAP_CONTENT; - } - mColorGrid.setAdapter(new ColorsAdapter(true)); - - } - - private class ColorsAdapter extends BaseAdapter { - private boolean mSquareViews; - - public ColorsAdapter(boolean squareViews) { - mSquareViews = squareViews; - } - - public View getView(int position, View convertView, ViewGroup parent) { - ColorView c; - if (convertView == null) { - c = new ColorView(ColorsActivity.this, mSquareViews); - } else { - c = (ColorView) convertView; - } - if (position == 0) { - c.setColor(mFgColor); - c.setTitle("Foreground color"); - } else { - c.setColor(mBgColor); - c.setTitle("Background color"); - } - return c; - } - - public int getCount() { - return 2; - } - - public Object getItem(int position) { - return (position == 0) ? mFgColor : mBgColor; - } - - public long getItemId(int position) { - return position; - } - } - - private class ColorView extends View { - private boolean mSquare; - - private Paint mTextPaint; - private Paint mShadowPaint; - // Things we paint - private int mBackgroundColor; - private String mText; - - private int mAscent; - private int mWidthCenter; - private int mHeightCenter; - - public ColorView(Context context, boolean square) { - super(context); - - mSquare = square; - - mTextPaint = new Paint(); - mTextPaint.setAntiAlias(true); - mTextPaint.setTextSize(16); - mTextPaint.setColor(0xFFFFFFFF); - mTextPaint.setTextAlign(Paint.Align.CENTER); - - mShadowPaint = new Paint(mTextPaint); - mShadowPaint.setStyle(Paint.Style.STROKE); - mShadowPaint.setStrokeCap(Paint.Cap.ROUND); - mShadowPaint.setStrokeJoin(Paint.Join.ROUND); - mShadowPaint.setStrokeWidth(4f); - mShadowPaint.setColor(0xFF000000); - - setPadding(20, 20, 20, 20); - } - - public void setColor(int color) { - mBackgroundColor = color; - } - - public void setTitle(String title) { - mText = title; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int width = measureWidth(widthMeasureSpec); - - int height; - if (mSquare) { - height = width; - } else { - height = measureHeight(heightMeasureSpec); - } - - mAscent = (int) mTextPaint.ascent(); - mWidthCenter = width / 2; - mHeightCenter = height / 2 - mAscent / 2; - - setMeasuredDimension(width, height); - } - - private int measureWidth(int measureSpec) { - int result = 0; - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - if (specMode == MeasureSpec.EXACTLY) { - // We were told how big to be - result = specSize; - } else { - // Measure the text - result = (int) mTextPaint.measureText(mText) + getPaddingLeft() + getPaddingRight(); - if (specMode == MeasureSpec.AT_MOST) { - // Respect AT_MOST value if that was what is called for by - // measureSpec - result = Math.min(result, specSize); - } - } - - return result; - } - - private int measureHeight(int measureSpec) { - int result = 0; - int specMode = MeasureSpec.getMode(measureSpec); - int specSize = MeasureSpec.getSize(measureSpec); - - mAscent = (int) mTextPaint.ascent(); - if (specMode == MeasureSpec.EXACTLY) { - // We were told how big to be - result = specSize; - } else { - // Measure the text (beware: ascent is a negative number) - result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop() + getPaddingBottom(); - if (specMode == MeasureSpec.AT_MOST) { - // Respect AT_MOST value if that was what is called for by - // measureSpec - result = Math.min(result, specSize); - } - } - return result; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - canvas.drawColor(mBackgroundColor); - canvas.drawText(mText, mWidthCenter, mHeightCenter, mShadowPaint); - canvas.drawText(mText, mWidthCenter, mHeightCenter, mTextPaint); - } - } - - private void editColor(int colorNumber) { - mCurrentColor = colorNumber; - new UberColorPickerDialog(this, this, (colorNumber == 0) ? mFgColor : mBgColor).show(); - } - - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - editColor(position); - } - - public void onNothingSelected(AdapterView<?> arg0) { - } - - public void colorChanged(int value) { - SharedPreferences.Editor editor = mPreferences.edit(); - if (mCurrentColor == 0) { - mFgColor = value; - editor.putInt(PreferenceConstants.COLOR_FG, mFgColor); - } else { - mBgColor = value; - editor.putInt(PreferenceConstants.COLOR_BG, mBgColor); - } - editor.commit(); - mColorGrid.invalidateViews(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { - mColorGrid.setNumColumns(2); - LayoutParams params = mLayout.getLayoutParams(); - params.height = params.width; - params.width = sLayoutLanscapeWidth; - } else { - mColorGrid.setNumColumns(1); - LayoutParams params = mLayout.getLayoutParams(); - params.height = LayoutParams.WRAP_CONTENT; - params.width = sLayoutPortraitWidth; - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - MenuItem reset = menu.add("Reset"); - reset.setAlphabeticShortcut('r'); - reset.setNumericShortcut('1'); - reset.setIcon(android.R.drawable.ic_menu_revert); - reset.setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem arg0) { - mFgColor = PreferenceConstants.DEFAULT_FG_COLOR; - mBgColor = PreferenceConstants.DEFAULT_BG_COLOR; - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putInt(PreferenceConstants.COLOR_FG, mFgColor); - editor.putInt(PreferenceConstants.COLOR_BG, mBgColor); - editor.commit(); - mColorGrid.invalidateViews(); - return true; - } - }); - return true; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EastAsianWidth.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EastAsianWidth.java deleted file mode 100644 index b27cd48..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EastAsianWidth.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.util; - -import android.util.Log; - -/** - * @author Kenny Root - * - */ -public class EastAsianWidth { - public static boolean useJNI = false; - private static final String TAG = "ConnectBot.EastAsianWidth"; - - /** - * @param charArray - * @param i - * @param position - * @param wideAttribute - * @param isLegacyEastAsian - */ - public native static void measure(char[] charArray, int start, int end, - byte[] wideAttribute, boolean isLegacyEastAsian); - - static { - try { - System.loadLibrary("org_connectbot_util_EastAsianWidth"); - - char[] testInput = {(char)0x4EBA}; - byte[] testResult = new byte[1]; - measure(testInput, 0, 1, testResult, true); - - if (testResult[0] == 1) - useJNI = true; - else - Log.d(TAG, "EastAsianWidth JNI measuring not available"); - } catch (Exception e) { - // Failure - } catch (UnsatisfiedLinkError e1) { - // Failure - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EncodingPreference.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EncodingPreference.java deleted file mode 100644 index 8a6d7aa..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/EncodingPreference.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.connectbot.util; - -import android.content.Context; -import android.preference.ListPreference; -import android.util.AttributeSet; - -import java.nio.charset.Charset; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -public class EncodingPreference extends ListPreference { - - public EncodingPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - List<CharSequence> charsetIdsList = new LinkedList<CharSequence>(); - List<CharSequence> charsetNamesList = new LinkedList<CharSequence>(); - - for (Entry<String, Charset> entry : Charset.availableCharsets().entrySet()) { - Charset c = entry.getValue(); - if (c.canEncode() && c.isRegistered()) { - String key = entry.getKey(); - if (key.startsWith("cp")) { - // Custom CP437 charset changes - charsetIdsList.add("CP437"); - charsetNamesList.add("CP437"); - } - charsetIdsList.add(entry.getKey()); - charsetNamesList.add(c.displayName()); - } - } - - this.setEntryValues(charsetIdsList.toArray(new CharSequence[charsetIdsList.size()])); - this.setEntries(charsetNamesList.toArray(new CharSequence[charsetNamesList.size()])); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/HelpTopicView.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/HelpTopicView.java deleted file mode 100644 index bf6f026..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/HelpTopicView.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.util; - -import android.content.Context; -import android.util.AttributeSet; -import android.webkit.WebSettings; -import android.webkit.WebView; - -import org.connectbot.HelpActivity; - -/** - * @author Kenny Root - * - */ -public class HelpTopicView extends WebView { - public HelpTopicView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - initialize(); - } - - public HelpTopicView(Context context, AttributeSet attrs) { - super(context, attrs); - initialize(); - } - - public HelpTopicView(Context context) { - super(context); - initialize(); - } - - private void initialize() { - WebSettings wSet = getSettings(); - //wSet.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); - wSet.setUseWideViewPort(false); - } - - public HelpTopicView setTopic(String topic) { - String path = - String.format("file:///android_asset/%s/%s%s", HelpActivity.HELPDIR, topic, - HelpActivity.SUFFIX); - loadUrl(path); - - computeScroll(); - - return this; - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/PreferenceConstants.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/PreferenceConstants.java deleted file mode 100644 index d2c54d6..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/PreferenceConstants.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.util; - -/** - * @author Kenny Root - * @author modified by raaar - */ -public class PreferenceConstants { - - public static final String SCROLLBACK = "scrollback"; - public static final String FONTSIZE = "fontsize"; - public static final String KEYMODE = "keymode"; - public static final String ENCODING = "encoding"; - - public static final String DELKEY = "delkey"; - public static final String DELKEY_BACKSPACE = "backspace"; - public static final String DELKEY_DEL = "del"; - - public static final String ROTATION = "rotation"; - - public static final String ROTATION_DEFAULT = "Default"; - public static final String ROTATION_LANDSCAPE = "Force landscape"; - public static final String ROTATION_PORTRAIT = "Force portrait"; - public static final String ROTATION_AUTOMATIC = "Automatic"; - - public static final String FULLSCREEN = "fullscreen"; - - public static final String KEYMODE_RIGHT = "Use right-side keys"; - public static final String KEYMODE_LEFT = "Use left-side keys"; - - public static final String CAMERA = "camera"; - - public static final String CAMERA_CTRLA_SPACE = "Ctrl+A then Space"; - public static final String CAMERA_CTRLA = "Ctrl+A"; - public static final String CAMERA_ESC = "Esc"; - public static final String CAMERA_ESC_A = "Esc+A"; - - public static final String KEEP_ALIVE = "keepalive"; - - public static final String BUMPY_ARROWS = "bumpyarrows"; - public static final String HIDE_KEYBOARD = "hidekeyboard"; - - public static final String SORT_BY_COLOR = "sortByColor"; - - public static final String BELL = "bell"; - public static final String BELL_VOLUME = "bellVolume"; - public static final String BELL_VIBRATE = "bellVibrate"; - public static final float DEFAULT_BELL_VOLUME = 0.25f; - - public final static int DEFAULT_FG_COLOR = 0xffcccccc; - public final static int DEFAULT_BG_COLOR = 0xff000000; - public final static int DEFAULT_SCROLLBACK = 140; - public final static float DEFAULT_FONT_SIZE = 10; - - public final static String COLOR_FG = "color_fg"; - public final static String COLOR_BG = "color_bg"; - -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/SelectionArea.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/SelectionArea.java deleted file mode 100644 index 5735e55..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/SelectionArea.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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.util; - -import de.mud.terminal.VDUBuffer; - -/** - * @author Kenny Root - * Keep track of a selection area for the terminal copying mechanism. - * If the orientation is flipped one way, swap the bottom and top or - * left and right to keep it in the correct orientation. - */ -public class SelectionArea { - private int top; - private int bottom; - private int left; - private int right; - private int maxColumns; - private int maxRows; - private boolean selectingOrigin; - - public SelectionArea() { - reset(); - } - - public final void reset() { - top = left = bottom = right = 0; - selectingOrigin = true; - } - - /** - * @param columns - * @param rows - */ - public void setBounds(int columns, int rows) { - maxColumns = columns - 1; - maxRows = rows - 1; - } - - private int checkBounds(int value, int max) { - if (value < 0) - return 0; - else if (value > max) - return max; - else - return value; - } - - public boolean isSelectingOrigin() { - return selectingOrigin; - } - - public void finishSelectingOrigin() { - selectingOrigin = false; - } - - public void decrementRow() { - if (selectingOrigin) - setTop(top - 1); - else - setBottom(bottom - 1); - } - - public void incrementRow() { - if (selectingOrigin) - setTop(top + 1); - else - setBottom(bottom + 1); - } - - public void setRow(int row) { - if (selectingOrigin) - setTop(row); - else - setBottom(row); - } - - private void setTop(int top) { - this.top = bottom = checkBounds(top, maxRows); - } - - public int getTop() { - return Math.min(top, bottom); - } - - private void setBottom(int bottom) { - this.bottom = checkBounds(bottom, maxRows); - } - - public int getBottom() { - return Math.max(top, bottom); - } - - public void decrementColumn() { - if (selectingOrigin) - setLeft(left - 1); - else - setRight(right - 1); - } - - public void incrementColumn() { - if (selectingOrigin) - setLeft(left + 1); - else - setRight(right + 1); - } - - public void setColumn(int column) { - if (selectingOrigin) - setLeft(column); - else - setRight(column); - } - - private void setLeft(int left) { - this.left = right = checkBounds(left, maxColumns); - } - - public int getLeft() { - return Math.min(left, right); - } - - private void setRight(int right) { - this.right = checkBounds(right, maxColumns); - } - - public int getRight() { - return Math.max(left, right); - } - - public String copyFrom(VDUBuffer vb) { - int size = (getRight() - getLeft() + 1) * (getBottom() - getTop() + 1); - - StringBuffer buffer = new StringBuffer(size); - - for(int y = getTop(); y <= getBottom(); y++) { - int lastNonSpace = buffer.length(); - - for (int x = getLeft(); x <= getRight(); x++) { - // only copy printable chars - char c = vb.getChar(x, y); - - if (!Character.isDefined(c) || - (Character.isISOControl(c) && c != '\t')) - c = ' '; - - if (c != ' ') - lastNonSpace = buffer.length(); - - buffer.append(c); - } - - // Don't leave a bunch of spaces in our copy buffer. - if (buffer.length() > lastNonSpace) - buffer.delete(lastNonSpace + 1, buffer.length()); - - if (y != bottom) - buffer.append("\n"); - } - - return buffer.toString(); - } - - @Override - public String toString() { - StringBuilder buffer = new StringBuilder(); - - buffer.append("SelectionArea[top="); - buffer.append(top); - buffer.append(", bottom="); - buffer.append(bottom); - buffer.append(", left="); - buffer.append(left); - buffer.append(", right="); - buffer.append(right); - buffer.append(", maxColumns="); - buffer.append(maxColumns); - buffer.append(", maxRows="); - buffer.append(maxRows); - buffer.append(", isSelectingOrigin="); - buffer.append(isSelectingOrigin()); - buffer.append("]"); - - return buffer.toString(); - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/UberColorPickerDialog.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/UberColorPickerDialog.java deleted file mode 100644 index e12307e..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/UberColorPickerDialog.java +++ /dev/null @@ -1,982 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * 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. - */ - -/* - * 090408 - * Keith Wiley - * kwiley@keithwiley.com - * http://keithwiley.com - * - * UberColorPickerDialog v1.1 - * - * This color picker was implemented as a (significant) extension of the - * ColorPickerDialog class provided in the Android API Demos. You are free - * to drop it unchanged into your own projects or to modify it as you see - * fit. I would appreciate it if this comment block were let intact, - * merely for credit's sake. - * - * Enjoy! - */ - -package org.connectbot.util; - -import android.app.Dialog; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ComposeShader; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.graphics.RadialGradient; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Shader; -import android.graphics.SweepGradient; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.GradientDrawable.Orientation; -import android.os.Bundle; -import android.util.DisplayMetrics; -import android.view.MotionEvent; -import android.view.View; - -/** - * UberColorPickerDialog is a seriously enhanced version of the UberColorPickerDialog - * class provided in the Android API Demos.<p> - * - * NOTE (from Kenny Root): This is a VERY slimmed down version custom for ConnectBot. - * Visit Keith's site for the full version at the URL listed in the author line.<p> - * - * @author Keith Wiley, kwiley@keithwiley.com, http://keithwiley.com - */ -public class UberColorPickerDialog extends Dialog { - private OnColorChangedListener mListener; - private int mInitialColor; - - /** - * Callback to the creator of the dialog, informing the creator of a new color and notifying that the dialog is about to dismiss. - */ - public interface OnColorChangedListener { - void colorChanged(int color); - } - - /** - * Ctor - * @param context - * @param listener - * @param initialColor - * @param showTitle If true, a title is shown across the top of the dialog. If false a toast is shown instead. - */ - public UberColorPickerDialog(Context context, - OnColorChangedListener listener, - int initialColor) { - super(context); - - mListener = listener; - mInitialColor = initialColor; - } - - /** - * Activity entry point - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - OnColorChangedListener l = new OnColorChangedListener() { - public void colorChanged(int color) { - mListener.colorChanged(color); - dismiss(); - } - }; - - DisplayMetrics dm = new DisplayMetrics(); - getWindow().getWindowManager().getDefaultDisplay().getMetrics(dm); - int screenWidth = dm.widthPixels; - int screenHeight = dm.heightPixels; - - setTitle("Pick a color (try the trackball)"); - - try { - setContentView(new ColorPickerView(getContext(), l, screenWidth, screenHeight, mInitialColor)); - } - catch (Exception e) { - //There is currently only one kind of ctor exception, that where no methods are enabled. - dismiss(); //This doesn't work! The dialog is still shown (its title at least, the layout is empty from the exception being thrown). <sigh> - } - } - - /** - * ColorPickerView is the meat of this color picker (as opposed to the enclosing class). - * All the heavy lifting is done directly by this View subclass. - * <P> - * You can enable/disable whichever color chooser methods you want by modifying the ENABLED_METHODS switches. They *should* - * do all the work required to properly enable/disable methods without losing track of what goes with what and what maps to what. - * <P> - * If you add a new color chooser method, do a text search for "NEW_METHOD_WORK_NEEDED_HERE". That tag indicates all - * the locations in the code that will have to be amended in order to properly add a new color chooser method. - * I highly recommend adding new methods to the end of the list. If you want to try to reorder the list, you're on your own. - */ - private static class ColorPickerView extends View { - private static int SWATCH_WIDTH = 95; - private static final int SWATCH_HEIGHT = 60; - - private static int PALETTE_POS_X = 0; - private static int PALETTE_POS_Y = SWATCH_HEIGHT; - private static final int PALETTE_DIM = SWATCH_WIDTH * 2; - private static final int PALETTE_RADIUS = PALETTE_DIM / 2; - private static final int PALETTE_CENTER_X = PALETTE_RADIUS; - private static final int PALETTE_CENTER_Y = PALETTE_RADIUS; - - private static final int SLIDER_THICKNESS = 40; - - private static int VIEW_DIM_X = PALETTE_DIM; - private static int VIEW_DIM_Y = SWATCH_HEIGHT; - - //NEW_METHOD_WORK_NEEDED_HERE - private static final int METHOD_HS_V_PALETTE = 0; - - //NEW_METHOD_WORK_NEEDED_HERE - //Add a new entry to the list for each controller in the new method - private static final int TRACKED_NONE = -1; //No object on screen is currently being tracked - private static final int TRACK_SWATCH_OLD = 10; - private static final int TRACK_SWATCH_NEW = 11; - private static final int TRACK_HS_PALETTE = 30; - private static final int TRACK_VER_VALUE_SLIDER = 31; - - private static final int TEXT_SIZE = 12; - private static int[] TEXT_HSV_POS = new int[2]; - private static int[] TEXT_RGB_POS = new int[2]; - private static int[] TEXT_YUV_POS = new int[2]; - private static int[] TEXT_HEX_POS = new int[2]; - - private static final float PI = 3.141592653589793f; - - private int mMethod = METHOD_HS_V_PALETTE; - private int mTracking = TRACKED_NONE; //What object on screen is currently being tracked for movement - - //Zillions of persistant Paint objecs for drawing the View - - private Paint mSwatchOld, mSwatchNew; - - //NEW_METHOD_WORK_NEEDED_HERE - //Add Paints to represent the palettes of the new method's UI controllers - private Paint mOvalHueSat; - - private Bitmap mVerSliderBM; - private Canvas mVerSliderCv; - - private Bitmap[] mHorSlidersBM = new Bitmap[3]; - private Canvas[] mHorSlidersCv = new Canvas[3]; - - private Paint mValDimmer; - - //NEW_METHOD_WORK_NEEDED_HERE - //Add Paints to represent the icon for the new method - private Paint mOvalHueSatSmall; - - private Paint mPosMarker; - private Paint mText; - - private Rect mOldSwatchRect = new Rect(); - private Rect mNewSwatchRect = new Rect(); - private Rect mPaletteRect = new Rect(); - private Rect mVerSliderRect = new Rect(); - - private int[] mSpectrumColorsRev; - private int mOriginalColor = 0; //The color passed in at the beginning, which can be reverted to at any time by tapping the old swatch. - private float[] mHSV = new float[3]; - private int[] mRGB = new int[3]; - private float[] mYUV = new float[3]; - private String mHexStr = ""; - private boolean mHSVenabled = true; //Only true if an HSV method is enabled - private boolean mRGBenabled = true; //Only true if an RGB method is enabled - private boolean mYUVenabled = true; //Only true if a YUV method is enabled - private boolean mHexenabled = true; //Only true if an RGB method is enabled - private int[] mCoord = new int[3]; //For drawing slider/palette markers - private int mFocusedControl = -1; //Which control receives trackball events. - private OnColorChangedListener mListener; - - /** - * Ctor. - * @param c - * @param l - * @param width Used to determine orientation and adjust layout accordingly - * @param height Used to determine orientation and adjust layout accordingly - * @param color The initial color - * @throws Exception - */ - ColorPickerView(Context c, OnColorChangedListener l, int width, int height, int color) - throws Exception { - super(c); - - //We need to make the dialog focusable to retrieve trackball events. - setFocusable(true); - - mListener = l; - - mOriginalColor = color; - - Color.colorToHSV(color, mHSV); - - updateAllFromHSV(); - - //Setup the layout based on whether this is a portrait or landscape orientation. - if (width <= height) { //Portrait layout - SWATCH_WIDTH = (PALETTE_DIM + SLIDER_THICKNESS) / 2; - - PALETTE_POS_X = 0; - PALETTE_POS_Y = TEXT_SIZE * 4 + SWATCH_HEIGHT; - - //Set more rects, lots of rects - mOldSwatchRect.set(0, TEXT_SIZE * 4, SWATCH_WIDTH, TEXT_SIZE * 4 + SWATCH_HEIGHT); - mNewSwatchRect.set(SWATCH_WIDTH, TEXT_SIZE * 4, SWATCH_WIDTH * 2, TEXT_SIZE * 4 + SWATCH_HEIGHT); - mPaletteRect.set(0, PALETTE_POS_Y, PALETTE_DIM, PALETTE_POS_Y + PALETTE_DIM); - mVerSliderRect.set(PALETTE_DIM, PALETTE_POS_Y, PALETTE_DIM + SLIDER_THICKNESS, PALETTE_POS_Y + PALETTE_DIM); - - TEXT_HSV_POS[0] = 3; - TEXT_HSV_POS[1] = 0; - TEXT_RGB_POS[0] = TEXT_HSV_POS[0] + 50; - TEXT_RGB_POS[1] = TEXT_HSV_POS[1]; - TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + 100; - TEXT_YUV_POS[1] = TEXT_HSV_POS[1]; - TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + 150; - TEXT_HEX_POS[1] = TEXT_HSV_POS[1]; - - VIEW_DIM_X = PALETTE_DIM + SLIDER_THICKNESS; - VIEW_DIM_Y = SWATCH_HEIGHT + PALETTE_DIM + TEXT_SIZE * 4; - } - else { //Landscape layout - SWATCH_WIDTH = 110; - - PALETTE_POS_X = SWATCH_WIDTH; - PALETTE_POS_Y = 0; - - //Set more rects, lots of rects - mOldSwatchRect.set(0, TEXT_SIZE * 7, SWATCH_WIDTH, TEXT_SIZE * 7 + SWATCH_HEIGHT); - mNewSwatchRect.set(0, TEXT_SIZE * 7 + SWATCH_HEIGHT, SWATCH_WIDTH, TEXT_SIZE * 7 + SWATCH_HEIGHT * 2); - mPaletteRect.set(SWATCH_WIDTH, PALETTE_POS_Y, SWATCH_WIDTH + PALETTE_DIM, PALETTE_POS_Y + PALETTE_DIM); - mVerSliderRect.set(SWATCH_WIDTH + PALETTE_DIM, PALETTE_POS_Y, SWATCH_WIDTH + PALETTE_DIM + SLIDER_THICKNESS, PALETTE_POS_Y + PALETTE_DIM); - - TEXT_HSV_POS[0] = 3; - TEXT_HSV_POS[1] = 0; - TEXT_RGB_POS[0] = TEXT_HSV_POS[0]; - TEXT_RGB_POS[1] = (int)(TEXT_HSV_POS[1] + TEXT_SIZE * 3.5); - TEXT_YUV_POS[0] = TEXT_HSV_POS[0] + 50; - TEXT_YUV_POS[1] = (int)(TEXT_HSV_POS[1] + TEXT_SIZE * 3.5); - TEXT_HEX_POS[0] = TEXT_HSV_POS[0] + 50; - TEXT_HEX_POS[1] = TEXT_HSV_POS[1]; - - VIEW_DIM_X = PALETTE_POS_X + PALETTE_DIM + SLIDER_THICKNESS; - VIEW_DIM_Y = Math.max(mNewSwatchRect.bottom, PALETTE_DIM); - } - - //Rainbows make everybody happy! - mSpectrumColorsRev = new int[] { - 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, - 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000, - }; - - //Setup all the Paint and Shader objects. There are lots of them! - - //NEW_METHOD_WORK_NEEDED_HERE - //Add Paints to represent the palettes of the new method's UI controllers - - mSwatchOld = new Paint(Paint.ANTI_ALIAS_FLAG); - mSwatchOld.setStyle(Paint.Style.FILL); - mSwatchOld.setColor(Color.HSVToColor(mHSV)); - - mSwatchNew = new Paint(Paint.ANTI_ALIAS_FLAG); - mSwatchNew.setStyle(Paint.Style.FILL); - mSwatchNew.setColor(Color.HSVToColor(mHSV)); - - Shader shaderA = new SweepGradient(0, 0, mSpectrumColorsRev, null); - Shader shaderB = new RadialGradient(0, 0, PALETTE_CENTER_X, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP); - Shader shader = new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SCREEN); - mOvalHueSat = new Paint(Paint.ANTI_ALIAS_FLAG); - mOvalHueSat.setShader(shader); - mOvalHueSat.setStyle(Paint.Style.FILL); - mOvalHueSat.setDither(true); - - mVerSliderBM = Bitmap.createBitmap(SLIDER_THICKNESS, PALETTE_DIM, Bitmap.Config.RGB_565); - mVerSliderCv = new Canvas(mVerSliderBM); - - for (int i = 0; i < 3; i++) { - mHorSlidersBM[i] = Bitmap.createBitmap(PALETTE_DIM, SLIDER_THICKNESS, Bitmap.Config.RGB_565); - mHorSlidersCv[i] = new Canvas(mHorSlidersBM[i]); - } - - mValDimmer = new Paint(Paint.ANTI_ALIAS_FLAG); - mValDimmer.setStyle(Paint.Style.FILL); - mValDimmer.setDither(true); - mValDimmer.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); - - //Whew, we're done making the big Paints and Shaders for the swatches, palettes, and sliders. - //Now we need to make the Paints and Shaders that will draw the little method icons in the method selector list. - - //NEW_METHOD_WORK_NEEDED_HERE - //Add Paints to represent the icon for the new method - - shaderA = new SweepGradient(0, 0, mSpectrumColorsRev, null); - shaderB = new RadialGradient(0, 0, PALETTE_DIM / 2, 0xFFFFFFFF, 0xFF000000, Shader.TileMode.CLAMP); - shader = new ComposeShader(shaderA, shaderB, PorterDuff.Mode.SCREEN); - mOvalHueSatSmall = new Paint(Paint.ANTI_ALIAS_FLAG); - mOvalHueSatSmall.setShader(shader); - mOvalHueSatSmall.setStyle(Paint.Style.FILL); - - //Make a simple stroking Paint for drawing markers and borders and stuff like that. - mPosMarker = new Paint(Paint.ANTI_ALIAS_FLAG); - mPosMarker.setStyle(Paint.Style.STROKE); - mPosMarker.setStrokeWidth(2); - - //Make a basic text Paint. - mText = new Paint(Paint.ANTI_ALIAS_FLAG); - mText.setTextSize(TEXT_SIZE); - mText.setColor(Color.WHITE); - - //Kickstart - initUI(); - } - - /** - * Draw the entire view (the entire dialog). - */ - @Override - protected void onDraw(Canvas canvas) { - //Draw the old and new swatches - drawSwatches(canvas); - - //Write the text - writeColorParams(canvas); - - //Draw the palette and sliders (the UI) - if (mMethod == METHOD_HS_V_PALETTE) - drawHSV1Palette(canvas); - } - - /** - * Draw the old and new swatches. - * @param canvas - */ - private void drawSwatches(Canvas canvas) { - float[] hsv = new float[3]; - - mText.setTextSize(16); - - //Draw the original swatch - canvas.drawRect(mOldSwatchRect, mSwatchOld); - Color.colorToHSV(mOriginalColor, hsv); - //if (UberColorPickerDialog.isGray(mColor)) //Don't need this right here, but imp't to note - // hsv[1] = 0; - if (hsv[2] > .5) - mText.setColor(Color.BLACK); - canvas.drawText("Revert", mOldSwatchRect.left + SWATCH_WIDTH / 2 - mText.measureText("Revert") / 2, mOldSwatchRect.top + 16, mText); - mText.setColor(Color.WHITE); - - //Draw the new swatch - canvas.drawRect(mNewSwatchRect, mSwatchNew); - if (mHSV[2] > .5) - mText.setColor(Color.BLACK); - canvas.drawText("Accept", mNewSwatchRect.left + SWATCH_WIDTH / 2 - mText.measureText("Accept") / 2, mNewSwatchRect.top + 16, mText); - mText.setColor(Color.WHITE); - - mText.setTextSize(TEXT_SIZE); - } - - /** - * Write the color parametes (HSV, RGB, YUV, Hex, etc.). - * @param canvas - */ - private void writeColorParams(Canvas canvas) { - if (mHSVenabled) { - canvas.drawText("H: " + Integer.toString((int)(mHSV[0] / 360.0f * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE, mText); - canvas.drawText("S: " + Integer.toString((int)(mHSV[1] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE * 2, mText); - canvas.drawText("V: " + Integer.toString((int)(mHSV[2] * 255)), TEXT_HSV_POS[0], TEXT_HSV_POS[1] + TEXT_SIZE * 3, mText); - } - - if (mRGBenabled) { - canvas.drawText("R: " + mRGB[0], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE, mText); - canvas.drawText("G: " + mRGB[1], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE * 2, mText); - canvas.drawText("B: " + mRGB[2], TEXT_RGB_POS[0], TEXT_RGB_POS[1] + TEXT_SIZE * 3, mText); - } - - if (mYUVenabled) { - canvas.drawText("Y: " + Integer.toString((int)(mYUV[0] * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE, mText); - canvas.drawText("U: " + Integer.toString((int)((mYUV[1] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE * 2, mText); - canvas.drawText("V: " + Integer.toString((int)((mYUV[2] + .5f) * 255)), TEXT_YUV_POS[0], TEXT_YUV_POS[1] + TEXT_SIZE * 3, mText); - } - - if (mHexenabled) - canvas.drawText("#" + mHexStr, TEXT_HEX_POS[0], TEXT_HEX_POS[1] + TEXT_SIZE, mText); - } - - /** - * Place a small circle on the 2D palette to indicate the current values. - * @param canvas - * @param markerPosX - * @param markerPosY - */ - private void mark2DPalette(Canvas canvas, int markerPosX, int markerPosY) { - mPosMarker.setColor(Color.BLACK); - canvas.drawOval(new RectF(markerPosX - 5, markerPosY - 5, markerPosX + 5, markerPosY + 5), mPosMarker); - mPosMarker.setColor(Color.WHITE); - canvas.drawOval(new RectF(markerPosX - 3, markerPosY - 3, markerPosX + 3, markerPosY + 3), mPosMarker); - } - - /** - * Draw a line across the slider to indicate its current value. - * @param canvas - * @param markerPos - */ - private void markVerSlider(Canvas canvas, int markerPos) { - mPosMarker.setColor(Color.BLACK); - canvas.drawRect(new Rect(0, markerPos - 2, SLIDER_THICKNESS, markerPos + 3), mPosMarker); - mPosMarker.setColor(Color.WHITE); - canvas.drawRect(new Rect(0, markerPos, SLIDER_THICKNESS, markerPos + 1), mPosMarker); - } - - /** - * Frame the slider to indicate that it has trackball focus. - * @param canvas - */ - private void hilightFocusedVerSlider(Canvas canvas) { - mPosMarker.setColor(Color.WHITE); - canvas.drawRect(new Rect(0, 0, SLIDER_THICKNESS, PALETTE_DIM), mPosMarker); - mPosMarker.setColor(Color.BLACK); - canvas.drawRect(new Rect(2, 2, SLIDER_THICKNESS - 2, PALETTE_DIM - 2), mPosMarker); - } - - /** - * Frame the 2D palette to indicate that it has trackball focus. - * @param canvas - */ - private void hilightFocusedOvalPalette(Canvas canvas) { - mPosMarker.setColor(Color.WHITE); - canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mPosMarker); - mPosMarker.setColor(Color.BLACK); - canvas.drawOval(new RectF(-PALETTE_RADIUS + 2, -PALETTE_RADIUS + 2, PALETTE_RADIUS - 2, PALETTE_RADIUS - 2), mPosMarker); - } - - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate the basic draw functions here. Use the 2D palette or 1D sliders as templates for the new method. - /** - * Draw the UI for HSV with angular H and radial S combined in 2D and a 1D V slider. - * @param canvas - */ - private void drawHSV1Palette(Canvas canvas) { - canvas.save(); - - canvas.translate(PALETTE_POS_X, PALETTE_POS_Y); - - //Draw the 2D palette - canvas.translate(PALETTE_CENTER_X, PALETTE_CENTER_Y); - canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mOvalHueSat); - canvas.drawOval(new RectF(-PALETTE_RADIUS, -PALETTE_RADIUS, PALETTE_RADIUS, PALETTE_RADIUS), mValDimmer); - if (mFocusedControl == 0) - hilightFocusedOvalPalette(canvas); - mark2DPalette(canvas, mCoord[0], mCoord[1]); - canvas.translate(-PALETTE_CENTER_X, -PALETTE_CENTER_Y); - - //Draw the 1D slider - canvas.translate(PALETTE_DIM, 0); - canvas.drawBitmap(mVerSliderBM, 0, 0, null); - if (mFocusedControl == 1) - hilightFocusedVerSlider(canvas); - markVerSlider(canvas, mCoord[2]); - - canvas.restore(); - } - - /** - * Initialize the current color chooser's UI (set its color parameters and set its palette and slider values accordingly). - */ - private void initUI() { - initHSV1Palette(); - - //Focus on the first controller (arbitrary). - mFocusedControl = 0; - } - - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the last init function shown below - /** - * Initialize a color chooser. - */ - private void initHSV1Palette() { - setOvalValDimmer(); - setVerValSlider(); - - float angle = 2*PI - mHSV[0] / (180 / 3.1415927f); - float radius = mHSV[1] * PALETTE_RADIUS; - mCoord[0] = (int)(Math.cos(angle) * radius); - mCoord[1] = (int)(Math.sin(angle) * radius); - - mCoord[2] = PALETTE_DIM - (int)(mHSV[2] * PALETTE_DIM); - } - - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the set functions below, one per UI controller in the new method - /** - * Adjust a Paint which, when painted, dims its underlying object to show the effects of varying value (brightness). - */ - private void setOvalValDimmer() { - float[] hsv = new float[3]; - hsv[0] = mHSV[0]; - hsv[1] = 0; - hsv[2] = mHSV[2]; - int gray = Color.HSVToColor(hsv); - mValDimmer.setColor(gray); - } - - /** - * Create a linear gradient shader to show variations in value. - */ - private void setVerValSlider() { - float[] hsv = new float[3]; - hsv[0] = mHSV[0]; - hsv[1] = mHSV[1]; - hsv[2] = 1; - int col = Color.HSVToColor(hsv); - - int colors[] = new int[2]; - colors[0] = col; - colors[1] = 0xFF000000; - GradientDrawable gradDraw = new GradientDrawable(Orientation.TOP_BOTTOM, colors); - gradDraw.setDither(true); - gradDraw.setLevel(10000); - gradDraw.setBounds(0, 0, SLIDER_THICKNESS, PALETTE_DIM); - gradDraw.draw(mVerSliderCv); - } - - /** - * Report the correct tightly bounded dimensions of the view. - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(VIEW_DIM_X, VIEW_DIM_Y); - } - - /** - * Wrap Math.round(). I'm not a Java expert. Is this the only way to avoid writing "(int)Math.round" everywhere? - * @param x - * @return - */ - private int round(double x) { - return (int)Math.round(x); - } - - /** - * Limit a value to the range [0,1]. - * @param n - * @return - */ - private float pinToUnit(float n) { - if (n < 0) { - n = 0; - } else if (n > 1) { - n = 1; - } - return n; - } - - /** - * Limit a value to the range [0,max]. - * @param n - * @param max - * @return - */ - private float pin(float n, float max) { - if (n < 0) { - n = 0; - } else if (n > max) { - n = max; - } - return n; - } - - /** - * Limit a value to the range [min,max]. - * @param n - * @param min - * @param max - * @return - */ - private float pin(float n, float min, float max) { - if (n < min) { - n = min; - } else if (n > max) { - n = max; - } - return n; - } - - /** - * No clue what this does (some sort of average/mean I presume). It came with the original UberColorPickerDialog - * in the API Demos and wasn't documented. I don't feel like spending any time figuring it out, I haven't looked at it at all. - * @param s - * @param d - * @param p - * @return - */ - private int ave(int s, int d, float p) { - return s + round(p * (d - s)); - } - - /** - * Came with the original UberColorPickerDialog in the API Demos, wasn't documented. I believe it takes an array of - * colors and a value in the range [0,1] and interpolates a resulting color in a seemingly predictable manner. - * I haven't looked at it at all. - * @param colors - * @param unit - * @return - */ - private int interpColor(int colors[], float unit) { - if (unit <= 0) { - return colors[0]; - } - if (unit >= 1) { - return colors[colors.length - 1]; - } - - float p = unit * (colors.length - 1); - int i = (int)p; - p -= i; - - // now p is just the fractional part [0...1) and i is the index - int c0 = colors[i]; - int c1 = colors[i+1]; - int a = ave(Color.alpha(c0), Color.alpha(c1), p); - int r = ave(Color.red(c0), Color.red(c1), p); - int g = ave(Color.green(c0), Color.green(c1), p); - int b = ave(Color.blue(c0), Color.blue(c1), p); - - return Color.argb(a, r, g, b); - } - - /** - * A standard point-in-rect routine. - * @param x - * @param y - * @param r - * @return true if point x,y is in rect r - */ - public boolean ptInRect(int x, int y, Rect r) { - return x > r.left && x < r.right && y > r.top && y < r.bottom; - } - - /** - * Process trackball events. Used mainly for fine-tuned color adjustment, or alternatively to switch between slider controls. - */ - @Override - public boolean dispatchTrackballEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - - //A longer event history implies faster trackball movement. - //Use it to infer a larger jump and therefore faster palette/slider adjustment. - int jump = event.getHistorySize() + 1; - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: { - } - break; - case MotionEvent.ACTION_MOVE: { - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the appropriate entry in this list, - //depending on whether you use 1D or 2D controllers - switch (mMethod) { - case METHOD_HS_V_PALETTE: - if (mFocusedControl == 0) { - changeHSPalette(x, y, jump); - } - else if (mFocusedControl == 1) { - if (y < 0) - changeSlider(mFocusedControl, true, jump); - else if (y > 0) - changeSlider(mFocusedControl, false, jump); - } - break; - } - } - break; - case MotionEvent.ACTION_UP: { - } - break; - } - - return true; - } - - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the appropriate functions below, - //one per UI controller in the new method - /** - * Effect a trackball change to a 2D palette. - * @param x -1: negative x change, 0: no x change, +1: positive x change. - * @param y -1: negative y change, 0, no y change, +1: positive y change. - * @param jump the amount by which to change. - */ - private void changeHSPalette(float x, float y, int jump) { - int x2 = 0, y2 = 0; - if (x < 0) - x2 = -jump; - else if (x > 0) - x2 = jump; - if (y < 0) - y2 = -jump; - else if (y > 0) - y2 = jump; - - mCoord[0] += x2; - mCoord[1] += y2; - - if (mCoord[0] < -PALETTE_RADIUS) - mCoord[0] = -PALETTE_RADIUS; - else if (mCoord[0] > PALETTE_RADIUS) - mCoord[0] = PALETTE_RADIUS; - if (mCoord[1] < -PALETTE_RADIUS) - mCoord[1] = -PALETTE_RADIUS; - else if (mCoord[1] > PALETTE_RADIUS) - mCoord[1] = PALETTE_RADIUS; - - float radius = (float)java.lang.Math.sqrt(mCoord[0] * mCoord[0] + mCoord[1] * mCoord[1]); - if (radius > PALETTE_RADIUS) - radius = PALETTE_RADIUS; - - float angle = (float)java.lang.Math.atan2(mCoord[1], mCoord[0]); - // need to turn angle [-PI ... PI] into unit [0....1] - float unit = angle/(2*PI); - if (unit < 0) { - unit += 1; - } - - mCoord[0] = round(Math.cos(angle) * radius); - mCoord[1] = round(Math.sin(angle) * radius); - - int c = interpColor(mSpectrumColorsRev, unit); - float[] hsv = new float[3]; - Color.colorToHSV(c, hsv); - mHSV[0] = hsv[0]; - mHSV[1] = radius / PALETTE_RADIUS; - updateAllFromHSV(); - mSwatchNew.setColor(Color.HSVToColor(mHSV)); - - setVerValSlider(); - - invalidate(); - } - - /** - * Effect a trackball change to a 1D slider. - * @param slider id of the slider to be effected - * @param increase true if the change is an increase, false if a decrease - * @param jump the amount by which to change in units of the range [0,255] - */ - private void changeSlider(int slider, boolean increase, int jump) { - //NEW_METHOD_WORK_NEEDED_HERE - //It is only necessary to add an entry here for a new method if the new method uses a 1D slider. - //Note, some sliders are horizontal and others are vertical. - //They differ a bit, especially in a sign flip on the vertical axis. - if (mMethod == METHOD_HS_V_PALETTE) { - //slider *must* equal 1 - - mHSV[2] += (increase ? jump : -jump) / 256.0f; - mHSV[2] = pinToUnit(mHSV[2]); - updateAllFromHSV(); - mCoord[2] = PALETTE_DIM - (int)(mHSV[2] * PALETTE_DIM); - - mSwatchNew.setColor(Color.HSVToColor(mHSV)); - - setOvalValDimmer(); - - invalidate(); - } - } - - /** - * Keep all colorspace representations in sync. - */ - private void updateRGBfromHSV() { - int color = Color.HSVToColor(mHSV); - mRGB[0] = Color.red(color); - mRGB[1] = Color.green(color); - mRGB[2] = Color.blue(color); - } - - /** - * Keep all colorspace representations in sync. - */ - private void updateYUVfromRGB() { - float r = mRGB[0] / 255.0f; - float g = mRGB[1] / 255.0f; - float b = mRGB[2] / 255.0f; - - ColorMatrix cm = new ColorMatrix(); - cm.setRGB2YUV(); - final float[] a = cm.getArray(); - - mYUV[0] = a[0] * r + a[1] * g + a[2] * b; - mYUV[0] = pinToUnit(mYUV[0]); - mYUV[1] = a[5] * r + a[6] * g + a[7] * b; - mYUV[1] = pin(mYUV[1], -.5f, .5f); - mYUV[2] = a[10] * r + a[11] * g + a[12] * b; - mYUV[2] = pin(mYUV[2], -.5f, .5f); - } - - /** - * Keep all colorspace representations in sync. - */ - private void updateHexFromHSV() { - //For now, assume 100% opacity - mHexStr = Integer.toHexString(Color.HSVToColor(mHSV)).toUpperCase(); - mHexStr = mHexStr.substring(2, mHexStr.length()); - } - - /** - * Keep all colorspace representations in sync. - */ - private void updateAllFromHSV() { - //Update mRGB - if (mRGBenabled || mYUVenabled) - updateRGBfromHSV(); - - //Update mYUV - if (mYUVenabled) - updateYUVfromRGB(); - - //Update mHexStr - if (mRGBenabled) - updateHexFromHSV(); - } - - /** - * Process touch events: down, move, and up - */ - @Override - public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - - //Generate coordinates which are palette=local with the origin at the upper left of the main 2D palette - int y2 = (int)(pin(round(y - PALETTE_POS_Y), PALETTE_DIM)); - - //Generate coordinates which are palette-local with the origin at the center of the main 2D palette - float circlePinnedX = x - PALETTE_POS_X - PALETTE_CENTER_X; - float circlePinnedY = y - PALETTE_POS_Y - PALETTE_CENTER_Y; - - //Is the event in a swatch? - boolean inSwatchOld = ptInRect(round(x), round(y), mOldSwatchRect); - boolean inSwatchNew = ptInRect(round(x), round(y), mNewSwatchRect); - - //Get the event's distance from the center of the main 2D palette - float radius = (float)java.lang.Math.sqrt(circlePinnedX * circlePinnedX + circlePinnedY * circlePinnedY); - - //Is the event in a circle-pinned 2D palette? - boolean inOvalPalette = radius <= PALETTE_RADIUS; - - //Pin the radius - if (radius > PALETTE_RADIUS) - radius = PALETTE_RADIUS; - - //Is the event in a vertical slider to the right of the main 2D palette - boolean inVerSlider = ptInRect(round(x), round(y), mVerSliderRect); - - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - mTracking = TRACKED_NONE; - - if (inSwatchOld) - mTracking = TRACK_SWATCH_OLD; - else if (inSwatchNew) - mTracking = TRACK_SWATCH_NEW; - - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the last entry in this list - else if (mMethod == METHOD_HS_V_PALETTE) { - if (inOvalPalette) { - mTracking = TRACK_HS_PALETTE; - mFocusedControl = 0; - } - else if (inVerSlider) { - mTracking = TRACK_VER_VALUE_SLIDER; - mFocusedControl = 1; - } - } - case MotionEvent.ACTION_MOVE: - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the entries in this list, - //one per UI controller the new method requires. - if (mTracking == TRACK_HS_PALETTE) { - float angle = (float)java.lang.Math.atan2(circlePinnedY, circlePinnedX); - // need to turn angle [-PI ... PI] into unit [0....1] - float unit = angle/(2*PI); - if (unit < 0) { - unit += 1; - } - - mCoord[0] = round(Math.cos(angle) * radius); - mCoord[1] = round(Math.sin(angle) * radius); - - int c = interpColor(mSpectrumColorsRev, unit); - float[] hsv = new float[3]; - Color.colorToHSV(c, hsv); - mHSV[0] = hsv[0]; - mHSV[1] = radius / PALETTE_RADIUS; - updateAllFromHSV(); - mSwatchNew.setColor(Color.HSVToColor(mHSV)); - - setVerValSlider(); - - invalidate(); - } - else if (mTracking == TRACK_VER_VALUE_SLIDER) { - if (mCoord[2] != y2) { - mCoord[2] = y2; - float value = 1.0f - (float)y2 / (float)PALETTE_DIM; - - mHSV[2] = value; - updateAllFromHSV(); - mSwatchNew.setColor(Color.HSVToColor(mHSV)); - - setOvalValDimmer(); - - invalidate(); - } - } - break; - case MotionEvent.ACTION_UP: - //NEW_METHOD_WORK_NEEDED_HERE - //To add a new method, replicate and extend the last entry in this list. - if (mTracking == TRACK_SWATCH_OLD && inSwatchOld) { - Color.colorToHSV(mOriginalColor, mHSV); - mSwatchNew.setColor(mOriginalColor); - initUI(); - invalidate(); - } - else if (mTracking == TRACK_SWATCH_NEW && inSwatchNew) { - mListener.colorChanged(mSwatchNew.getColor()); - invalidate(); - } - - mTracking= TRACKED_NONE; - break; - } - - return true; - } - } -} diff --git a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/VolumePreference.java b/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/VolumePreference.java deleted file mode 100644 index 2e7f61c..0000000 --- a/sl4a/ScriptingLayerForAndroid/src/org/connectbot/util/VolumePreference.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.util; - -import android.content.Context; -import android.preference.DialogPreference; -import android.util.AttributeSet; -import android.view.View; -import android.widget.SeekBar; -import android.widget.SeekBar.OnSeekBarChangeListener; - -/** - * @author kenny - * - */ -public class VolumePreference extends DialogPreference implements OnSeekBarChangeListener { - /** - * @param context - * @param attrs - */ - public VolumePreference(Context context, AttributeSet attrs) { - super(context, attrs); - - setupLayout(context, attrs); - } - - public VolumePreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - setupLayout(context, attrs); - } - - private void setupLayout(Context context, AttributeSet attrs) { - setPersistent(true); - } - - @Override - protected View onCreateDialogView() { - SeekBar sb = new SeekBar(getContext()); - - sb.setMax(100); - sb.setProgress((int)(getPersistedFloat( - PreferenceConstants.DEFAULT_BELL_VOLUME) * 100)); - sb.setPadding(10, 10, 10, 10); - sb.setOnSeekBarChangeListener(this); - - return sb; - } - - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - persistFloat(progress / 100f); - } - - public void onStartTrackingTouch(SeekBar seekBar) { } - - public void onStopTrackingTouch(SeekBar seekBar) { } -} diff --git a/sl4a/Utils/Android.mk b/sl4a/Utils/Android.mk deleted file mode 100644 index 5417389..0000000 --- a/sl4a/Utils/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (C) 2016 Google, Inc. -# -# 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - - -LOCAL_MODULE := sl4a.Utils -LOCAL_MODULE_OWNER := google -LOCAL_STATIC_JAVA_LIBRARIES := guava android-common -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java b/sl4a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java deleted file mode 100644 index 3e6956d..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/ConvertUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -public class ConvertUtils { - /** - * Converts a String of comma separated bytes to a byte array - * - * @param value The value to convert - * @return the byte array - */ - public static byte[] convertStringToByteArray(String value) { - if (value.equals("")) { - return new byte[0]; - } - String[] parseString = value.split(","); - byte[] byteArray = new byte[parseString.length]; - if (byteArray.length > 0) { - for (int i = 0; i < parseString.length; i++) { - byte byteValue = Byte.valueOf(parseString[i].trim()); - byteArray[i] = byteValue; - } - } - return byteArray; - } - - /** - * Converts a byte array to a comma separated String - * - * @param byteArray - * @return comma separated string of bytes - */ - public static String convertByteArrayToString(byte[] byteArray) { - String ret = ""; - if (byteArray != null) { - for (int i = 0; i < byteArray.length; i++) { - if ((i + 1) != byteArray.length) { - ret = ret + Byte.valueOf(byteArray[i]) + ","; - } - else { - ret = ret + Byte.valueOf(byteArray[i]); - } - } - } - return ret; - } - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/FileUtils.java b/sl4a/Utils/src/com/googlecode/android_scripting/FileUtils.java deleted file mode 100644 index 91abc2c..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/FileUtils.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.content.res.AssetManager; -import android.os.Environment; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.lang.reflect.Method; - -/** - * Utility functions for handling files. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class FileUtils { - - private FileUtils() { - // Utility class. - } - - static public boolean externalStorageMounted() { - String state = Environment.getExternalStorageState(); - return Environment.MEDIA_MOUNTED.equals(state) - || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state); - } - - public static int chmod(File path, int mode) throws Exception { - Class<?> fileUtils = Class.forName("android.os.FileUtils"); - Method setPermissions = - fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class); - return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1); - } - - public static boolean recursiveChmod(File root, int mode) throws Exception { - boolean success = chmod(root, mode) == 0; - for (File path : root.listFiles()) { - if (path.isDirectory()) { - success = recursiveChmod(path, mode); - } - success &= (chmod(path, mode) == 0); - } - return success; - } - - public static boolean delete(File path) { - boolean result = true; - if (path.exists()) { - if (path.isDirectory()) { - for (File child : path.listFiles()) { - result &= delete(child); - } - result &= path.delete(); // Delete empty directory. - } - if (path.isFile()) { - result &= path.delete(); - } - if (!result) { - Log.e("Delete failed;"); - } - return result; - } else { - Log.e("File does not exist."); - return false; - } - } - - public static File copyFromStream(String name, InputStream input) { - if (name == null || name.length() == 0) { - Log.e("No script name specified."); - return null; - } - File file = new File(name); - if (!makeDirectories(file.getParentFile(), 0755)) { - return null; - } - try { - OutputStream output = new FileOutputStream(file); - IoUtils.copy(input, output); - } catch (Exception e) { - Log.e(e); - return null; - } - return file; - } - - public static boolean makeDirectories(File directory, int mode) { - File parent = directory; - while (parent.getParentFile() != null && !parent.exists()) { - parent = parent.getParentFile(); - } - if (!directory.exists()) { - Log.v("Creating directory: " + directory.getName()); - if (!directory.mkdirs()) { - Log.e("Failed to create directory."); - return false; - } - } - try { - recursiveChmod(parent, mode); - } catch (Exception e) { - Log.e(e); - return false; - } - return true; - } - - public static File getExternalDownload() { - try { - Class<?> c = Class.forName("android.os.Environment"); - Method m = c.getDeclaredMethod("getExternalStoragePublicDirectory", String.class); - String download = c.getDeclaredField("DIRECTORY_DOWNLOADS").get(null).toString(); - return (File) m.invoke(null, download); - } catch (Exception e) { - return new File(Environment.getExternalStorageDirectory(), "Download"); - } - } - - public static boolean rename(File file, String name) { - return file.renameTo(new File(file.getParent(), name)); - } - - public static String readToString(File file) throws IOException { - if (file == null || !file.exists()) { - return null; - } - FileReader reader = new FileReader(file); - StringBuilder out = new StringBuilder(); - char[] buffer = new char[1024 * 4]; - int numRead = 0; - while ((numRead = reader.read(buffer)) > -1) { - out.append(String.valueOf(buffer, 0, numRead)); - } - reader.close(); - return out.toString(); - } - - public static String readFromAssetsFile(Context context, String name) throws IOException { - AssetManager am = context.getAssets(); - BufferedReader reader = new BufferedReader(new InputStreamReader(am.open(name))); - String line; - StringBuilder builder = new StringBuilder(); - while ((line = reader.readLine()) != null) { - builder.append(line); - } - reader.close(); - return builder.toString(); - } - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/ForegroundService.java b/sl4a/Utils/src/com/googlecode/android_scripting/ForegroundService.java deleted file mode 100644 index 64fbe24..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/ForegroundService.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.Service; - -import java.lang.reflect.Method; - -public abstract class ForegroundService extends Service { - private static final Class<?>[] mStartForegroundSignature = - new Class[] { int.class, Notification.class }; - private static final Class<?>[] mStopForegroundSignature = new Class[] { boolean.class }; - - private final int mNotificationId; - - private NotificationManager mNotificationManager; - private Method mStartForeground; - private Method mStopForeground; - private Object[] mStartForegroundArgs = new Object[2]; - private Object[] mStopForegroundArgs = new Object[1]; - - public ForegroundService(int id) { - mNotificationId = id; - } - - protected abstract Notification createNotification(); - - /** - * This is a wrapper around the new startForeground method, using the older APIs if it is not - * available. - */ - private void startForegroundCompat(Notification notification) { - // If we have the new startForeground API, then use it. - if (mStartForeground != null) { - mStartForegroundArgs[0] = Integer.valueOf(mNotificationId); - mStartForegroundArgs[1] = notification; - try { - mStartForeground.invoke(this, mStartForegroundArgs); - } catch (Exception e) { - Log.e(e); - } - return; - } - - // Fall back on the old API. - setForeground(true); - if (notification != null) { - mNotificationManager.notify(mNotificationId, notification); - } - } - - /** - * This is a wrapper around the new stopForeground method, using the older APIs if it is not - * available. - */ - private void stopForegroundCompat() { - // If we have the new stopForeground API, then use it. - if (mStopForeground != null) { - mStopForegroundArgs[0] = Boolean.TRUE; - try { - mStopForeground.invoke(this, mStopForegroundArgs); - } catch (Exception e) { - Log.e(e); - } - return; - } - - // Fall back on the old API. Note to cancel BEFORE changing the - // foreground state, since we could be killed at that point. - mNotificationManager.cancel(mNotificationId); - setForeground(false); - } - - @Override - public void onCreate() { - mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - try { - mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature); - mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature); - } catch (NoSuchMethodException e) { - // Running on an older platform. - mStartForeground = mStopForeground = null; - } - startForegroundCompat(createNotification()); - } - - @Override - public void onDestroy() { - // Make sure our notification is gone. - stopForegroundCompat(); - } -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/IoUtils.java b/sl4a/Utils/src/com/googlecode/android_scripting/IoUtils.java deleted file mode 100644 index 0fd0ca0..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/IoUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class IoUtils { - private static final int BUFFER_SIZE = 1024 * 8; - - private IoUtils() { - // Utility class. - } - - public static int copy(InputStream input, OutputStream output) throws Exception, IOException { - byte[] buffer = new byte[BUFFER_SIZE]; - - BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE); - BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE); - int count = 0, n = 0; - try { - while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) { - out.write(buffer, 0, n); - count += n; - } - out.flush(); - } finally { - try { - out.close(); - } catch (IOException e) { - Log.e(e.getMessage(), e); - } - try { - in.close(); - } catch (IOException e) { - Log.e(e.getMessage(), e); - } - } - return count; - } - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/Log.java b/sl4a/Utils/src/com/googlecode/android_scripting/Log.java deleted file mode 100644 index 4947a0c..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/Log.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.app.AlertDialog; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.DialogInterface; -import android.widget.Toast; - -public class Log { - private Log() { - // Utility class. - } - - private static String getTag() { - StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); - String fullClassName = stackTraceElements[4].getClassName(); - String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1); - int lineNumber = stackTraceElements[4].getLineNumber(); - return "sl4a." + className + ":" + lineNumber; - } - - private static void toast(Context context, String message) { - Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); - } - - public static void notify(Context context, String title, String contentTitle, String message) { - android.util.Log.v(getTag(), String.format("%s %s", contentTitle, message)); - - String packageName = context.getPackageName(); - int iconId = context.getResources().getIdentifier("stat_sys_warning", "drawable", packageName); - NotificationManager notificationManager = - (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); - Notification.Builder builder = new Notification.Builder(context); - builder.setSmallIcon(iconId > 0 ? iconId : -1) - .setTicker(title) - .setWhen(0) - .setContentTitle(contentTitle) - .setContentText(message) - .setContentIntent(PendingIntent.getService(context, 0, null, 0)); - Notification note = builder.build(); - note.contentView.getLayoutId(); - notificationManager.notify(NotificationIdFactory.create(), note); - } - - public static void showDialog(final Context context, final String title, final String message) { - android.util.Log.v(getTag(), String.format("%s %s", title, message)); - - MainThread.run(context, new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(title); - builder.setMessage(message); - - DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }; - builder.setPositiveButton("Ok", buttonListener); - builder.show(); - } - }); - } - - public static void v(String message) { - android.util.Log.v(getTag(), message); - } - - public static void v(String message, Throwable e) { - android.util.Log.v(getTag(), message, e); - } - - public static void v(Context context, String message) { - toast(context, message); - android.util.Log.v(getTag(), message); - } - - public static void v(Context context, String message, Throwable e) { - toast(context, message); - android.util.Log.v(getTag(), message, e); - } - - public static void e(Throwable e) { - android.util.Log.e(getTag(), "Error", e); - } - - public static void e(String message) { - android.util.Log.e(getTag(), message); - } - - public static void e(String message, Throwable e) { - android.util.Log.e(getTag(), message, e); - } - - public static void e(Context context, String message) { - toast(context, message); - android.util.Log.e(getTag(), message); - } - - public static void e(Context context, String message, Throwable e) { - toast(context, message); - android.util.Log.e(getTag(), message, e); - } - - public static void w(Throwable e) { - android.util.Log.w(getTag(), "Warning", e); - } - - public static void w(String message) { - android.util.Log.w(getTag(), message); - } - - public static void w(String message, Throwable e) { - android.util.Log.w(getTag(), message, e); - } - - public static void w(Context context, String message) { - toast(context, message); - android.util.Log.w(getTag(), message); - } - - public static void w(Context context, String message, Throwable e) { - toast(context, message); - android.util.Log.w(getTag(), message, e); - } - - public static void d(String message) { - android.util.Log.d(getTag(), message); - } - - public static void d(String message, Throwable e) { - android.util.Log.d(getTag(), message, e); - } - - public static void d(Context context, String message) { - toast(context, message); - android.util.Log.d(getTag(), message); - } - - public static void d(Context context, String message, Throwable e) { - toast(context, message); - android.util.Log.d(getTag(), message, e); - } - - public static void i(String message) { - android.util.Log.i(getTag(), message); - } - - public static void i(String message, Throwable e) { - android.util.Log.i(getTag(), message, e); - } - - public static void i(Context context, String message) { - toast(context, message); - android.util.Log.i(getTag(), message); - } - - public static void i(Context context, String message, Throwable e) { - toast(context, message); - android.util.Log.i(getTag(), message, e); - } -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/MainThread.java b/sl4a/Utils/src/com/googlecode/android_scripting/MainThread.java deleted file mode 100644 index 840c1e7..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/MainThread.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import android.content.Context; -import android.os.Handler; - -import com.googlecode.android_scripting.future.FutureResult; - -import java.util.concurrent.Callable; - -public class MainThread { - - private MainThread() { - // Utility class. - } - - /** - * Executed in the main thread, returns the result of an execution. Anything that runs here should - * finish quickly to avoid hanging the UI thread. - */ - public static <T> T run(Context context, final Callable<T> task) { - final FutureResult<T> result = new FutureResult<T>(); - Handler handler = new Handler(context.getMainLooper()); - handler.post(new Runnable() { - @Override - public void run() { - try { - result.set(task.call()); - } catch (Exception e) { - Log.e(e); - result.set(null); - } - } - }); - try { - return result.get(); - } catch (InterruptedException e) { - Log.e(e); - } - return null; - } - - public static void run(Context context, final Runnable task) { - Handler handler = new Handler(context.getMainLooper()); - handler.post(new Runnable() { - @Override - public void run() { - task.run(); - } - }); - } -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/NotificationIdFactory.java b/sl4a/Utils/src/com/googlecode/android_scripting/NotificationIdFactory.java deleted file mode 100644 index c87d94d..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/NotificationIdFactory.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Creates unique ids to identify the notifications created by the android scripting service and the - * trigger service. - * - * @author Felix Arends (felix.arends@gmail.com) - * - */ -public final class NotificationIdFactory { - private static final AtomicInteger mNextId = new AtomicInteger(0); - - public static int create() { - return mNextId.incrementAndGet(); - } - - private NotificationIdFactory() { - } -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/SimpleServer.java b/sl4a/Utils/src/com/googlecode/android_scripting/SimpleServer.java deleted file mode 100644 index b93b6cb..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/SimpleServer.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import com.google.common.collect.Lists; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.net.BindException; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.SocketException; -import java.net.UnknownHostException; -import java.util.Collections; -import java.util.Enumeration; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -//import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; - -/** - * A simple server. - * @author Damon Kohler (damonkohler@gmail.com) - */ -public abstract class SimpleServer { - private static int threadIndex = 0; - private final ConcurrentHashMap<Integer, ConnectionThread> mConnectionThreads = - new ConcurrentHashMap<Integer, ConnectionThread>(); - private final List<SimpleServerObserver> mObservers = Lists.newArrayList(); - private volatile boolean mStopServer = false; - private ServerSocket mServer; - private Thread mServerThread; - - public interface SimpleServerObserver { - public void onConnect(); - public void onDisconnect(); - } - - protected abstract void handleConnection(Socket socket) throws Exception; - protected abstract void handleRPCConnection(Socket socket, - Integer UID, - BufferedReader reader, - PrintWriter writer) throws Exception; - - /** Adds an observer. */ - public void addObserver(SimpleServerObserver observer) { - mObservers.add(observer); - } - - /** Removes an observer. */ - public void removeObserver(SimpleServerObserver observer) { - mObservers.remove(observer); - } - - private void notifyOnConnect() { - for (SimpleServerObserver observer : mObservers) { - observer.onConnect(); - } - } - - private void notifyOnDisconnect() { - for (SimpleServerObserver observer : mObservers) { - observer.onDisconnect(); - } - } - - private final class ConnectionThread extends Thread { - private final Socket mmSocket; - private final BufferedReader reader; - private final PrintWriter writer; - private final Integer UID; - private final boolean isRpc; - - private ConnectionThread(Socket socket, boolean rpc, Integer uid, BufferedReader reader, PrintWriter writer) { - setName("SimpleServer ConnectionThread " + getId()); - mmSocket = socket; - this.UID = uid; - this.reader = reader; - this.writer = writer; - this.isRpc = rpc; - } - - @Override - public void run() { - Log.v("Server thread " + getId() + " started."); - try { - if(isRpc) { - Log.d("Handling RPC connection in "+getId()); - handleRPCConnection(mmSocket, UID, reader, writer); - }else{ - Log.d("Handling Non-RPC connection in "+getId()); - handleConnection(mmSocket); - } - } catch (Exception e) { - if (!mStopServer) { - Log.e("Server error.", e); - } - } finally { - close(); - mConnectionThreads.remove(this.UID); - notifyOnDisconnect(); - Log.v("Server thread " + getId() + " stopped."); - } - } - - private void close() { - if (mmSocket != null) { - try { - mmSocket.close(); - } catch (IOException e) { - Log.e(e.getMessage(), e); - } - } - } - } - - /** Returns the number of active connections to this server. */ - public int getNumberOfConnections() { - return mConnectionThreads.size(); - } - - public static InetAddress getPrivateInetAddress() throws UnknownHostException, SocketException { - - InetAddress candidate = null; - Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); - for (NetworkInterface netint : Collections.list(nets)) { - if (!netint.isLoopback() || !netint.isUp()) { // Ignore if localhost or not active - continue; - } - Enumeration<InetAddress> addresses = netint.getInetAddresses(); - for (InetAddress address : Collections.list(addresses)) { - if (address instanceof Inet4Address) { - Log.d("local address " + address); - return address; // Prefer ipv4 - } - candidate = address; // Probably an ipv6 - } - } - if (candidate != null) { - return candidate; // return ipv6 address if no suitable ipv6 - } - return InetAddress.getLocalHost(); // No damn matches. Give up, return local host. - } - - public static InetAddress getPublicInetAddress() throws UnknownHostException, SocketException { - - InetAddress candidate = null; - Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); - for (NetworkInterface netint : Collections.list(nets)) { - if (netint.isLoopback() || !netint.isUp()) { // Ignore if localhost or not active - continue; - } - Enumeration<InetAddress> addresses = netint.getInetAddresses(); - for (InetAddress address : Collections.list(addresses)) { - if (address instanceof Inet4Address) { - return address; // Prefer ipv4 - } - candidate = address; // Probably an ipv6 - } - } - if (candidate != null) { - return candidate; // return ipv6 address if no suitable ipv6 - } - return InetAddress.getLocalHost(); // No damn matches. Give up, return local host. - } - - /** - * Starts the RPC server bound to the localhost address. - * - * @param port - * the port to bind to or 0 to pick any unused port - * - * @return the port that the server is bound to - * @throws IOException - */ - public InetSocketAddress startLocal(int port) { - InetAddress address; - try { - // address = InetAddress.getLocalHost(); - address = getPrivateInetAddress(); - mServer = new ServerSocket(port, 5, address); - } catch (BindException e) { - Log.e("Port " + port + " already in use."); - try { - address = getPrivateInetAddress(); - mServer = new ServerSocket(0, 5, address); - } catch (IOException e1) { - e1.printStackTrace(); - return null; - } - } catch (Exception e) { - Log.e("Failed to start server.", e); - return null; - } - int boundPort = start(); - return InetSocketAddress.createUnresolved(mServer.getInetAddress().getHostAddress(), boundPort); - } - - /** - * data Starts the RPC server bound to the public facing address. - * - * @param port - * the port to bind to or 0 to pick any unused port - * - * @return the port that the server is bound to - */ - public InetSocketAddress startPublic(int port) { - InetAddress address; - try { - // address = getPublicInetAddress(); - address = null; - mServer = new ServerSocket(port, 5 /* backlog */, address); - } catch (Exception e) { - Log.e("Failed to start server.", e); - return null; - } - int boundPort = start(); - return InetSocketAddress.createUnresolved(mServer.getInetAddress().getHostAddress(), boundPort); - } - - /** - * data Starts the RPC server bound to all interfaces - * - * @param port - * the port to bind to or 0 to pick any unused port - * - * @return the port that the server is bound to - */ - public InetSocketAddress startAllInterfaces(int port) { - try { - mServer = new ServerSocket(port, 5 /* backlog */); - } catch (Exception e) { - Log.e("Failed to start server.", e); - return null; - } - int boundPort = start(); - return InetSocketAddress.createUnresolved(mServer.getInetAddress().getHostAddress(), boundPort); - } - - private int start() { - mServerThread = new Thread() { - @Override - public void run() { - while (!mStopServer) { - try { - Socket sock = mServer.accept(); - if (!mStopServer) { - startConnectionThread(sock); - } else { - sock.close(); - } - } catch (IOException e) { - if (!mStopServer) { - Log.e("Failed to accept connection.", e); - } - } catch (JSONException e) { - if (!mStopServer) { - Log.e("Failed to parse request.", e); - } - } - } - } - }; - mServerThread.start(); - Log.v("Bound to " + mServer.getInetAddress()); - return mServer.getLocalPort(); - } - - private void startConnectionThread(final Socket sock) throws IOException, JSONException { - BufferedReader reader = - new BufferedReader(new InputStreamReader(sock.getInputStream()), 8192); - PrintWriter writer = new PrintWriter(sock.getOutputStream(), true); - String data; - if((data = reader.readLine()) != null) { - Log.v("Received: " + data); - JSONObject request = new JSONObject(data); - if(request.has("cmd") && request.has("uid")) { - String cmd = request.getString("cmd"); - int uid = request.getInt("uid"); - JSONObject result = new JSONObject(); - if(cmd.equals("initiate")) { - Log.d("Initiate a new session"); - threadIndex += 1; - int mUID = threadIndex; - ConnectionThread networkThread = new ConnectionThread(sock,true,mUID,reader,writer); - mConnectionThreads.put(mUID, networkThread); - networkThread.start(); - notifyOnConnect(); - result.put("uid", mUID); - result.put("status",true); - result.put("error", null); - }else if(cmd.equals("continue")) { - Log.d("Continue an existing session"); - Log.d("keys: "+mConnectionThreads.keySet().toString()); - if(!mConnectionThreads.containsKey(uid)) { - result.put("uid", uid); - result.put("status",false); - result.put("error", "Session does not exist."); - }else{ - ConnectionThread networkThread = new ConnectionThread(sock,true,uid,reader,writer); - mConnectionThreads.put(uid, networkThread); - networkThread.start(); - notifyOnConnect(); - result.put("uid", uid); - result.put("status",true); - result.put("error", null); - } - }else { - result.put("uid", uid); - result.put("status",false); - result.put("error", "Unrecognized command."); - } - writer.write(result + "\n"); - writer.flush(); - Log.v("Sent: " + result); - }else{ - ConnectionThread networkThread = new ConnectionThread(sock,false,0,reader,writer); - mConnectionThreads.put(0, networkThread); - networkThread.start(); - notifyOnConnect(); - } - } - } - - public void shutdown() { - // Stop listening on the server socket to ensure that - // beyond this point there are no incoming requests. - mStopServer = true; - try { - mServer.close(); - } catch (IOException e) { - Log.e("Failed to close server socket.", e); - } - // Since the server is not running, the mNetworkThreads set can only - // shrink from this point onward. We can just stop all of the running helper - // threads. In the worst case, one of the running threads will already have - // shut down. Since this is a CopyOnWriteList, we don't have to worry about - // concurrency issues while iterating over the set of threads. - for (ConnectionThread connectionThread : mConnectionThreads.values()) { - connectionThread.close(); - } - for (SimpleServerObserver observer : mObservers) { - removeObserver(observer); - } - } -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/SingleThreadExecutor.java b/sl4a/Utils/src/com/googlecode/android_scripting/SingleThreadExecutor.java deleted file mode 100644 index 7c5b1c5..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/SingleThreadExecutor.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting; - -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -public class SingleThreadExecutor extends ThreadPoolExecutor { - - public SingleThreadExecutor() { - super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); - } - - @Override - protected void afterExecute(Runnable r, Throwable t) { - if (t != null) { - throw new RuntimeException(t); - } - } -}
\ No newline at end of file diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/exception/Sl4aException.java b/sl4a/Utils/src/com/googlecode/android_scripting/exception/Sl4aException.java deleted file mode 100644 index 2f85b4b..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/exception/Sl4aException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.exception; - -@SuppressWarnings("serial") -public class Sl4aException extends Exception { - - public Sl4aException(Exception e) { - super(e); - } - - public Sl4aException(String message) { - super(message); - } - - public Sl4aException(String message, Exception e) { - super(message, e); - } - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/future/FutureResult.java b/sl4a/Utils/src/com/googlecode/android_scripting/future/FutureResult.java deleted file mode 100644 index 573424c..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/future/FutureResult.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.future; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -/** - * FutureResult represents an eventual execution result for asynchronous operations. - * - * @author Damon Kohler (damonkohler@gmail.com) - */ -public class FutureResult<T> implements Future<T> { - - private final CountDownLatch mLatch = new CountDownLatch(1); - private volatile T mResult = null; - - public void set(T result) { - mResult = result; - mLatch.countDown(); - } - - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public T get() throws InterruptedException { - mLatch.await(); - return mResult; - } - - @Override - public T get(long timeout, TimeUnit unit) throws InterruptedException { - mLatch.await(timeout, unit); - return mResult; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return mResult != null; - } - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/ExternalClassLoader.java b/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/ExternalClassLoader.java deleted file mode 100644 index 3bbe349..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/ExternalClassLoader.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import dalvik.system.DexClassLoader; - -import java.util.Collection; -import java.util.Iterator; - -public class ExternalClassLoader { - - public Object load(Collection<String> dexPaths, Collection<String> nativePaths, String className) - throws Exception { - String dexOutputDir = "/sdcard/dexoutput"; - String joinedDexPaths = join(dexPaths, ":"); - String joinedNativeLibPaths = nativePaths != null ? join(nativePaths, ":") : null; - DexClassLoader loader = - new DexClassLoader(joinedDexPaths, dexOutputDir, joinedNativeLibPaths, this.getClass() - .getClassLoader()); - Class<?> classToLoad = Class.forName(className, true, loader); - return classToLoad.newInstance(); - } - - private static String join(Collection<String> collection, String delimiter) { - StringBuffer buffer = new StringBuffer(); - Iterator<String> iter = collection.iterator(); - while (iter.hasNext()) { - buffer.append(iter.next()); - if (iter.hasNext()) { - buffer.append(delimiter); - } - } - return buffer.toString(); - } -}
\ No newline at end of file diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterConstants.java b/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterConstants.java deleted file mode 100644 index cf4667a..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterConstants.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.os.Environment; - -/** - * A collection of constants required for installation/removal of an interpreter. - * - * @author Damon Kohler (damonkohler@gmail.com) - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public interface InterpreterConstants { - - public static final String SDCARD_ROOT = - Environment.getExternalStorageDirectory().getAbsolutePath() + "/"; - - public static final String SDCARD_SL4A_ROOT = SDCARD_ROOT + "sl4a/"; - - public static final String SCRIPTS_ROOT = SDCARD_SL4A_ROOT + "scripts/"; - - public static final String SDCARD_SL4A_DOC = SDCARD_SL4A_ROOT + "doc/"; - - public static final String SL4A_DALVIK_CACHE_ROOT = "/dalvik-cache/"; - - public static final String INTERPRETER_EXTRAS_ROOT = "/extras/"; - - // Interpreters discovery mechanism. - public static final String ACTION_DISCOVER_INTERPRETERS = - "com.googlecode.android_scripting.DISCOVER_INTERPRETERS"; - - // Interpreters broadcasts. - public static final String ACTION_INTERPRETER_ADDED = - "com.googlecode.android_scripting.INTERPRETER_ADDED"; - public static final String ACTION_INTERPRETER_REMOVED = - "com.googlecode.android_scripting.INTERPRETER_REMOVED"; - - // Interpreter content provider. - public static final String PROVIDER_PROPERTIES = "com.googlecode.android_scripting.base"; - public static final String PROVIDER_ENVIRONMENT_VARIABLES = - "com.googlecode.android_scripting.env"; - public static final String PROVIDER_ARGUMENTS = "com.googlecode.android_scripting.args"; - - public static final String INSTALLED_PREFERENCE_KEY = "SL4A.interpreter.installed"; - - public static final String MIME = "script/"; -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterDescriptor.java b/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterDescriptor.java deleted file mode 100644 index 519798c..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterDescriptor.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.content.Context; - -import java.io.File; -import java.util.List; -import java.util.Map; - -/** - * Provides interpreter-specific info for execution/installation/removal purposes. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public interface InterpreterDescriptor { - - /** - * Returns unique name of the interpreter. - */ - public String getName(); - - /** - * Returns display name of the interpreter. - */ - public String getNiceName(); - - /** - * Returns supported script-file extension. - */ - public String getExtension(); - - /** - * Returns interpreter version number. - */ - public int getVersion(); - - /** - * Returns the binary as a File object. Context is the InterpreterProvider's {@link Context} and - * is provided to find the interpreter installation directory. - */ - public File getBinary(Context context); - - /** - * Returns execution parameters in case when script name is not provided (when interpreter is - * started in a shell mode); - */ - public String getInteractiveCommand(Context context); - - /** - * Returns command line arguments to execute a with a given script (format string with one - * argument). - */ - public String getScriptCommand(Context context); - - /** - * Returns an array of command line arguments required to execute the interpreter (it's essential - * that the order in the array is consistent with order of arguments in the command line). - */ - public List<String> getArguments(Context context); - - /** - * Should return a map of environment variables names and their values (or null if interpreter - * does not require any environment variables). - */ - public Map<String, String> getEnvironmentVariables(Context context); - - /** - * Returns true if interpreter has an archive. - */ - public boolean hasInterpreterArchive(); - - /** - * Returns true if interpreter has an extras archive. - */ - public boolean hasExtrasArchive(); - - /** - * Returns true if interpreter comes with a scripts archive. - */ - public boolean hasScriptsArchive(); - - /** - * Returns file name of the interpreter archive. - */ - public String getInterpreterArchiveName(); - - /** - * Returns file name of the extras archive. - */ - public String getExtrasArchiveName(); - - /** - * Returns file name of the scripts archive. - */ - public String getScriptsArchiveName(); - - /** - * Returns URL location of the interpreter archive. - */ - public String getInterpreterArchiveUrl(); - - /** - * Returns URL location of the scripts archive. - */ - public String getScriptsArchiveUrl(); - - /** - * Returns URL location of the extras archive. - */ - public String getExtrasArchiveUrl(); - - /** - * Returns true if interpreter can be executed in interactive mode. - */ - public boolean hasInteractiveMode(); -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterPropertyNames.java b/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterPropertyNames.java deleted file mode 100644 index b8995a7..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterPropertyNames.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -/** - * A collection of {@link String} keys for querying an InterpreterProvider. - * - * @author Alexey Reznichenko (alexey.reznichenko@gmail.com) - */ -public interface InterpreterPropertyNames { - - /** - * Unique name of the interpreter. - */ - public static final String NAME = "name"; - - /** - * Display name of the interpreter. - */ - public static final String NICE_NAME = "niceName"; - - /** - * Supported script file extension. - */ - public static final String EXTENSION = "extension"; - - /** - * Absolute path of the interpreter executable. - */ - public static final String BINARY = "binary"; - - /** - * Final argument to interpreter binary when running the interpreter interactively. - */ - public static final String INTERACTIVE_COMMAND = "interactiveCommand"; - - /** - * Final argument to interpreter binary when running a script. - */ - public static final String SCRIPT_COMMAND = "scriptCommand"; - - /** - * Interpreter interactive mode flag. - */ - public static final String HAS_INTERACTIVE_MODE = "hasInteractiveMode"; - -} diff --git a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterUtils.java b/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterUtils.java deleted file mode 100644 index df81261..0000000 --- a/sl4a/Utils/src/com/googlecode/android_scripting/interpreter/InterpreterUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.googlecode.android_scripting.interpreter; - -import android.content.Context; - -import java.io.File; - -public class InterpreterUtils { - - private InterpreterUtils() { - // Utility class - } - - public static File getInterpreterRoot(Context context) { - return context.getFilesDir(); - } - - public static File getInterpreterRoot(Context context, String interpreterName) { - return new File(getInterpreterRoot(context), interpreterName); - } -} diff --git a/sl4a/Utils/src/com/trilead/ssh2/StreamGobbler.java b/sl4a/Utils/src/com/trilead/ssh2/StreamGobbler.java deleted file mode 100644 index 2d67337..0000000 --- a/sl4a/Utils/src/com/trilead/ssh2/StreamGobbler.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2016 Google Inc. - * - * 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 com.trilead.ssh2; - -import com.googlecode.android_scripting.Log; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; - -/** - * A <code>StreamGobbler</code> is an InputStream that uses an internal worker thread to constantly - * consume input from another InputStream. It uses a buffer to store the consumed data. The buffer - * size is automatically adjusted, if needed. - * <p> - * This class is sometimes very convenient - if you wrap a session's STDOUT and STDERR InputStreams - * with instances of this class, then you don't have to bother about the shared window of STDOUT and - * STDERR in the low level SSH-2 protocol, since all arriving data will be immediatelly consumed by - * the worker threads. Also, as a side effect, the streams will be buffered (e.g., single byte - * read() operations are faster). - * <p> - * Other SSH for Java libraries include this functionality by default in their STDOUT and STDERR - * InputStream implementations, however, please be aware that this approach has also a downside: - * <p> - * If you do not call the StreamGobbler's <code>read()</code> method often enough and the peer is - * constantly sending huge amounts of data, then you will sooner or later encounter a low memory - * situation due to the aggregated data (well, it also depends on the Java heap size). Joe Average - * will like this class anyway - a paranoid programmer would never use such an approach. - * <p> - * The term "StreamGobbler" was taken from an article called "When Runtime.exec() won't", see - * http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html. - * - * @author Christian Plattner, plattner@trilead.com - * @version $Id: StreamGobbler.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $ - */ - -public class StreamGobbler extends InputStream { - class GobblerThread extends Thread { - @Override - public void run() { - - while (true) { - try { - byte[] saveBuffer = null; - - int avail = is.read(buffer, write_pos, buffer.length - write_pos); - - synchronized (synchronizer) { - if (avail <= 0) { - isEOF = true; - synchronizer.notifyAll(); - break; - } - write_pos += avail; - - int space_available = buffer.length - write_pos; - - if (space_available == 0) { - if (read_pos > 0) { - saveBuffer = new byte[read_pos]; - System.arraycopy(buffer, 0, saveBuffer, 0, read_pos); - System.arraycopy(buffer, read_pos, buffer, 0, buffer.length - read_pos); - write_pos -= read_pos; - read_pos = 0; - } else { - write_pos = 0; - saveBuffer = buffer; - } - } - - synchronizer.notifyAll(); - } - - writeToFile(saveBuffer); - - } catch (IOException e) { - synchronized (synchronizer) { - exception = e; - synchronizer.notifyAll(); - break; - } - } - } - } - } - - private InputStream is; - private GobblerThread t; - - private Object synchronizer = new Object(); - - private boolean isEOF = false; - private boolean isClosed = false; - private IOException exception = null; - - private byte[] buffer; - private int read_pos = 0; - private int write_pos = 0; - private final FileOutputStream mLogStream; - private final int mBufferSize; - - public StreamGobbler(InputStream is, File log, int buffer_size) { - this.is = is; - mBufferSize = buffer_size; - FileOutputStream out = null; - try { - out = new FileOutputStream(log, false); - } catch (IOException e) { - Log.e(e); - } - mLogStream = out; - buffer = new byte[mBufferSize]; - t = new GobblerThread(); - t.setDaemon(true); - t.start(); - } - - public void writeToFile(byte[] buffer) { - if (mLogStream != null && buffer != null) { - try { - mLogStream.write(buffer); - } catch (IOException e) { - Log.e(e); - } - } - } - - @Override - public int read() throws IOException { - synchronized (synchronizer) { - if (isClosed) { - throw new IOException("This StreamGobbler is closed."); - } - - while (read_pos == write_pos) { - if (exception != null) { - throw exception; - } - - if (isEOF) { - return -1; - } - - try { - synchronizer.wait(); - } catch (InterruptedException e) { - } - } - - int b = buffer[read_pos++] & 0xff; - - return b; - } - } - - @Override - public int available() throws IOException { - synchronized (synchronizer) { - if (isClosed) { - throw new IOException("This StreamGobbler is closed."); - } - - return write_pos - read_pos; - } - } - - @Override - public int read(byte[] b) throws IOException { - return read(b, 0, b.length); - } - - @Override - public void close() throws IOException { - synchronized (synchronizer) { - if (isClosed) { - return; - } - isClosed = true; - isEOF = true; - synchronizer.notifyAll(); - is.close(); - } - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (b == null) { - throw new NullPointerException(); - } - - if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length)) { - throw new IndexOutOfBoundsException(); - } - - if (len == 0) { - return 0; - } - - synchronized (synchronizer) { - if (isClosed) { - throw new IOException("This StreamGobbler is closed."); - } - - while (read_pos == write_pos) { - if (exception != null) { - throw exception; - } - - if (isEOF) { - return -1; - } - - try { - synchronizer.wait(); - } catch (InterruptedException e) { - } - } - - int avail = write_pos - read_pos; - - avail = (avail > len) ? len : avail; - - System.arraycopy(buffer, read_pos, b, off, avail); - - read_pos += avail; - - return avail; - } - } -} |