diff options
Diffstat (limited to 'core/java')
17 files changed, 269 insertions, 140 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 182ebef..ee92646 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -896,6 +896,9 @@ public class Notification implements Parcelable /** {@hide} */ public void setUser(UserHandle user) { + if (user.getIdentifier() == UserHandle.USER_ALL) { + user = UserHandle.OWNER; + } if (tickerView != null) { tickerView.setUser(user); } diff --git a/core/java/android/app/Presentation.java b/core/java/android/app/Presentation.java index 3e8af60..16a0c57 100644 --- a/core/java/android/app/Presentation.java +++ b/core/java/android/app/Presentation.java @@ -79,17 +79,16 @@ import android.util.TypedValue; * Here's how to use the media router to create and show a presentation on the preferred * presentation display using {@link android.media.MediaRouter.RouteInfo#getPresentationDisplay()}. * </p> - * {@samplecode + * <pre> * MediaRouter mediaRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE); * MediaRouter.RouteInfo route = mediaRouter.getSelectedRoute(); - * if (route != null) ${ + * if (route != null) { * Display presentationDisplay = route.getPresentationDisplay(); - * if (presentationDisplay != null) ${ + * if (presentationDisplay != null) { * Presentation presentation = new MyPresentation(context, presentationDisplay); * presentation.show(); - * $} - * $} - * } + * } + * }</pre> * <p> * The following sample code from <code>ApiDemos</code> demonstrates how to use the media * router to automatically switch between showing content in the main activity and showing @@ -114,18 +113,17 @@ import android.util.TypedValue; * {@link DisplayManager#getDisplays(String)} and the * {@link DisplayManager#DISPLAY_CATEGORY_PRESENTATION} category. * </p> - * {@samplecode + * <pre> * DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); * Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); - * if (presentationDisplays.length > 0) ${ + * if (presentationDisplays.length > 0) { * // If there is more than one suitable presentation display, then we could consider * // giving the user a choice. For this example, we simply choose the first display * // which is the one the system recommends as the preferred presentation display. * Display display = presentationDisplays[0]; * Presentation presentation = new MyPresentation(context, presentationDisplay); * presentation.show(); - * $} - * } + * }</pre> * <p> * The following sample code from <code>ApiDemos</code> demonstrates how to use the display * manager to enumerate displays and show content on multiple presentation displays diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 6966793..4c0eba0 100755 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1228,7 +1228,7 @@ public class DevicePolicyManager { public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 1 << 1; /** - * Disable all current and future keyguard customizations + * Disable all current and future keyguard customizations. */ public static final int KEYGUARD_DISABLE_FEATURES_ALL = 0x7fffffff; @@ -1381,8 +1381,9 @@ public class DevicePolicyManager { * this method; if it has not, a security exception will be thrown. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. - * @param which {@link DevicePolicyManager#KEYGUARD_DISABLE_WIDGETS_ALL} or - * {@link DevicePolicyManager#KEYGUARD_DISABLE_FEATURES_NONE} (the default). + * @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default), + * {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA}, + * {@link #KEYGUARD_DISABLE_FEATURES_ALL} */ public void setKeyguardDisabledFeatures(ComponentName admin, int which) { if (mService != null) { @@ -1399,6 +1400,8 @@ public class DevicePolicyManager { * admin, if specified, or all admins. * @param admin The name of the admin component to check, or null to check if any admins * have disabled features in keyguard. + * @return bitfield of flags. See {@link #setKeyguardDisabledFeatures(ComponentName, int)} + * for a list. */ public int getKeyguardDisabledFeatures(ComponentName admin) { return getKeyguardDisabledFeatures(admin, UserHandle.myUserId()); diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index fcecd04..52771ee 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -144,6 +144,7 @@ public class AppWidgetHostView extends FrameLayout { // We add padding to the AppWidgetHostView if necessary Rect padding = getDefaultPaddingForWidget(mContext, info.provider, null); setPadding(padding.left, padding.top, padding.right, padding.bottom); + setContentDescription(info.label); } } @@ -243,14 +244,22 @@ public class AppWidgetHostView extends FrameLayout { * * @param newOptions The bundle of options, in addition to the size information, * can be null. - * @param minWidth The minimum width that the widget will be displayed at. - * @param minHeight The maximum height that the widget will be displayed at. - * @param maxWidth The maximum width that the widget will be displayed at. - * @param maxHeight The maximum height that the widget will be displayed at. + * @param minWidth The minimum width in dips that the widget will be displayed at. + * @param minHeight The maximum height in dips that the widget will be displayed at. + * @param maxWidth The maximum width in dips that the widget will be displayed at. + * @param maxHeight The maximum height in dips that the widget will be displayed at. * */ public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth, int maxHeight) { + updateAppWidgetSize(newOptions, minWidth, minHeight, maxWidth, maxHeight, false); + } + + /** + * @hide + */ + public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth, + int maxHeight, boolean ignorePadding) { if (newOptions == null) { newOptions = new Bundle(); } @@ -264,10 +273,10 @@ public class AppWidgetHostView extends FrameLayout { int xPaddingDips = (int) ((padding.left + padding.right) / density); int yPaddingDips = (int) ((padding.top + padding.bottom) / density); - int newMinWidth = minWidth - xPaddingDips; - int newMinHeight = minHeight - yPaddingDips; - int newMaxWidth = maxWidth - xPaddingDips; - int newMaxHeight = maxHeight - yPaddingDips; + int newMinWidth = minWidth - (ignorePadding ? 0 : xPaddingDips); + int newMinHeight = minHeight - (ignorePadding ? 0 : yPaddingDips); + int newMaxWidth = maxWidth - (ignorePadding ? 0 : xPaddingDips); + int newMaxHeight = maxHeight - (ignorePadding ? 0 : yPaddingDips); AppWidgetManager widgetManager = AppWidgetManager.getInstance(mContext); @@ -544,7 +553,10 @@ public class AppWidgetHostView extends FrameLayout { if (options.containsKey(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)) { int category = options.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY); if (category == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) { - layoutId = mInfo.initialKeyguardLayout; + int kgLayoutId = mInfo.initialKeyguardLayout; + // If a default keyguard layout is not specified, use the standard + // default layout. + layoutId = kgLayoutId == 0 ? layoutId : kgLayoutId; } } defaultView = inflater.inflate(layoutId, this, false); diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index 2af65b9..3dd640c 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -80,6 +80,13 @@ public class AppWidgetManager { public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK"; /** + * Similar to ACTION_APPWIDGET_PICK, but used from keyguard + * @hide + */ + public static final String + ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK"; + + /** * Send this from your {@link AppWidgetHost} activity when you want to bind an AppWidget to * display and bindAppWidgetIdIfAllowed returns false. * <p> @@ -224,13 +231,6 @@ public class AppWidgetManager { public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; /** - * An intent extra to pass to the AppWidget picker which allows the picker to filter - * the list based on the {@link AppWidgetProviderInfo#widgetFeatures}. - * @hide - */ - public static final String EXTRA_FEATURES_FILTER = "featuresFilter"; - - /** * An intent extra to pass to the AppWidget picker to specify whether or not to sort * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets * @hide diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index 8b62931..7b8b286 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -54,18 +54,6 @@ public class AppWidgetProviderInfo implements Parcelable { public static final int WIDGET_CATEGORY_KEYGUARD = 2; /** - * Indicates that the widget supports no special features. - */ - public static final int WIDGET_FEATURES_NONE = 0; - - /** - * Indicates that the widget is output only, ie. has nothing clickable. This may be enforced by - * the host. Presently, this flag is used by the keyguard to indicate that it can be placed - * in the first position. - */ - public static final int WIDGET_FEATURES_STATUS = 1; - - /** * Identity of this AppWidget component. This component should be a {@link * android.content.BroadcastReceiver}, and it will be sent the AppWidget intents * {@link android.appwidget as described in the AppWidget package documentation}. @@ -207,15 +195,6 @@ public class AppWidgetProviderInfo implements Parcelable { */ public int widgetCategory; - /** - * A field which specifies any special features that this widget supports. See - * {@link #WIDGET_FEATURES_NONE}, {@link #WIDGET_FEATURES_STATUS}. - * - * <p>This field corresponds to the <code>widgetFeatures</code> attribute in - * the AppWidget meta-data file. - */ - public int widgetFeatures; - public AppWidgetProviderInfo() { } @@ -242,7 +221,6 @@ public class AppWidgetProviderInfo implements Parcelable { this.autoAdvanceViewId = in.readInt(); this.resizeMode = in.readInt(); this.widgetCategory = in.readInt(); - this.widgetFeatures = in.readInt(); } public void writeToParcel(android.os.Parcel out, int flags) { @@ -271,7 +249,6 @@ public class AppWidgetProviderInfo implements Parcelable { out.writeInt(this.autoAdvanceViewId); out.writeInt(this.resizeMode); out.writeInt(this.widgetCategory); - out.writeInt(this.widgetFeatures); } @Override @@ -283,7 +260,7 @@ public class AppWidgetProviderInfo implements Parcelable { that.minResizeWidth = this.minResizeHeight; that.minResizeHeight = this.minResizeHeight; that.updatePeriodMillis = this.updatePeriodMillis; - that.initialLayout = that.initialLayout; + that.initialLayout = this.initialLayout; that.initialKeyguardLayout = this.initialKeyguardLayout; that.configure = this.configure == null ? null : this.configure.clone(); that.label = this.label == null ? null : this.label.substring(0); @@ -292,7 +269,6 @@ public class AppWidgetProviderInfo implements Parcelable { that.autoAdvanceViewId = this.autoAdvanceViewId; that.resizeMode = this.resizeMode; that.widgetCategory = this.widgetCategory; - that.widgetFeatures = this.widgetFeatures; return that; } diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java index a37c26f..382b25e 100644 --- a/core/java/android/net/NetworkStatsHistory.java +++ b/core/java/android/net/NetworkStatsHistory.java @@ -177,6 +177,12 @@ public class NetworkStatsHistory implements Parcelable { throw new ProtocolException("unexpected version: " + version); } } + + if (bucketStart.length != bucketCount || rxBytes.length != bucketCount + || rxPackets.length != bucketCount || txBytes.length != bucketCount + || txPackets.length != bucketCount || operations.length != bucketCount) { + throw new ProtocolException("Mismatched history lengths"); + } } public void writeToStream(DataOutputStream out) throws IOException { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index a3360bc..b6016e9 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2338,6 +2338,7 @@ public final class ViewRootImpl implements ViewParent, mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds); } bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop); + bounds.intersect(0, 0, mAttachInfo.mViewRootImpl.mWidth, mAttachInfo.mViewRootImpl.mHeight); drawable.setBounds(bounds); drawable.draw(canvas); } diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index 5c60a12..7147c57 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -168,6 +168,17 @@ public class AccessibilityRecord { } /** + * Sets the window id. + * + * @param windowId The window id. + * + * @hide + */ + public void setWindowId(int windowId) { + mSourceWindowId = windowId; + } + + /** * Gets the id of the window from which the event comes from. * * @return The window id. diff --git a/core/java/android/webkit/AccessibilityInjector.java b/core/java/android/webkit/AccessibilityInjector.java index 95a0416..008a615 100644 --- a/core/java/android/webkit/AccessibilityInjector.java +++ b/core/java/android/webkit/AccessibilityInjector.java @@ -18,6 +18,7 @@ package android.webkit; import android.content.Context; import android.os.Bundle; +import android.os.Handler; import android.os.SystemClock; import android.provider.Settings; import android.speech.tts.TextToSpeech; @@ -159,7 +160,7 @@ class AccessibilityInjector { * <p> * This should only be called before a page loads. */ - private void addAccessibilityApisIfNecessary() { + public void addAccessibilityApisIfNecessary() { if (!isAccessibilityEnabled() || !isJavaScriptEnabled()) { return; } @@ -333,8 +334,9 @@ class AccessibilityInjector { */ public void onPageStarted(String url) { mAccessibilityScriptInjected = false; - if (DEBUG) + if (DEBUG) { Log.w(TAG, "[" + mWebView.hashCode() + "] Started loading new page"); + } addAccessibilityApisIfNecessary(); } @@ -348,30 +350,57 @@ class AccessibilityInjector { */ public void onPageFinished(String url) { if (!isAccessibilityEnabled()) { - mAccessibilityScriptInjected = false; toggleFallbackAccessibilityInjector(false); return; } - if (!shouldInjectJavaScript(url)) { - mAccessibilityScriptInjected = false; - toggleFallbackAccessibilityInjector(true); - if (DEBUG) - Log.d(TAG, "[" + mWebView.hashCode() + "] Using fallback accessibility support"); - return; + toggleFallbackAccessibilityInjector(true); + + if (shouldInjectJavaScript(url)) { + // If we're supposed to use the JS screen reader, request a + // callback to confirm that CallbackHandler is working. + if (DEBUG) { + Log.d(TAG, "[" + mWebView.hashCode() + "] Request callback "); + } + + mCallback.requestCallback(mWebView, mInjectScriptRunnable); + } + } + + /** + * Runnable used to inject the JavaScript-based screen reader if the + * {@link CallbackHandler} API was successfully exposed to JavaScript. + */ + private Runnable mInjectScriptRunnable = new Runnable() { + @Override + public void run() { + if (DEBUG) { + Log.d(TAG, "[" + mWebView.hashCode() + "] Received callback"); + } + + injectJavaScript(); } + }; + /** + * Called by {@link #mInjectScriptRunnable} to inject the JavaScript-based + * screen reader after confirming that the {@link CallbackHandler} API is + * functional. + */ + private void injectJavaScript() { toggleFallbackAccessibilityInjector(false); if (!mAccessibilityScriptInjected) { mAccessibilityScriptInjected = true; final String injectionUrl = getScreenReaderInjectionUrl(); mWebView.loadUrl(injectionUrl); - if (DEBUG) + if (DEBUG) { Log.d(TAG, "[" + mWebView.hashCode() + "] Loading screen reader into WebView"); + } } else { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "[" + mWebView.hashCode() + "] Attempted to inject screen reader twice"); + } } } @@ -447,12 +476,10 @@ class AccessibilityInjector { * been done. */ private void addTtsApis() { - if (mTextToSpeech != null) { - return; + if (mTextToSpeech == null) { + mTextToSpeech = new TextToSpeechWrapper(mContext); } - if (DEBUG) - Log.d(TAG, "[" + mWebView.hashCode() + "] Adding TTS APIs into WebView"); - mTextToSpeech = new TextToSpeechWrapper(mContext); + mWebView.addJavascriptInterface(mTextToSpeech, ALIAS_TTS_JS_INTERFACE); } @@ -461,34 +488,29 @@ class AccessibilityInjector { * already been done. */ private void removeTtsApis() { - if (mTextToSpeech == null) { - return; + if (mTextToSpeech != null) { + mTextToSpeech.stop(); + mTextToSpeech.shutdown(); + mTextToSpeech = null; } - if (DEBUG) - Log.d(TAG, "[" + mWebView.hashCode() + "] Removing TTS APIs from WebView"); mWebView.removeJavascriptInterface(ALIAS_TTS_JS_INTERFACE); - mTextToSpeech.stop(); - mTextToSpeech.shutdown(); - mTextToSpeech = null; } private void addCallbackApis() { - if (mCallback != null) { - return; + if (mCallback == null) { + mCallback = new CallbackHandler(ALIAS_TRAVERSAL_JS_INTERFACE); } - mCallback = new CallbackHandler(ALIAS_TRAVERSAL_JS_INTERFACE); mWebView.addJavascriptInterface(mCallback, ALIAS_TRAVERSAL_JS_INTERFACE); } private void removeCallbackApis() { - if (mCallback == null) { - return; + if (mCallback != null) { + mCallback = null; } mWebView.removeJavascriptInterface(ALIAS_TRAVERSAL_JS_INTERFACE); - mCallback = null; } /** @@ -638,9 +660,10 @@ class AccessibilityInjector { private volatile boolean mShutdown; public TextToSpeechWrapper(Context context) { - if (DEBUG) + if (DEBUG) { Log.d(WRAP_TAG, "[" + hashCode() + "] Initializing text-to-speech on thread " + Thread.currentThread().getId() + "..."); + } final String pkgName = context.getPackageName(); @@ -672,12 +695,14 @@ class AccessibilityInjector { public int speak(String text, int queueMode, HashMap<String, String> params) { synchronized (mTextToSpeech) { if (!mReady) { - if (DEBUG) + if (DEBUG) { Log.w(WRAP_TAG, "[" + hashCode() + "] Attempted to speak before TTS init"); + } return TextToSpeech.ERROR; } else { - if (DEBUG) + if (DEBUG) { Log.i(WRAP_TAG, "[" + hashCode() + "] Speak called from JS binder"); + } } return mTextToSpeech.speak(text, queueMode, params); @@ -689,12 +714,14 @@ class AccessibilityInjector { public int stop() { synchronized (mTextToSpeech) { if (!mReady) { - if (DEBUG) + if (DEBUG) { Log.w(WRAP_TAG, "[" + hashCode() + "] Attempted to stop before initialize"); + } return TextToSpeech.ERROR; } else { - if (DEBUG) + if (DEBUG) { Log.i(WRAP_TAG, "[" + hashCode() + "] Stop called from JS binder"); + } } return mTextToSpeech.stop(); @@ -705,12 +732,14 @@ class AccessibilityInjector { protected void shutdown() { synchronized (mTextToSpeech) { if (!mReady) { - if (DEBUG) + if (DEBUG) { Log.w(WRAP_TAG, "[" + hashCode() + "] Called shutdown before initialize"); + } } else { - if (DEBUG) + if (DEBUG) { Log.i(WRAP_TAG, "[" + hashCode() + "] Shutting down text-to-speech from " + "thread " + Thread.currentThread().getId() + "..."); + } } mShutdown = true; mReady = false; @@ -723,14 +752,16 @@ class AccessibilityInjector { public void onInit(int status) { synchronized (mTextToSpeech) { if (!mShutdown && (status == TextToSpeech.SUCCESS)) { - if (DEBUG) + if (DEBUG) { Log.d(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode() + "] Initialized successfully"); + } mReady = true; } else { - if (DEBUG) + if (DEBUG) { Log.w(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode() + "] Failed to initialize"); + } mReady = false; } } @@ -745,9 +776,10 @@ class AccessibilityInjector { @Override public void onError(String utteranceId) { - if (DEBUG) + if (DEBUG) { Log.w(WRAP_TAG, "[" + TextToSpeechWrapper.this.hashCode() + "] Failed to speak utterance"); + } } @Override @@ -770,12 +802,16 @@ class AccessibilityInjector { private final AtomicInteger mResultIdCounter = new AtomicInteger(); private final Object mResultLock = new Object(); private final String mInterfaceName; + private final Handler mMainHandler; + + private Runnable mCallbackRunnable; private boolean mResult = false; private int mResultId = -1; private CallbackHandler(String interfaceName) { mInterfaceName = interfaceName; + mMainHandler = new Handler(); } /** @@ -826,25 +862,29 @@ class AccessibilityInjector { private boolean waitForResultTimedLocked(int resultId) { final long startTimeMillis = SystemClock.uptimeMillis(); - if (DEBUG) + 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) + 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) + if (DEBUG) { Log.w(TAG, "Check " + mResultId + " versus expected " + resultId); + } if (mResultId == resultId) { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Received CVOX result after " + elapsedTimeMillis + " ms"); + } return true; } @@ -852,18 +892,21 @@ class AccessibilityInjector { // Fail if we've already exceeded the timeout. if (waitTimeMillis <= 0) { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Timed out while waiting for CVOX result"); + } return false; } try { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Start waiting..."); + } mResultLock.wait(waitTimeMillis); } catch (InterruptedException ie) { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Interrupted while waiting for CVOX result"); + } } } } @@ -878,8 +921,9 @@ class AccessibilityInjector { @JavascriptInterface @SuppressWarnings("unused") public void onResult(String id, String result) { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Saw CVOX result of '" + result + "' for ID " + id); + } final int resultId; try { @@ -893,11 +937,34 @@ class AccessibilityInjector { mResult = Boolean.parseBoolean(result); mResultId = resultId; } else { - if (DEBUG) + if (DEBUG) { Log.w(TAG, "Result with ID " + resultId + " was stale vesus " + mResultId); + } } mResultLock.notifyAll(); } } + + /** + * Requests a callback to ensure that the JavaScript interface for this + * object has been added successfully. + * + * @param webView The web view to request a callback from. + * @param callbackRunnable Runnable to execute if a callback is received. + */ + public void requestCallback(WebView webView, Runnable callbackRunnable) { + mCallbackRunnable = callbackRunnable; + + webView.loadUrl("javascript:(function() { " + mInterfaceName + ".callback(); })();"); + } + + @JavascriptInterface + @SuppressWarnings("unused") + public void callback() { + if (mCallbackRunnable != null) { + mMainHandler.post(mCallbackRunnable); + mCallbackRunnable = null; + } + } } } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 0f8966e..ae56e6b 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -2500,6 +2500,9 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // Remove all pending messages because we are restoring previous // state. mWebViewCore.removeMessages(); + if (isAccessibilityInjectionEnabled()) { + getAccessibilityInjector().addAccessibilityApisIfNecessary(); + } // Send a restore state message. mWebViewCore.sendMessage(EventHub.RESTORE_STATE, index); } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 495e46b..5397eb6 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -144,7 +144,6 @@ public class Editor { CharSequence mError; boolean mErrorWasChanged; ErrorPopup mErrorPopup; - private int mLastLayoutDirection = -1; /** * This flag is set if the TextView tries to display an error before it @@ -290,29 +289,12 @@ public class Editor { public void setError(CharSequence error, Drawable icon) { mError = TextUtils.stringOrSpannedString(error); mErrorWasChanged = true; - final int layoutDirection = mTextView.getLayoutDirection(); - if (mLastLayoutDirection != layoutDirection) { - final Drawables dr = mTextView.mDrawables; - switch (layoutDirection) { - default: - case View.LAYOUT_DIRECTION_LTR: - if (dr != null) { - mTextView.setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop, icon, - dr.mDrawableBottom); - } else { - mTextView.setCompoundDrawables(null, null, icon, null); - } - break; - case View.LAYOUT_DIRECTION_RTL: - if (dr != null) { - mTextView.setCompoundDrawables(icon, dr.mDrawableTop, dr.mDrawableRight, - dr.mDrawableBottom); - } else { - mTextView.setCompoundDrawables(icon, null, null, null); - } - break; - } - mLastLayoutDirection = layoutDirection; + final Drawables dr = mTextView.mDrawables; + if (dr != null) { + mTextView.setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop, icon, + dr.mDrawableBottom); + } else { + mTextView.setCompoundDrawables(null, null, icon, null); } if (mError == null) { if (mErrorPopup != null) { diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl index eb902fd..280e4d5 100644 --- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl +++ b/core/java/com/android/internal/policy/IFaceLockCallback.aidl @@ -22,6 +22,5 @@ oneway interface IFaceLockCallback { void unlock(); void cancel(); void reportFailedAttempt(); - void exposeFallback(); void pokeWakelock(int millis); } diff --git a/core/java/com/android/internal/policy/IFaceLockInterface.aidl b/core/java/com/android/internal/policy/IFaceLockInterface.aidl index a017722..017801b 100644 --- a/core/java/com/android/internal/policy/IFaceLockInterface.aidl +++ b/core/java/com/android/internal/policy/IFaceLockInterface.aidl @@ -23,7 +23,6 @@ interface IFaceLockInterface { void startUi(IBinder containingWindowToken, int x, int y, int width, int height, boolean useLiveliness); void stopUi(); - void makeInvisible(); void registerCallback(IFaceLockCallback cb); void unregisterCallback(IFaceLockCallback cb); } diff --git a/core/java/com/android/internal/widget/FaceUnlockView.java b/core/java/com/android/internal/widget/FaceUnlockView.java new file mode 100644 index 0000000..e3c1247 --- /dev/null +++ b/core/java/com/android/internal/widget/FaceUnlockView.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 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.android.internal.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.widget.RelativeLayout; + +public class FaceUnlockView extends RelativeLayout { + private static final String TAG = "FaceUnlockView"; + + public FaceUnlockView(Context context) { + this(context, null); + } + + public FaceUnlockView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + private int resolveMeasured(int measureSpec, int desired) + { + int result = 0; + int specSize = MeasureSpec.getSize(measureSpec); + switch (MeasureSpec.getMode(measureSpec)) { + case MeasureSpec.UNSPECIFIED: + result = desired; + break; + case MeasureSpec.AT_MOST: + result = Math.max(specSize, desired); + break; + case MeasureSpec.EXACTLY: + default: + result = specSize; + } + return result; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int minimumWidth = getSuggestedMinimumWidth(); + final int minimumHeight = getSuggestedMinimumHeight(); + int viewWidth = resolveMeasured(widthMeasureSpec, minimumWidth); + int viewHeight = resolveMeasured(heightMeasureSpec, minimumHeight); + + final int chosenSize = Math.min(viewWidth, viewHeight); + final int newWidthMeasureSpec = + MeasureSpec.makeMeasureSpec(chosenSize, MeasureSpec.AT_MOST); + final int newHeightMeasureSpec = + MeasureSpec.makeMeasureSpec(chosenSize, MeasureSpec.AT_MOST); + + super.onMeasure(newWidthMeasureSpec, newHeightMeasureSpec); + } +} diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index f8c3b4d..e5e1a2b 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -129,6 +129,11 @@ public class LockPatternUtils { */ public static final int ID_DEFAULT_STATUS_WIDGET = -2; + /** + * Intent extra that's used to tag the default widget when using the picker + */ + public static final String EXTRA_DEFAULT_WIDGET = "com.android.settings.DEFAULT_WIDGET"; + protected final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently"; protected final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline"; protected final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen"; @@ -1068,11 +1073,7 @@ public class LockPatternUtils { } return appWidgetIds; } - if (appWidgetIdString == null) { - return new int[] { LockPatternUtils.ID_DEFAULT_STATUS_WIDGET }; - } else { - return new int[0]; - } + return new int[0]; } private static String combineStrings(int[] list, String separator) { diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 6c5ed7e..7a76ab0 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -18,7 +18,6 @@ package com.android.internal.widget; import android.content.Context; -import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -33,11 +32,9 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; import android.util.AttributeSet; -import android.util.Log; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; -import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; @@ -657,9 +654,11 @@ public class LockPatternView extends View { handleActionMove(event); return true; case MotionEvent.ACTION_CANCEL: - resetPattern(); - mPatternInProgress = false; - notifyPatternCleared(); + if (mPatternInProgress) { + mPatternInProgress = false; + resetPattern(); + notifyPatternCleared(); + } if (PROFILE_DRAWING) { if (mDrawingProfilingStarted) { Debug.stopMethodTracing(); @@ -826,7 +825,7 @@ public class LockPatternView extends View { mPatternInProgress = true; mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); - } else { + } else if (mPatternInProgress) { mPatternInProgress = false; notifyPatternCleared(); } |
