summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/os/FileUtils.java14
-rw-r--r--core/java/android/os/UserManager.java2
-rw-r--r--core/java/android/webkit/AccessibilityInjector.java127
-rw-r--r--core/java/android/webkit/WebViewClassic.java14
-rw-r--r--core/java/com/android/internal/widget/RotarySelector.java15
-rw-r--r--core/java/com/android/internal/widget/SlidingTab.java15
-rw-r--r--core/java/com/android/internal/widget/WaveView.java15
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/GlowPadView.java7
-rw-r--r--core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java7
9 files changed, 153 insertions, 63 deletions
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 0941d71..2bec1c1 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,6 +16,7 @@
package android.os;
+import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -91,7 +92,7 @@ public class FileUtils {
}
return result;
}
-
+
/**
* Copy data from a source stream to destFile.
* Return true if succeed, return false if failed.
@@ -143,12 +144,16 @@ public class FileUtils {
*/
public static String readTextFile(File file, int max, String ellipsis) throws IOException {
InputStream input = new FileInputStream(file);
+ // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
+ // input stream, bytes read not equal to buffer size is not necessarily the correct
+ // indication for EOF; but it is true for BufferedInputStream due to its implementation.
+ BufferedInputStream bis = new BufferedInputStream(input);
try {
long size = file.length();
if (max > 0 || (size > 0 && max == 0)) { // "head" mode: read the first N bytes
if (size > 0 && (max == 0 || size < max)) max = (int) size;
byte[] data = new byte[max + 1];
- int length = input.read(data);
+ int length = bis.read(data);
if (length <= 0) return "";
if (length <= max) return new String(data, 0, length);
if (ellipsis == null) return new String(data, 0, max);
@@ -161,7 +166,7 @@ public class FileUtils {
if (last != null) rolled = true;
byte[] tmp = last; last = data; data = tmp;
if (data == null) data = new byte[-max];
- len = input.read(data);
+ len = bis.read(data);
} while (len == data.length);
if (last == null && len <= 0) return "";
@@ -178,12 +183,13 @@ public class FileUtils {
int len;
byte[] data = new byte[1024];
do {
- len = input.read(data);
+ len = bis.read(data);
if (len > 0) contents.write(data, 0, len);
} while (len == data.length);
return contents.toString();
}
} finally {
+ bis.close();
input.close();
}
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 2739cac..898c766 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -320,6 +320,8 @@ public class UserManager {
* @return a value greater than or equal to 1
*/
public static int getMaxSupportedUsers() {
+ // Don't allow multiple users on certain builds
+ if (android.os.Build.ID.startsWith("JVP")) return 1;
return SystemProperties.getInt("fw.max_users",
Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
}
diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java
index 357a16e..fe5cad4 100644
--- a/core/java/android/webkit/AccessibilityInjector.java
+++ b/core/java/android/webkit/AccessibilityInjector.java
@@ -97,9 +97,12 @@ class AccessibilityInjector {
// Template for JavaScript that performs AndroidVox actions.
private static final String ACCESSIBILITY_ANDROIDVOX_TEMPLATE =
"(function() {" +
- " if ((typeof(cvox) != 'undefined')"+
+ " if ((typeof(cvox) != 'undefined')" +
+ " && (cvox != null)" +
" && (typeof(cvox.ChromeVox) != 'undefined')" +
+ " && (cvox.ChromeVox != null)" +
" && (typeof(cvox.AndroidVox) != 'undefined')" +
+ " && (cvox.AndroidVox != null)" +
" && cvox.ChromeVox.isActive) {" +
" return cvox.AndroidVox.performAction('%1s');" +
" } else {" +
@@ -110,9 +113,12 @@ class AccessibilityInjector {
// JS code used to shut down an active AndroidVox instance.
private static final String TOGGLE_CVOX_TEMPLATE =
"javascript:(function() {" +
- " if ((typeof(cvox) != 'undefined')"+
+ " if ((typeof(cvox) != 'undefined')" +
+ " && (cvox != null)" +
" && (typeof(cvox.ChromeVox) != 'undefined')" +
- " && (typeof(cvox.ChromeVox.host) != 'undefined')) {" +
+ " && (cvox.ChromeVox != null)" +
+ " && (typeof(cvox.ChromeVox.host) != 'undefined')" +
+ " && (cvox.ChromeVox.host != null)) {" +
" cvox.ChromeVox.host.activateOrDeactivateChromeVox(%b);" +
" }" +
"})();";
@@ -132,33 +138,60 @@ class AccessibilityInjector {
}
/**
+ * If JavaScript is enabled, pauses or resumes AndroidVox.
+ *
+ * @param enabled Whether feedback should be enabled.
+ */
+ public void toggleAccessibilityFeedback(boolean enabled) {
+ if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) {
+ return;
+ }
+
+ toggleAndroidVox(enabled);
+
+ if (!enabled && (mTextToSpeech != null)) {
+ mTextToSpeech.stop();
+ }
+ }
+
+ /**
* Attempts to load scripting interfaces for accessibility.
* <p>
- * This should be called when the window is attached.
- * </p>
+ * This should only be called before a page loads.
*/
- public void addAccessibilityApisIfNecessary() {
+ private void addAccessibilityApisIfNecessary() {
if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) {
return;
}
addTtsApis();
addCallbackApis();
- toggleAndroidVox(true);
}
/**
* Attempts to unload scripting interfaces for accessibility.
* <p>
- * This should be called when the window is detached.
- * </p>
+ * This should only be called before a page loads.
*/
- public void removeAccessibilityApisIfNecessary() {
- toggleAndroidVox(false);
+ private void removeAccessibilityApisIfNecessary() {
removeTtsApis();
removeCallbackApis();
}
+ /**
+ * Destroys this accessibility injector.
+ */
+ public void destroy() {
+ if (mTextToSpeech != null) {
+ mTextToSpeech.shutdown();
+ mTextToSpeech = null;
+ }
+
+ if (mCallback != null) {
+ mCallback = null;
+ }
+ }
+
private void toggleAndroidVox(boolean state) {
if (!mAccessibilityScriptInjected) {
return;
@@ -517,7 +550,12 @@ class AccessibilityInjector {
* settings.
*/
private boolean isJavaScriptEnabled() {
- return mWebView.getSettings().getJavaScriptEnabled();
+ final WebSettings settings = mWebView.getSettings();
+ if (settings == null) {
+ return false;
+ }
+
+ return settings.getJavaScriptEnabled();
}
/**
@@ -732,7 +770,7 @@ class AccessibilityInjector {
private final String mInterfaceName;
private boolean mResult = false;
- private long mResultId = -1;
+ private int mResultId = -1;
private CallbackHandler(String interfaceName) {
mInterfaceName = interfaceName;
@@ -784,34 +822,46 @@ class AccessibilityInjector {
* @return Whether the result was received.
*/
private boolean waitForResultTimedLocked(int resultId) {
- if (DEBUG)
- Log.d(TAG, "Waiting for CVOX result...");
- long waitTimeMillis = RESULT_TIMEOUT;
final long startTimeMillis = SystemClock.uptimeMillis();
+
+ if (DEBUG)
+ Log.d(TAG, "Waiting for CVOX result with ID " + resultId + "...");
+
while (true) {
+ // Fail if we received a callback from the future.
+ if (mResultId > resultId) {
+ if (DEBUG)
+ Log.w(TAG, "Aborted CVOX result");
+ return false;
+ }
+
+ final long elapsedTimeMillis = (SystemClock.uptimeMillis() - startTimeMillis);
+
+ // Succeed if we received the callback we were expecting.
+ if (DEBUG)
+ Log.w(TAG, "Check " + mResultId + " versus expected " + resultId);
+ if (mResultId == resultId) {
+ if (DEBUG)
+ Log.w(TAG, "Received CVOX result after " + elapsedTimeMillis + " ms");
+ return true;
+ }
+
+ final long waitTimeMillis = (RESULT_TIMEOUT - elapsedTimeMillis);
+
+ // Fail if we've already exceeded the timeout.
+ if (waitTimeMillis <= 0) {
+ if (DEBUG)
+ Log.w(TAG, "Timed out while waiting for CVOX result");
+ return false;
+ }
+
try {
- if (mResultId == resultId) {
- if (DEBUG)
- Log.w(TAG, "Received CVOX result");
- return true;
- }
- if (mResultId > resultId) {
- if (DEBUG)
- Log.w(TAG, "Obsolete CVOX result");
- return false;
- }
- final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
- waitTimeMillis = RESULT_TIMEOUT - elapsedTimeMillis;
- if (waitTimeMillis <= 0) {
- if (DEBUG)
- Log.w(TAG, "Timed out while waiting for CVOX result");
- return false;
- }
+ if (DEBUG)
+ Log.w(TAG, "Start waiting...");
mResultLock.wait(waitTimeMillis);
} catch (InterruptedException ie) {
if (DEBUG)
Log.w(TAG, "Interrupted while waiting for CVOX result");
- /* ignore */
}
}
}
@@ -827,11 +877,11 @@ class AccessibilityInjector {
@SuppressWarnings("unused")
public void onResult(String id, String result) {
if (DEBUG)
- Log.w(TAG, "Saw CVOX result of '" + result + "'");
- final long resultId;
+ Log.w(TAG, "Saw CVOX result of '" + result + "' for ID " + id);
+ final int resultId;
try {
- resultId = Long.parseLong(id);
+ resultId = Integer.parseInt(id);
} catch (NumberFormatException e) {
return;
}
@@ -840,6 +890,9 @@ class AccessibilityInjector {
if (resultId > mResultId) {
mResult = Boolean.parseBoolean(result);
mResultId = resultId;
+ } else {
+ if (DEBUG)
+ Log.w(TAG, "Result with ID " + resultId + " was stale vesus " + mResultId);
}
mResultLock.notifyAll();
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 7d0d0ba..0f8966e 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -2132,6 +2132,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private void destroyJava() {
mCallbackProxy.blockMessages();
+ if (mAccessibilityInjector != null) {
+ mAccessibilityInjector.destroy();
+ mAccessibilityInjector = null;
+ }
if (mWebViewCore != null) {
// Tell WebViewCore to destroy itself
synchronized (this) {
@@ -3967,8 +3971,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// null, and that will be the case
mWebView.setCertificate(null);
- // reset the flag since we set to true in if need after
- // loading is see onPageFinished(Url)
if (isAccessibilityInjectionEnabled()) {
getAccessibilityInjector().onPageStarted(url);
}
@@ -5397,7 +5399,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mWebView.hasWindowFocus()) setActive(true);
if (isAccessibilityInjectionEnabled()) {
- getAccessibilityInjector().addAccessibilityApisIfNecessary();
+ getAccessibilityInjector().toggleAccessibilityFeedback(true);
}
updateHwAccelerated();
@@ -5410,11 +5412,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mWebView.hasWindowFocus()) setActive(false);
if (isAccessibilityInjectionEnabled()) {
- getAccessibilityInjector().removeAccessibilityApisIfNecessary();
- } else {
- // Ensure the injector is cleared if we're detaching from the window
- // and accessibility is disabled.
- mAccessibilityInjector = null;
+ getAccessibilityInjector().toggleAccessibilityFeedback(false);
}
updateHwAccelerated();
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index a2a38dc..4e405f4 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -25,7 +25,9 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -667,11 +669,16 @@ public class RotarySelector extends View {
* Triggers haptic feedback.
*/
private synchronized void vibrate(long duration) {
- if (mVibrator == null) {
- mVibrator = (android.os.Vibrator)
- getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ final boolean hapticEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
+ if (hapticEnabled) {
+ if (mVibrator == null) {
+ mVibrator = (android.os.Vibrator) getContext()
+ .getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ mVibrator.vibrate(duration);
}
- mVibrator.vibrate(duration);
}
/**
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index f535a08..aebc4f6 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -21,7 +21,9 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
@@ -811,11 +813,16 @@ public class SlidingTab extends ViewGroup {
* Triggers haptic feedback.
*/
private synchronized void vibrate(long duration) {
- if (mVibrator == null) {
- mVibrator = (android.os.Vibrator)
- getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ final boolean hapticEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
+ if (hapticEnabled) {
+ if (mVibrator == null) {
+ mVibrator = (android.os.Vibrator) getContext()
+ .getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ mVibrator.vibrate(duration);
}
- mVibrator.vibrate(duration);
}
/**
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index 2d89234..d33d50c 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -25,7 +25,9 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -573,11 +575,16 @@ public class WaveView extends View implements ValueAnimator.AnimatorUpdateListen
* Triggers haptic feedback.
*/
private synchronized void vibrate(long duration) {
- if (mVibrator == null) {
- mVibrator = (android.os.Vibrator)
- getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ final boolean hapticEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
+ if (hapticEnabled) {
+ if (mVibrator == null) {
+ mVibrator = (android.os.Vibrator) getContext()
+ .getSystemService(Context.VIBRATOR_SERVICE);
+ }
+ mVibrator.vibrate(duration);
}
- mVibrator.vibrate(duration);
}
/**
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index f507a79..0f49776 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -31,7 +31,9 @@ import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -543,7 +545,10 @@ public class GlowPadView extends View {
}
private void vibrate() {
- if (mVibrator != null) {
+ final boolean hapticEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
+ if (mVibrator != null && hapticEnabled) {
mVibrator.vibrate(mVibrationDuration);
}
}
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index 7990b4c..e22d1e8 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -32,7 +32,9 @@ import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.UserHandle;
import android.os.Vibrator;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -593,7 +595,10 @@ public class MultiWaveView extends View {
}
private void vibrate() {
- if (mVibrator != null) {
+ final boolean hapticEnabled = Settings.System.getIntForUser(
+ mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
+ UserHandle.USER_CURRENT) != 0;
+ if (mVibrator != null && hapticEnabled) {
mVibrator.vibrate(mVibrationDuration);
}
}