diff options
12 files changed, 138 insertions, 17 deletions
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 8483b4f0cf44..4bc0892d3d75 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -187,6 +187,59 @@ public final class ContactsContract { public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query"; /** + * <p> + * API for obtaining a pre-authorized version of a URI that normally requires special + * permission (beyond READ_CONTACTS) to read. The caller obtaining the pre-authorized URI + * must already have the necessary permissions to access the URI; otherwise a + * {@link SecurityException} will be thrown. + * </p> + * <p> + * The authorized URI returned in the bundle contains an expiring token that allows the + * caller to execute the query without having the special permissions that would normally + * be required. + * </p> + * <p> + * This API does not access disk, and should be safe to invoke from the UI thread. + * </p> + * <p> + * Example usage: + * <pre> + * Uri profileUri = ContactsContract.Profile.CONTENT_VCARD_URI; + * Bundle uriBundle = new Bundle(); + * uriBundle.putParcelable(ContactsContract.Authorization.KEY_URI_TO_AUTHORIZE, uri); + * Bundle authResponse = getContext().getContentResolver().call( + * ContactsContract.AUTHORITY_URI, + * ContactsContract.Authorization.AUTHORIZATION_METHOD, + * null, // String arg, not used. + * uriBundle); + * if (authResponse != null) { + * Uri preauthorizedProfileUri = (Uri) authResponse.getParcelable( + * ContactsContract.Authorization.KEY_AUTHORIZED_URI); + * // This pre-authorized URI can be queried by a caller without READ_PROFILE + * // permission. + * } + * </pre> + * </p> + * @hide + */ + public static final class Authorization { + /** + * The method to invoke to create a pre-authorized URI out of the input argument. + */ + public static final String AUTHORIZATION_METHOD = "authorize"; + + /** + * The key to set in the outbound Bundle with the URI that should be authorized. + */ + public static final String KEY_URI_TO_AUTHORIZE = "uri_to_authorize"; + + /** + * The key to retrieve from the returned Bundle to obtain the pre-authorized URI. + */ + public static final String KEY_AUTHORIZED_URI = "authorized_uri"; + } + + /** * @hide */ public static final class Preferences { diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 3d2a3cefeab2..5754e60d0815 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4053,6 +4053,14 @@ public final class Settings { public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout"; /** + * Duration in milliseconds before pre-authorized URIs for the contacts + * provider should expire. + * @hide + */ + public static final String CONTACTS_PREAUTH_URI_EXPIRATION = + "contacts_preauth_uri_expiration"; + + /** * This are the settings to be backed up. * * NOTE: Settings are backed up and restored in the order they appear diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 8da1820e4725..1c22a0b733f0 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2079,10 +2079,12 @@ public class WebView extends AbsoluteLayout * <p> * The 'data' scheme URL formed by this method uses the default US-ASCII * charset. If you need need to set a different charset, you should form a - * 'data' scheme URL which specifies a charset parameter and call - * {@link #loadUrl(String)} instead. + * 'data' scheme URL which explicitly specifies a charset parameter in the + * mediatype portion of the URL and call {@link #loadUrl(String)} instead. + * Note that the charset obtained from the mediatype portion of a data URL + * always overrides that specified in the HTML or XML document itself. * @param data A String of data in the given encoding. - * @param mimeType The MIMEType of the data, e.g. 'text/html'. + * @param mimeType The MIME type of the data, e.g. 'text/html'. * @param encoding The encoding of the data. */ public void loadData(String data, String mimeType, String encoding) { diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 53d497004fc6..2d5120853b8d 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -319,8 +319,12 @@ void Context::destroyWorkerThreadResources() { void Context::printWatchdogInfo(void *ctx) { Context *rsc = (Context *)ctx; - LOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot, - rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file); + if (rsc->watchdog.command && rsc->watchdog.file) { + LOGE("RS watchdog timeout: %i %s line %i %s", rsc->watchdog.inRoot, + rsc->watchdog.command, rsc->watchdog.line, rsc->watchdog.file); + } else { + LOGE("RS watchdog timeout: %i", rsc->watchdog.inRoot); + } } diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e971896e9617..65d513853ccf 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -305,6 +305,9 @@ <!-- Content description of the ringer silent icon in the notification panel for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_ringer_silent">Ringer silent.</string> + <!-- Content description to tell the user an application has been removed from recents --> + <string name="accessibility_recents_item_dismissed"><xliff:g id="app" example="Calendar">%s</xliff:g> dismissed.</string> + <!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] --> <string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string> <!-- Title of dialog shown when 4G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] --> diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index d3c4a6143c30..8d5c33f8beb1 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -38,6 +38,7 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.BaseAdapter; @@ -512,6 +513,12 @@ public class RecentsPanelView extends RelativeLayout final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); + + // Accessibility feedback + setContentDescription( + mContext.getString(R.string.accessibility_recents_item_dismissed, ad.getLabel())); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + setContentDescription(null); } private void startApplicationDetailsActivity(String packageName) { diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java index 8343bbdf738e..6614d7929496 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java @@ -609,6 +609,10 @@ class KeyguardStatusViewManager implements OnClickListener { public void onClockVisibilityChanged() { // ignored } + + public void onDeviceProvisioned() { + // ignored + } }; private SimStateCallback mSimStateCallback = new SimStateCallback() { diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java index f67f0e056d65..2d8185b4f33c 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java @@ -99,6 +99,7 @@ public class KeyguardUpdateMonitor { private static final int MSG_RINGER_MODE_CHANGED = 305; private static final int MSG_PHONE_STATE_CHANGED = 306; private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307; + private static final int MSG_DEVICE_PROVISIONED = 308; /** * When we receive a @@ -178,6 +179,9 @@ public class KeyguardUpdateMonitor { case MSG_CLOCK_VISIBILITY_CHANGED: handleClockVisibilityChanged(); break; + case MSG_DEVICE_PROVISIONED: + handleDeviceProvisioned(); + break; } } }; @@ -197,10 +201,8 @@ public class KeyguardUpdateMonitor { super.onChange(selfChange); mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0; - if (mDeviceProvisioned && mContentObserver != null) { - // We don't need the observer anymore... - mContext.getContentResolver().unregisterContentObserver(mContentObserver); - mContentObserver = null; + if (mDeviceProvisioned) { + mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED)); } if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned); } @@ -212,8 +214,14 @@ public class KeyguardUpdateMonitor { // prevent a race condition between where we check the flag and where we register the // observer by grabbing the value once again... - mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), + boolean provisioned = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0; + if (provisioned != mDeviceProvisioned) { + mDeviceProvisioned = provisioned; + if (mDeviceProvisioned) { + mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED)); + } + } } // take a guess to start @@ -271,6 +279,17 @@ public class KeyguardUpdateMonitor { }, filter); } + protected void handleDeviceProvisioned() { + for (int i = 0; i < mInfoCallbacks.size(); i++) { + mInfoCallbacks.get(i).onDeviceProvisioned(); + } + if (mContentObserver != null) { + // We don't need the observer anymore... + mContext.getContentResolver().unregisterContentObserver(mContentObserver); + mContentObserver = null; + } + } + protected void handlePhoneStateChanged(String newState) { if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")"); if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) { @@ -477,6 +496,10 @@ public class KeyguardUpdateMonitor { */ void onClockVisibilityChanged(); + /** + * Called when the device becomes provisioned + */ + void onDeviceProvisioned(); } /** diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java index bbfc5137cb8e..0471dfe8c1d9 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java @@ -1316,4 +1316,9 @@ public class KeyguardViewMediator implements KeyguardViewCallback, public void onTimeChanged() { // ignored } + + /** {@inheritDoc} */ + public void onDeviceProvisioned() { + mContext.sendBroadcast(mUserPresentIntent); + } } diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 0c44e45884d7..d1bb8d1176f2 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -649,6 +649,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler public void onRingerModeChanged(int state) {} @Override public void onClockVisibilityChanged() {} + @Override + public void onDeviceProvisioned() {} //We need to stop faceunlock when a phonecall comes in @Override diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index de8d41a2808b..af86ae954794 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -349,8 +349,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } // Already prepared (isPrepared will be reset to false later) - if (st.isPrepared) + if (st.isPrepared) { return true; + } if ((mPreparedPanel != null) && (mPreparedPanel != st)) { // Another Panel is prepared and possibly open, so close it @@ -800,14 +801,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { closePanel(st, true); } else if (st.isPrepared) { + boolean show = true; + if (st.refreshMenuContent) { + // Something may have invalidated the menu since we prepared it. + // Re-prepare it to refresh. + st.isPrepared = false; + show = preparePanel(st, event); + } - // Write 'menu opened' to event log - EventLog.writeEvent(50001, 0); + if (show) { + // Write 'menu opened' to event log + EventLog.writeEvent(50001, 0); - // Show menu - openPanel(st, event); + // Show menu + openPanel(st, event); - playSoundEffect = true; + playSoundEffect = true; + } } } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index b9d3d76bbd11..1aed7fe0a1d8 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2067,7 +2067,7 @@ final class ActivityStack { * task starting at a specified index. */ private final void performClearTaskAtIndexLocked(int taskId, int i) { - while (i < (mHistory.size()-1)) { + while (i < mHistory.size()) { ActivityRecord r = mHistory.get(i); if (r.task.taskId != taskId) { // Whoops hit the end. |