summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Activity.java35
-rw-r--r--core/java/android/app/ActivityManager.java2
-rw-r--r--core/java/android/app/ActivityManagerNative.java47
-rw-r--r--core/java/android/app/AppOpsManager.java10
-rw-r--r--core/java/android/app/BackStackRecord.java12
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java7
-rw-r--r--core/java/android/app/Fragment.java8
-rw-r--r--core/java/android/app/IActivityManager.java12
-rw-r--r--core/java/android/app/IUiAutomationConnection.aidl4
-rw-r--r--core/java/android/app/Instrumentation.java5
-rw-r--r--core/java/android/app/Notification.java79
-rw-r--r--core/java/android/app/SystemServiceRegistry.java3
-rw-r--r--core/java/android/app/assist/AssistStructure.java71
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeScanner.java8
-rw-r--r--core/java/android/content/ContentProvider.java106
-rw-r--r--core/java/android/content/Intent.java2
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl2
-rw-r--r--core/java/android/content/pm/PackageInstaller.java24
-rw-r--r--core/java/android/content/pm/PackageManager.java7
-rw-r--r--core/java/android/content/pm/PermissionInfo.java17
-rw-r--r--core/java/android/content/res/DrawableCache.java2
-rw-r--r--core/java/android/hardware/camera2/CameraCaptureSession.java39
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java8
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java12
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java12
-rw-r--r--core/java/android/hardware/camera2/ICameraDeviceUser.aidl2
-rw-r--r--core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java5
-rw-r--r--core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java5
-rw-r--r--core/java/android/hardware/camera2/impl/CameraDeviceImpl.java25
-rw-r--r--core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java14
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java16
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java8
-rw-r--r--core/java/android/os/FileUtils.java12
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl1
-rw-r--r--core/java/android/os/UserManager.java4
-rw-r--r--core/java/android/provider/CalendarContract.java2
-rw-r--r--core/java/android/provider/ContactsContract.java4
-rw-r--r--core/java/android/provider/DocumentsProvider.java6
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/provider/VoicemailContract.java7
-rw-r--r--core/java/android/security/keymaster/KeymasterDefs.java6
-rw-r--r--core/java/android/service/chooser/ChooserTarget.java128
-rw-r--r--core/java/android/service/chooser/ChooserTargetService.java5
-rw-r--r--core/java/android/service/chooser/IChooserTargetResult.aidl2
-rw-r--r--core/java/android/service/voice/IVoiceInteractionSession.aidl1
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java94
-rw-r--r--core/java/android/text/BidiFormatter.java15
-rw-r--r--core/java/android/text/TextLine.java4
-rw-r--r--core/java/android/text/format/Formatter.java31
-rw-r--r--core/java/android/util/LocalLog.java33
-rw-r--r--core/java/android/view/inputmethod/InputMethodManagerInternal.java30
-rw-r--r--core/java/android/widget/AbsListView.java19
-rw-r--r--core/java/android/widget/AppSecurityPermissions.java8
-rw-r--r--core/java/android/widget/Editor.java6
-rw-r--r--core/java/android/widget/RelativeLayout.java7
-rw-r--r--core/java/android/widget/SimpleMonthView.java7
56 files changed, 754 insertions, 295 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7572799..e49acfa 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1545,6 +1545,24 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Ask to have the current assistant shown to the user. This only works if the calling
+ * activity is the current foreground activity. It is the same as calling
+ * {@link android.service.voice.VoiceInteractionService#showSession
+ * VoiceInteractionService.showSession} and requesting all of the possible context.
+ * The receiver will always see
+ * {@link android.service.voice.VoiceInteractionSession#SHOW_SOURCE_APPLICATION} set.
+ * @return Returns true if the assistant was successfully invoked, else false. For example
+ * false will be returned if the caller is not the current top activity.
+ */
+ public boolean showAssist(Bundle args) {
+ try {
+ return ActivityManagerNative.getDefault().showAssistFromActivity(mToken, args);
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
@@ -3771,6 +3789,11 @@ public class Activity extends ContextThemeWrapper
/**
* Callback for the result from requesting permissions. This method
* is invoked for every call on {@link #requestPermissions(String[], int)}.
+ * <p>
+ * <strong>Note:</strong> It is possible that the permissions request interaction
+ * with the user is interrupted. In this case you will receive empty permissions
+ * and results arrays which should be treated as a cancellation.
+ * </p>
*
* @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
* @param permissions The requested permissions. Never null.
@@ -3977,16 +4000,24 @@ public class Activity extends ContextThemeWrapper
* as intermediaries that dispatch their intent to the target the user selects -- to
* do this, they must perform all security checks including permission grants as if
* their launch had come from the original activity.
+ * @param intent The Intent to start.
+ * @param options ActivityOptions or null.
+ * @param ignoreTargetSecurity If true, the activity manager will not check whether the
+ * caller it is doing the start is, is actually allowed to start the target activity.
+ * If you set this to true, you must set an explicit component in the Intent and do any
+ * appropriate security checks yourself.
+ * @param userId The user the new activity should run as.
* @hide
*/
- public void startActivityAsCaller(Intent intent, @Nullable Bundle options, int userId) {
+ public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
+ boolean ignoreTargetSecurity, int userId) {
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivityAsCaller(
this, mMainThread.getApplicationThread(), mToken, this,
- intent, -1, options, userId);
+ intent, -1, options, ignoreTargetSecurity, userId);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, -1, ar.getResultCode(),
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9ca206a..55b2fd9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2807,7 +2807,7 @@ public class ActivityManager {
/**
* Request that the system start watching for the calling process to exceed a pss
- * size as given here. Once called, the system will look for any occassions where it
+ * size as given here. Once called, the system will look for any occasions where it
* sees the associated process with a larger pss size and, when this happens, automatically
* pull a heap dump from it and allow the user to share the data. Note that this request
* continues running even if the process is killed and restarted. To remove the watch,
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index fc408a8..b758a7a 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -206,9 +206,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
? ProfilerInfo.CREATOR.createFromParcel(data) : null;
Bundle options = data.readInt() != 0
? Bundle.CREATOR.createFromParcel(data) : null;
+ boolean ignoreTargetSecurity = data.readInt() != 0;
int userId = data.readInt();
int result = startActivityAsCaller(app, callingPackage, intent, resolvedType,
- resultTo, resultWho, requestCode, startFlags, profilerInfo, options, userId);
+ resultTo, resultWho, requestCode, startFlags, profilerInfo, options,
+ ignoreTargetSecurity, userId);
reply.writeNoException();
reply.writeInt(result);
return true;
@@ -2191,8 +2193,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
int requestType = data.readInt();
IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder());
- requestAssistContextExtras(requestType, receiver);
+ IBinder activityToken = data.readStrongBinder();
+ boolean res = requestAssistContextExtras(requestType, receiver, activityToken);
reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
return true;
}
@@ -2223,7 +2227,17 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
- boolean res = isScreenCaptureAllowedOnCurrentActivity();
+ boolean res = isAssistDataAllowedOnCurrentActivity();
+ reply.writeNoException();
+ reply.writeInt(res ? 1 : 0);
+ return true;
+ }
+
+ case SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ Bundle args = data.readBundle();
+ boolean res = showAssistFromActivity(token, args);
reply.writeNoException();
reply.writeInt(res ? 1 : 0);
return true;
@@ -2675,7 +2689,8 @@ class ActivityManagerProxy implements IActivityManager
}
public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException {
+ int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
+ int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -2699,6 +2714,7 @@ class ActivityManagerProxy implements IActivityManager
} else {
data.writeInt(0);
}
+ data.writeInt(ignoreTargetSecurity ? 1 : 0);
data.writeInt(userId);
mRemote.transact(START_ACTIVITY_AS_CALLER_TRANSACTION, data, reply, 0);
reply.readException();
@@ -5373,17 +5389,20 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
- throws RemoteException {
+ public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
+ IBinder activityToken) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(requestType);
data.writeStrongBinder(receiver.asBinder());
+ data.writeStrongBinder(activityToken);
mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
reply.readException();
+ boolean res = reply.readInt() != 0;
data.recycle();
reply.recycle();
+ return res;
}
public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
@@ -5425,7 +5444,7 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
- public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException {
+ public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -5437,6 +5456,20 @@ class ActivityManagerProxy implements IActivityManager
return res;
}
+ public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ data.writeBundle(args);
+ mRemote.transact(SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
public void killUid(int uid, String reason) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 08e1696..976830f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -325,6 +325,12 @@ public class AppOpsManager {
/** Write external storage. */
public static final String OPSTR_WRITE_EXTERNAL_STORAGE
= "android:write_external_storage";
+ /** Required to draw on top of other apps. */
+ public static final String OPSTR_SYSTEM_ALERT_WINDOW
+ = "android:system_alert_window";
+ /** Required to write/modify/update system settingss. */
+ public static final String OPSTR_WRITE_SETTINGS
+ = "android:write_settings";
/**
* This maps each operation to the operation that serves as the
@@ -427,8 +433,8 @@ public class AppOpsManager {
OPSTR_SEND_SMS,
null,
null,
- null,
- null,
+ OPSTR_WRITE_SETTINGS,
+ OPSTR_SYSTEM_ALERT_WINDOW,
null,
OPSTR_CAMERA,
OPSTR_RECORD_AUDIO,
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 13030ca..84cbea9 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -1094,8 +1094,10 @@ final class BackStackRecord extends FragmentTransaction implements
container.getViewTreeObserver().removeOnPreDrawListener(this);
// Don't include any newly-hidden fragments in the transition.
- excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
- overallTransition);
+ if (inFragment != null) {
+ excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
+ overallTransition);
+ }
ArrayMap<String, View> namedViews = null;
if (sharedElementTransition != null) {
@@ -1692,7 +1694,7 @@ final class BackStackRecord extends FragmentTransaction implements
private static void setNameOverrides(TransitionState state, ArrayList<String> sourceNames,
ArrayList<String> targetNames) {
- if (sourceNames != null) {
+ if (sourceNames != null && targetNames != null) {
for (int i = 0; i < sourceNames.size(); i++) {
String source = sourceNames.get(i);
String target = targetNames.get(i);
@@ -1703,7 +1705,9 @@ final class BackStackRecord extends FragmentTransaction implements
private void setBackNameOverrides(TransitionState state, ArrayMap<String, View> namedViews,
boolean isEnd) {
- int count = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
+ int targetCount = mSharedElementTargetNames == null ? 0 : mSharedElementTargetNames.size();
+ int sourceCount = mSharedElementSourceNames == null ? 0 : mSharedElementSourceNames.size();
+ final int count = Math.min(targetCount, sourceCount);
for (int i = 0; i < count; i++) {
String source = mSharedElementSourceNames.get(i);
String originalTarget = mSharedElementTargetNames.get(i);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index ad104a4..7fbb99a 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -25,6 +25,7 @@ import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -238,8 +239,12 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
if (decorView != null && decorView.getBackground() == null) {
getWindow().setBackgroundDrawable(new ColorDrawable(Color.BLACK));
}
+ final boolean targetsM = decorView == null || decorView.getContext()
+ .getApplicationInfo().targetSdkVersion >= VERSION_CODES.MNC;
+ ArrayList<String> sharedElementNames = targetsM ? mSharedElementNames :
+ mAllSharedElementNames;
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(mActivity, this,
- mSharedElementNames, resultCode, data);
+ sharedElementNames, resultCode, data);
mActivity.convertToTranslucent(new Activity.TranslucentConversionListener() {
@Override
public void onTranslucentConversionComplete(boolean drawComplete) {
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 5490fe7..82206ea 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1213,6 +1213,11 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
/**
* Callback for the result from requesting permissions. This method
* is invoked for every call on {@link #requestPermissions(String[], int)}.
+ * <p>
+ * <strong>Note:</strong> It is possible that the permissions request interaction
+ * with the user is interrupted. In this case you will receive empty permissions
+ * and results arrays which should be treated as a cancellation.
+ * </p>
*
* @param requestCode The request code passed in {@link #requestPermissions(String[], int)}.
* @param permissions The requested permissions. Never null.
@@ -1249,7 +1254,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
*/
public boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
if (mHost != null) {
- mHost.getContext().getPackageManager().shouldShowRequestPermissionRationale(permission);
+ return mHost.getContext().getPackageManager()
+ .shouldShowRequestPermissionRationale(permission);
}
return false;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1d87d77..9ebbb9b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -72,7 +72,8 @@ public interface IActivityManager extends IInterface {
ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
public int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int flags, ProfilerInfo profilerInfo, Bundle options, int userId) throws RemoteException;
+ int flags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
+ int userId) throws RemoteException;
public WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, ProfilerInfo profilerInfo, Bundle options,
@@ -433,8 +434,8 @@ public interface IActivityManager extends IInterface {
public Bundle getAssistContextExtras(int requestType) throws RemoteException;
- public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
- throws RemoteException;
+ public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
+ IBinder activityToken) throws RemoteException;
public void reportAssistContextExtras(IBinder token, Bundle extras,
AssistStructure structure, AssistContent content, Uri referrer) throws RemoteException;
@@ -442,7 +443,9 @@ public interface IActivityManager extends IInterface {
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
Bundle args) throws RemoteException;
- public boolean isScreenCaptureAllowedOnCurrentActivity() throws RemoteException;
+ public boolean isAssistDataAllowedOnCurrentActivity() throws RemoteException;
+
+ public boolean showAssistFromActivity(IBinder token, Bundle args) throws RemoteException;
public void killUid(int uid, String reason) throws RemoteException;
@@ -857,4 +860,5 @@ public interface IActivityManager extends IInterface {
int UNREGISTER_UID_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+298;
int IS_SCREEN_CAPTURE_ALLOWED_ON_CURRENT_ACTIVITY_TRANSACTION
= IBinder.FIRST_CALL_TRANSACTION+299;
+ int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
}
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 8ab9ac3..474154b 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -38,10 +38,12 @@ interface IUiAutomationConnection {
boolean injectInputEvent(in InputEvent event, boolean sync);
boolean setRotation(int rotation);
Bitmap takeScreenshot(int width, int height);
- void shutdown();
boolean clearWindowContentFrameStats(int windowId);
WindowContentFrameStats getWindowContentFrameStats(int windowId);
void clearWindowAnimationFrameStats();
WindowAnimationFrameStats getWindowAnimationFrameStats();
void executeShellCommand(String command, in ParcelFileDescriptor fd);
+
+ // Called from the system process.
+ oneway void shutdown();
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 653f1b6..c2d901d 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1701,7 +1701,8 @@ public class Instrumentation {
*/
public ActivityResult execStartActivityAsCaller(
Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options, int userId) {
+ Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity,
+ int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -1725,7 +1726,7 @@ public class Instrumentation {
.startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options, userId);
+ requestCode, 0, null, options, ignoreTargetSecurity, userId);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c3dece8..fc71783 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -166,8 +166,10 @@ public class Notification implements Parcelable
/**
* The resource id of a drawable to use as the icon in the status bar.
- * This is required; notifications with an invalid icon resource will not be shown.
+ *
+ * @deprecated Use {@link Builder#setSmallIcon(Icon)} instead.
*/
+ @Deprecated
@DrawableRes
public int icon;
@@ -269,8 +271,11 @@ public class Notification implements Parcelable
public RemoteViews headsUpContentView;
/**
- * The bitmap that may escape the bounds of the panel and bar.
+ * A large bitmap to be shown in the notification content area.
+ *
+ * @deprecated Use {@link Builder#setLargeIcon(Icon)} instead.
*/
+ @Deprecated
public Bitmap largeIcon;
/**
@@ -900,11 +905,15 @@ public class Notification implements Parcelable
*/
public static class Action implements Parcelable {
private final Bundle mExtras;
+ private Icon mIcon;
private final RemoteInput[] mRemoteInputs;
/**
* Small icon representing the action.
+ *
+ * @deprecated Use {@link Action#getIcon()} instead.
*/
+ @Deprecated
public int icon;
/**
@@ -919,7 +928,12 @@ public class Notification implements Parcelable
public PendingIntent actionIntent;
private Action(Parcel in) {
- icon = in.readInt();
+ if (in.readInt() != 0) {
+ mIcon = Icon.CREATOR.createFromParcel(in);
+ }
+ if (mIcon.getType() == Icon.TYPE_RESOURCE) {
+ icon = mIcon.getResId();
+ }
title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
if (in.readInt() == 1) {
actionIntent = PendingIntent.CREATOR.createFromParcel(in);
@@ -929,15 +943,16 @@ public class Notification implements Parcelable
}
/**
- * Use {@link Notification.Builder#addAction(int, CharSequence, PendingIntent)}.
+ * @deprecated Use {@link android.app.Notification.Action.Builder}.
*/
+ @Deprecated
public Action(int icon, CharSequence title, PendingIntent intent) {
- this(icon, title, intent, new Bundle(), null);
+ this(Icon.createWithResource("", icon), title, intent, new Bundle(), null);
}
- private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
+ private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
RemoteInput[] remoteInputs) {
- this.icon = icon;
+ this.mIcon = icon;
this.title = title;
this.actionIntent = intent;
this.mExtras = extras != null ? extras : new Bundle();
@@ -945,6 +960,17 @@ public class Notification implements Parcelable
}
/**
+ * Return an icon representing the action.
+ */
+ public Icon getIcon() {
+ if (mIcon == null && icon != 0) {
+ // you snuck an icon in here without using the builder; let's try to keep it
+ mIcon = Icon.createWithResource("", icon);
+ }
+ return mIcon;
+ }
+
+ /**
* Get additional metadata carried around with this Action.
*/
public Bundle getExtras() {
@@ -963,7 +989,7 @@ public class Notification implements Parcelable
* Builder class for {@link Action} objects.
*/
public static final class Builder {
- private final int mIcon;
+ private final Icon mIcon;
private final CharSequence mTitle;
private final PendingIntent mIntent;
private final Bundle mExtras;
@@ -975,7 +1001,18 @@ public class Notification implements Parcelable
* @param title the title of the action
* @param intent the {@link PendingIntent} to fire when users trigger this action
*/
+ @Deprecated
public Builder(int icon, CharSequence title, PendingIntent intent) {
+ this(Icon.createWithResource("", icon), title, intent, new Bundle(), null);
+ }
+
+ /**
+ * Construct a new builder for {@link Action} object.
+ * @param icon icon to show for this action
+ * @param title the title of the action
+ * @param intent the {@link PendingIntent} to fire when users trigger this action
+ */
+ public Builder(Icon icon, CharSequence title, PendingIntent intent) {
this(icon, title, intent, new Bundle(), null);
}
@@ -985,11 +1022,11 @@ public class Notification implements Parcelable
* @param action the action to read fields from.
*/
public Builder(Action action) {
- this(action.icon, action.title, action.actionIntent, new Bundle(action.mExtras),
+ this(action.getIcon(), action.title, action.actionIntent, new Bundle(action.mExtras),
action.getRemoteInputs());
}
- private Builder(int icon, CharSequence title, PendingIntent intent, Bundle extras,
+ private Builder(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
RemoteInput[] remoteInputs) {
mIcon = icon;
mTitle = title;
@@ -1063,7 +1100,7 @@ public class Notification implements Parcelable
@Override
public Action clone() {
return new Action(
- icon,
+ getIcon(),
title,
actionIntent, // safe to alias
new Bundle(mExtras),
@@ -1075,7 +1112,13 @@ public class Notification implements Parcelable
}
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(icon);
+ final Icon ic = getIcon();
+ if (ic != null) {
+ out.writeInt(1);
+ ic.writeToParcel(out, 0);
+ } else {
+ out.writeInt(0);
+ }
TextUtils.writeToParcel(title, out, flags);
if (actionIntent != null) {
out.writeInt(1);
@@ -1819,6 +1862,9 @@ public class Notification implements Parcelable
} else {
sb.append("null");
}
+ if (this.tickerText != null) {
+ sb.append(" tick");
+ }
sb.append(" defaults=0x");
sb.append(Integer.toHexString(this.defaults));
sb.append(" flags=0x");
@@ -2725,7 +2771,10 @@ public class Notification implements Parcelable
* @param icon Resource ID of a drawable that represents the action.
* @param title Text describing the action.
* @param intent PendingIntent to be fired when the action is invoked.
+ *
+ * @deprecated Use {@link #addAction(Action)} instead.
*/
+ @Deprecated
public Builder addAction(int icon, CharSequence title, PendingIntent intent) {
mActions.add(new Action(icon, safeCharSequence(title), intent));
return this;
@@ -3122,7 +3171,7 @@ public class Notification implements Parcelable
private RemoteViews generateActionButton(Action action) {
final boolean tombstone = (action.actionIntent == null);
- RemoteViews button = new RemoteViews(mContext.getPackageName(),
+ RemoteViews button = new BuilderRemoteViews(mContext.getApplicationInfo(),
tombstone ? getActionTombstoneLayoutResource()
: getActionLayoutResource());
button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
@@ -4265,7 +4314,7 @@ public class Notification implements Parcelable
*
* In the expanded form, {@link Notification#bigContentView}, up to 5
* {@link Notification.Action}s specified with
- * {@link Notification.Builder#addAction(int, CharSequence, PendingIntent) addAction} will be
+ * {@link Notification.Builder#addAction(Action) addAction} will be
* shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to
* {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will be
* treated as album artwork.
@@ -4391,7 +4440,7 @@ public class Notification implements Parcelable
private RemoteViews generateMediaActionButton(Action action) {
final boolean tombstone = (action.actionIntent == null);
- RemoteViews button = new RemoteViews(mBuilder.mContext.getPackageName(),
+ RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(),
R.layout.notification_material_media_action);
button.setImageViewResource(R.id.action0, action.icon);
button.setDrawableParameters(R.id.action0, false, -1,
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 10e8a53..01a1c18 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -691,6 +691,9 @@ final class SystemServiceRegistry {
@Override
public MidiManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.MIDI_SERVICE);
+ if (b == null) {
+ return null;
+ }
return new MidiManager(IMidiManager.Stub.asInterface(b));
}});
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 40126d6..ee0fc91 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.ComponentName;
import android.graphics.Matrix;
import android.graphics.Rect;
+import android.os.BadParcelableException;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -31,8 +32,12 @@ public class AssistStructure implements Parcelable {
static final String TAG = "AssistStructure";
static final boolean DEBUG_PARCEL = false;
+ static final boolean DEBUG_PARCEL_CHILDREN = false;
static final boolean DEBUG_PARCEL_TREE = false;
+ static final int VALIDATE_WINDOW_TOKEN = 0x11111111;
+ static final int VALIDATE_VIEW_TOKEN = 0x22222222;
+
boolean mHaveData;
ComponentName mActivityComponent;
@@ -173,6 +178,26 @@ public class AssistStructure implements Parcelable {
mCurViewStackEntry = entry;
}
+ void writeView(ViewNode child, Parcel out, PooledStringWriter pwriter, int levelAdj) {
+ if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition()
+ + ", windows=" + mNumWrittenWindows
+ + ", views=" + mNumWrittenViews
+ + ", level=" + (mCurViewStackPos+levelAdj));
+ out.writeInt(VALIDATE_VIEW_TOKEN);
+ int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix);
+ mNumWrittenViews++;
+ // If the child has children, push it on the stack to write them next.
+ if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) {
+ if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG,
+ "Preparing to write " + child.mChildren.length
+ + " children: @ #" + mNumWrittenViews
+ + ", level " + (mCurViewStackPos+levelAdj));
+ out.writeInt(child.mChildren.length);
+ int pos = ++mCurViewStackPos;
+ pushViewStackEntry(child, pos);
+ }
+ }
+
boolean writeNextEntryToParcel(AssistStructure as, Parcel out, PooledStringWriter pwriter) {
// Write next view node if appropriate.
if (mCurViewStackEntry != null) {
@@ -182,20 +207,7 @@ public class AssistStructure implements Parcelable {
+ mCurViewStackEntry.curChild + " in " + mCurViewStackEntry.node);
ViewNode child = mCurViewStackEntry.node.mChildren[mCurViewStackEntry.curChild];
mCurViewStackEntry.curChild++;
- if (DEBUG_PARCEL) Log.d(TAG, "write view: at " + out.dataPosition()
- + ", windows=" + mNumWrittenWindows
- + ", views=" + mNumWrittenViews);
- out.writeInt(1);
- int flags = child.writeSelfToParcel(out, pwriter, mTmpMatrix);
- mNumWrittenViews++;
- // If the child has children, push it on the stack to write them next.
- if ((flags&ViewNode.FLAGS_HAS_CHILDREN) != 0) {
- if (DEBUG_PARCEL_TREE) Log.d(TAG, "Preparing to write "
- + child.mChildren.length + " children under " + child);
- out.writeInt(child.mChildren.length);
- int pos = ++mCurViewStackPos;
- pushViewStackEntry(child, pos);
- }
+ writeView(child, out, pwriter, 1);
return true;
}
@@ -223,13 +235,13 @@ public class AssistStructure implements Parcelable {
if (DEBUG_PARCEL) Log.d(TAG, "write window #" + pos + ": at " + out.dataPosition()
+ ", windows=" + mNumWrittenWindows
+ ", views=" + mNumWrittenViews);
- out.writeInt(1);
+ out.writeInt(VALIDATE_WINDOW_TOKEN);
win.writeSelfToParcel(out, pwriter, mTmpMatrix);
mNumWrittenWindows++;
ViewNode root = win.mRoot;
mCurViewStackPos = 0;
- if (DEBUG_PARCEL_TREE) Log.d(TAG, "Pushing initial root view " + root);
- pushViewStackEntry(root, 0);
+ if (DEBUG_PARCEL_TREE) Log.d(TAG, "Writing initial root view " + root);
+ writeView(root, out, pwriter, 0);
return true;
}
@@ -271,11 +283,16 @@ public class AssistStructure implements Parcelable {
+ ", views=" + mNumReadViews);
}
- Parcel readParcel() {
+ Parcel readParcel(int validateToken, int level) {
if (DEBUG_PARCEL) Log.d(TAG, "readParcel: at " + mCurParcel.dataPosition()
+ ", avail=" + mCurParcel.dataAvail() + ", windows=" + mNumReadWindows
- + ", views=" + mNumReadViews);
- if (mCurParcel.readInt() != 0) {
+ + ", views=" + mNumReadViews + ", level=" + level);
+ int token = mCurParcel.readInt();
+ if (token != 0) {
+ if (token != validateToken) {
+ throw new BadParcelableException("Got token " + Integer.toHexString(token)
+ + ", expected token " + Integer.toHexString(validateToken));
+ }
return mCurParcel;
}
// We have run out of partial data, need to read another batch.
@@ -406,7 +423,7 @@ public class AssistStructure implements Parcelable {
}
WindowNode(ParcelTransferReader reader) {
- Parcel in = reader.readParcel();
+ Parcel in = reader.readParcel(VALIDATE_WINDOW_TOKEN, 0);
reader.mNumReadWindows++;
mX = in.readInt();
mY = in.readInt();
@@ -414,7 +431,7 @@ public class AssistStructure implements Parcelable {
mHeight = in.readInt();
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mDisplayId = in.readInt();
- mRoot = new ViewNode(reader);
+ mRoot = new ViewNode(reader, 0);
}
void writeSelfToParcel(Parcel out, PooledStringWriter pwriter, float[] tmpMatrix) {
@@ -548,8 +565,8 @@ public class AssistStructure implements Parcelable {
ViewNode() {
}
- ViewNode(ParcelTransferReader reader) {
- final Parcel in = reader.readParcel();
+ ViewNode(ParcelTransferReader reader, int nestingLevel) {
+ final Parcel in = reader.readParcel(VALIDATE_VIEW_TOKEN, nestingLevel);
reader.mNumReadViews++;
final PooledStringReader preader = reader.mStringReader;
mClassName = preader.readString();
@@ -604,9 +621,13 @@ public class AssistStructure implements Parcelable {
}
if ((flags&FLAGS_HAS_CHILDREN) != 0) {
final int NCHILDREN = in.readInt();
+ if (DEBUG_PARCEL_TREE || DEBUG_PARCEL_CHILDREN) Log.d(TAG,
+ "Preparing to read " + NCHILDREN
+ + " children: @ #" + reader.mNumReadViews
+ + ", level " + nestingLevel);
mChildren = new ViewNode[NCHILDREN];
for (int i=0; i<NCHILDREN; i++) {
- mChildren[i] = new ViewNode(reader);
+ mChildren[i] = new ViewNode(reader, nestingLevel + 1);
}
}
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index e09ab56..2ba8774 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -79,6 +79,10 @@ public final class BluetoothLeScanner {
* delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * An app must hold
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+ * in order to get results.
*
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code callback} is null.
@@ -95,6 +99,10 @@ public final class BluetoothLeScanner {
* Start Bluetooth LE scan. The scan results will be delivered through {@code callback}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * An app must hold
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+ * in order to get results.
*
* @param filters {@link ScanFilter}s for finding exact BLE devices.
* @param settings Settings for the scan.
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 3cc7684..ba9cf7c 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -16,8 +16,11 @@
package android.content;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_ERRORED;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -40,8 +43,8 @@ import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.UserHandle;
-import android.util.Log;
import android.text.TextUtils;
+import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
@@ -474,14 +477,9 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
- enforceReadPermissionInner(uri, callerToken);
-
- final int permOp = AppOpsManager.permissionToOpCode(mReadPermission);
- if (permOp != AppOpsManager.OP_NONE) {
- final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
- if (mode != AppOpsManager.MODE_ALLOWED) {
- return mode;
- }
+ final int mode = enforceReadPermissionInner(uri, callingPkg, callerToken);
+ if (mode != MODE_ALLOWED) {
+ return mode;
}
if (mReadOp != AppOpsManager.OP_NONE) {
@@ -493,14 +491,9 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
- enforceWritePermissionInner(uri, callerToken);
-
- final int permOp = AppOpsManager.permissionToOpCode(mWritePermission);
- if (permOp != AppOpsManager.OP_NONE) {
- final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
- if (mode != AppOpsManager.MODE_ALLOWED) {
- return mode;
- }
+ final int mode = enforceWritePermissionInner(uri, callingPkg, callerToken);
+ if (mode != MODE_ALLOWED) {
+ return mode;
}
if (mWriteOp != AppOpsManager.OP_NONE) {
@@ -518,26 +511,47 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
== PERMISSION_GRANTED;
}
+ /**
+ * Verify that calling app holds both the given permission and any app-op
+ * associated with that permission.
+ */
+ private int checkPermissionAndAppOp(String permission, String callingPkg,
+ IBinder callerToken) {
+ if (getContext().checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid(),
+ callerToken) != PERMISSION_GRANTED) {
+ return MODE_ERRORED;
+ }
+
+ final int permOp = AppOpsManager.permissionToOpCode(permission);
+ if (permOp != AppOpsManager.OP_NONE) {
+ return mTransport.mAppOpsManager.noteProxyOp(permOp, callingPkg);
+ }
+
+ return MODE_ALLOWED;
+ }
+
/** {@hide} */
- protected void enforceReadPermissionInner(Uri uri, IBinder callerToken)
+ protected int enforceReadPermissionInner(Uri uri, String callingPkg, IBinder callerToken)
throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
String missingPerm = null;
+ int strongestMode = MODE_ALLOWED;
if (UserHandle.isSameApp(uid, mMyUid)) {
- return;
+ return MODE_ALLOWED;
}
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getReadPermission();
if (componentPerm != null) {
- if (context.checkPermission(componentPerm, pid, uid, callerToken)
- == PERMISSION_GRANTED) {
- return;
+ final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
+ if (mode == MODE_ALLOWED) {
+ return MODE_ALLOWED;
} else {
missingPerm = componentPerm;
+ strongestMode = Math.max(strongestMode, mode);
}
}
@@ -551,14 +565,15 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
for (PathPermission pp : pps) {
final String pathPerm = pp.getReadPermission();
if (pathPerm != null && pp.match(path)) {
- if (context.checkPermission(pathPerm, pid, uid, callerToken)
- == PERMISSION_GRANTED) {
- return;
+ final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
+ if (mode == MODE_ALLOWED) {
+ return MODE_ALLOWED;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultRead = false;
missingPerm = pathPerm;
+ strongestMode = Math.max(strongestMode, mode);
}
}
}
@@ -566,7 +581,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
// if we passed <path-permission> checks above, and no default
// <provider> permission, then allow access.
- if (allowDefaultRead) return;
+ if (allowDefaultRead) return MODE_ALLOWED;
}
// last chance, check against any uri grants
@@ -575,7 +590,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
? maybeAddUserId(uri, callingUserId) : uri;
if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION,
callerToken) == PERMISSION_GRANTED) {
- return;
+ return MODE_ALLOWED;
+ }
+
+ // If the worst denial we found above was ignored, then pass that
+ // ignored through; otherwise we assume it should be a real error below.
+ if (strongestMode == MODE_IGNORED) {
+ return MODE_IGNORED;
}
final String failReason = mExported
@@ -587,25 +608,27 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
}
/** {@hide} */
- protected void enforceWritePermissionInner(Uri uri, IBinder callerToken)
+ protected int enforceWritePermissionInner(Uri uri, String callingPkg, IBinder callerToken)
throws SecurityException {
final Context context = getContext();
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
String missingPerm = null;
+ int strongestMode = MODE_ALLOWED;
if (UserHandle.isSameApp(uid, mMyUid)) {
- return;
+ return MODE_ALLOWED;
}
if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getWritePermission();
if (componentPerm != null) {
- if (context.checkPermission(componentPerm, pid, uid, callerToken)
- == PERMISSION_GRANTED) {
- return;
+ final int mode = checkPermissionAndAppOp(componentPerm, callingPkg, callerToken);
+ if (mode == MODE_ALLOWED) {
+ return MODE_ALLOWED;
} else {
missingPerm = componentPerm;
+ strongestMode = Math.max(strongestMode, mode);
}
}
@@ -619,14 +642,15 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
for (PathPermission pp : pps) {
final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) {
- if (context.checkPermission(pathPerm, pid, uid, callerToken)
- == PERMISSION_GRANTED) {
- return;
+ final int mode = checkPermissionAndAppOp(pathPerm, callingPkg, callerToken);
+ if (mode == MODE_ALLOWED) {
+ return MODE_ALLOWED;
} else {
// any denied <path-permission> means we lose
// default <provider> access.
allowDefaultWrite = false;
missingPerm = pathPerm;
+ strongestMode = Math.max(strongestMode, mode);
}
}
}
@@ -634,13 +658,19 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
// if we passed <path-permission> checks above, and no default
// <provider> permission, then allow access.
- if (allowDefaultWrite) return;
+ if (allowDefaultWrite) return MODE_ALLOWED;
}
// last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
callerToken) == PERMISSION_GRANTED) {
- return;
+ return MODE_ALLOWED;
+ }
+
+ // If the worst denial we found above was ignored, then pass that
+ // ignored through; otherwise we assume it should be a real error below.
+ if (strongestMode == MODE_IGNORED) {
+ return MODE_IGNORED;
}
final String failReason = mExported
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5571662..f786d2f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1023,7 +1023,7 @@ public class Intent implements Parcelable, Cloneable {
*
* <p>Note: if you app targets {@link android.os.Build.VERSION_CODES#MNC MNC}
* and above and declares as using the {@link android.Manifest.permission#CALL_PHONE}
- * permission which is not granted, then atempting to use this action will
+ * permission which is not granted, then attempting to use this action will
* result in a {@link java.lang.SecurityException}.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index ceb610a..bc24d67 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -253,7 +253,7 @@ interface IPackageManager {
List<PackageInfo> getPreferredPackages(int flags);
- void resetPreferredActivities(int userId);
+ void resetApplicationPreferences(int userId);
ResolveInfo getLastChosenActivity(in Intent intent,
String resolvedType, int flags);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index b7ee82d..9341be1 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -18,8 +18,10 @@ package android.content.pm;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
@@ -889,6 +891,8 @@ public class PackageInstaller {
public String abiOverride;
/** {@hide} */
public String volumeUuid;
+ /** {@hide} */
+ public String[] grantedRuntimePermissions;
/**
* Construct parameters for a new package install session.
@@ -914,6 +918,7 @@ public class PackageInstaller {
referrerUri = source.readParcelable(null);
abiOverride = source.readString();
volumeUuid = source.readString();
+ grantedRuntimePermissions = source.readStringArray();
}
/**
@@ -987,6 +992,23 @@ public class PackageInstaller {
this.referrerUri = referrerUri;
}
+ /**
+ * Sets which runtime permissions to be granted to the package at installation.
+ * Using this API requires holding {@link android.Manifest.permission
+ * #INSTALL_GRANT_RUNTIME_PERMISSIONS}
+ *
+ * @param permissions The permissions to grant or null to grant all runtime
+ * permissions.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS)
+ public void setGrantedRuntimePermissions(String[] permissions) {
+ installFlags |= PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS;
+ this.grantedRuntimePermissions = permissions;
+ }
+
/** {@hide} */
public void setInstallFlagsInternal() {
installFlags |= PackageManager.INSTALL_INTERNAL;
@@ -1012,6 +1034,7 @@ public class PackageInstaller {
pw.printPair("referrerUri", referrerUri);
pw.printPair("abiOverride", abiOverride);
pw.printPair("volumeUuid", volumeUuid);
+ pw.printPair("grantedRuntimePermissions", grantedRuntimePermissions);
pw.println();
}
@@ -1033,6 +1056,7 @@ public class PackageInstaller {
dest.writeParcelable(referrerUri, flags);
dest.writeString(abiOverride);
dest.writeString(volumeUuid);
+ dest.writeStringArray(grantedRuntimePermissions);
}
public static final Parcelable.Creator<SessionParams>
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6533bbc..cda5816 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1514,6 +1514,13 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device has biometric hardware to detect a fingerprint.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_FINGERPRINT = "android.hardware.fingerprint";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports portrait orientation
* screens. For backwards compatibility, you can assume that if neither
* this nor {@link #FEATURE_SCREEN_LANDSCAPE} is set then the device supports
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
index 2828d83..d514513 100644
--- a/core/java/android/content/pm/PermissionInfo.java
+++ b/core/java/android/content/pm/PermissionInfo.java
@@ -145,12 +145,10 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_COSTS_MONEY = 1<<0;
/**
- * Flag for {@link #protectionLevel}, corresponding
- * to the <code>hide</code> value of
- * {@link android.R.attr#permissionFlags}.
- * @hide
+ * Flag for {@link #flags}, indicating that this permission has been
+ * installed into the system's globally defined permissions.
*/
- public static final int PROTECTION_FLAG_HIDE = 1<<1;
+ public static final int FLAG_INSTALLED = 1<<30;
/**
* Additional flags about this permission as given by
@@ -210,6 +208,15 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
protLevel += "|pre23";
}
+ if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) {
+ protLevel += "|installer";
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) {
+ protLevel += "|verifier";
+ }
+ if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) {
+ protLevel += "|preinstalled";
+ }
return protLevel;
}
diff --git a/core/java/android/content/res/DrawableCache.java b/core/java/android/content/res/DrawableCache.java
index fc70bc6..ba00134 100644
--- a/core/java/android/content/res/DrawableCache.java
+++ b/core/java/android/content/res/DrawableCache.java
@@ -52,6 +52,6 @@ class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> {
@Override
public boolean shouldInvalidateEntry(Drawable.ConstantState entry, int configChanges) {
- return false;
+ return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());
}
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index 46cafad..46ffe36 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -138,6 +138,45 @@ public abstract class CameraCaptureSession implements AutoCloseable {
*/
public abstract void prepare(@NonNull Surface surface) throws CameraAccessException;
+
+ /**
+ * <p>Free all buffers allocated for an output Surface.</p>
+ *
+ * <p>Normally, once allocated, the image buffers for a given output Surface remain allocated
+ * for the lifetime of the capture session, to minimize latency of captures and to reduce
+ * memory allocation overhead.</p>
+ *
+ * <p>However, in some cases, it may be desirable for allocated buffers to be freed to reduce
+ * the application's memory consumption, if the particular output Surface will not be used by
+ * the application for some time.</p>
+ *
+ * <p>The tearDown() method can be used to perform this operation. After the call finishes, all
+ * unfilled image buffers will have been freed. Any future use of the target Surface may require
+ * allocation of additional buffers, as if the session had just been created. Buffers being
+ * held by the application (either explicitly as Image objects from ImageReader, or implicitly
+ * as the current texture in a SurfaceTexture or the current contents of a RS Allocation, will
+ * remain valid and allocated even when tearDown is invoked.</p>
+ *
+ * <p>A Surface that has had tearDown() called on it is eligible to have prepare() invoked on it
+ * again even if it was used as a request target before the tearDown() call, as long as it
+ * doesn't get used as a target of a request between the tearDown() and prepare() calls.</p>
+ *
+ * @param surface the output Surface for which buffers should be freed. Must be one of the
+ * the output Surfaces used to create this session.
+ *
+ * @throws CameraAccessException if the camera device is no longer connected or has
+ * encountered a fatal error.
+ * @throws IllegalStateException if this session is no longer active, either because the session
+ * was explicitly closed, a new session has been created
+ * or the camera device has been closed.
+ * @throws IllegalArgumentException if the Surface is invalid, not part of this Session, or has
+ * already been used as a target of a CaptureRequest in this
+ * session or immediately prior sessions.
+ *
+ * @hide
+ */
+ public abstract void tearDown(@NonNull Surface surface) throws CameraAccessException;
+
/**
* <p>Submit a request for an image to be captured by the camera device.</p>
*
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index c36683b..af1367c 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1994,8 +1994,9 @@ public abstract class CameraMetadata<TKey> {
public static final int EDGE_MODE_OFF = 0;
/**
- * <p>Apply edge enhancement at a quality level that does not slow down frame rate relative to sensor
- * output</p>
+ * <p>Apply edge enhancement at a quality level that does not slow down frame rate
+ * relative to sensor output. It may be the same as OFF if edge enhancement will
+ * slow down frame rate relative to sensor.</p>
* @see CaptureRequest#EDGE_MODE
*/
public static final int EDGE_MODE_FAST = 1;
@@ -2117,7 +2118,8 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>Noise reduction is applied without reducing frame rate relative to sensor
- * output.</p>
+ * output. It may be the same as OFF if noise reduction will reduce frame rate
+ * relative to sensor.</p>
* @see CaptureRequest#NOISE_REDUCTION_MODE
*/
public static final int NOISE_REDUCTION_MODE_FAST = 1;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a136d0f..e965d65 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -1584,8 +1584,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* will be applied. HIGH_QUALITY mode indicates that the
* camera device will use the highest-quality enhancement algorithms,
* even if it slows down capture rate. FAST means the camera device will
- * not slow down capture rate when applying edge enhancement. Every output stream will
- * have a similar amount of enhancement applied.</p>
+ * not slow down capture rate when applying edge enhancement. FAST may be the same as OFF if
+ * edge enhancement will slow down capture rate. Every output stream will have a similar
+ * amount of enhancement applied.</p>
* <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
* buffer of high-resolution images during preview and reprocess image(s) from that buffer
* into a final capture when triggered by the user. In this mode, the camera device applies
@@ -1594,7 +1595,7 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* since those will be reprocessed later if necessary.</p>
* <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera
* device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
- * The camera device may adjust its internal noise reduction parameters for best
+ * The camera device may adjust its internal edge enhancement parameters for best
* image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
@@ -2003,8 +2004,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
* even if it slows down capture rate. FAST means the camera device will not
- * slow down capture rate when applying noise filtering. Every output stream will
- * have a similar amount of enhancement applied.</p>
+ * slow down capture rate when applying noise filtering. FAST may be the same as MINIMAL if
+ * MINIMAL is listed, or the same as OFF if any noise filtering will slow down capture rate.
+ * Every output stream will have a similar amount of enhancement applied.</p>
* <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
* buffer of high-resolution images during preview and reprocess image(s) from that buffer
* into a final capture when triggered by the user. In this mode, the camera device applies
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index f7cf185..d5511c1 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2095,8 +2095,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* will be applied. HIGH_QUALITY mode indicates that the
* camera device will use the highest-quality enhancement algorithms,
* even if it slows down capture rate. FAST means the camera device will
- * not slow down capture rate when applying edge enhancement. Every output stream will
- * have a similar amount of enhancement applied.</p>
+ * not slow down capture rate when applying edge enhancement. FAST may be the same as OFF if
+ * edge enhancement will slow down capture rate. Every output stream will have a similar
+ * amount of enhancement applied.</p>
* <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
* buffer of high-resolution images during preview and reprocess image(s) from that buffer
* into a final capture when triggered by the user. In this mode, the camera device applies
@@ -2105,7 +2106,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* since those will be reprocessed later if necessary.</p>
* <p>For YUV_REPROCESSING, these FAST/HIGH_QUALITY modes both mean that the camera
* device will apply FAST/HIGH_QUALITY YUV-domain edge enhancement, respectively.
- * The camera device may adjust its internal noise reduction parameters for best
+ * The camera device may adjust its internal edge enhancement parameters for best
* image quality based on the {@link CaptureRequest#REPROCESS_EFFECTIVE_EXPOSURE_FACTOR android.reprocess.effectiveExposureFactor}, if it is set.</p>
* <p><b>Possible values:</b>
* <ul>
@@ -2786,8 +2787,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* will be applied. HIGH_QUALITY mode indicates that the camera device
* will use the highest-quality noise filtering algorithms,
* even if it slows down capture rate. FAST means the camera device will not
- * slow down capture rate when applying noise filtering. Every output stream will
- * have a similar amount of enhancement applied.</p>
+ * slow down capture rate when applying noise filtering. FAST may be the same as MINIMAL if
+ * MINIMAL is listed, or the same as OFF if any noise filtering will slow down capture rate.
+ * Every output stream will have a similar amount of enhancement applied.</p>
* <p>ZERO_SHUTTER_LAG is meant to be used by applications that maintain a continuous circular
* buffer of high-resolution images during preview and reprocess image(s) from that buffer
* into a final capture when triggered by the user. In this mode, the camera device applies
diff --git a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
index 1574f93..7cb3673 100644
--- a/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
+++ b/core/java/android/hardware/camera2/ICameraDeviceUser.aidl
@@ -100,4 +100,6 @@ interface ICameraDeviceUser
int flush(out LongParcelable lastFrameNumber);
int prepare(int streamId);
+
+ int tearDown(int streamId);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 3c19cd2..d325c77 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -146,6 +146,11 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession
}
@Override
+ public void tearDown(Surface surface) throws CameraAccessException {
+ mDeviceImpl.tearDown(surface);
+ }
+
+ @Override
public synchronized int capture(CaptureRequest request, CaptureCallback callback,
Handler handler) throws CameraAccessException {
if (request == null) {
diff --git a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
index d732535..a920e2b 100644
--- a/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraConstrainedHighSpeedCaptureSessionImpl.java
@@ -169,6 +169,11 @@ public class CameraConstrainedHighSpeedCaptureSessionImpl
}
@Override
+ public void tearDown(Surface surface) throws CameraAccessException {
+ mSessionImpl.tearDown(surface);
+ }
+
+ @Override
public int capture(CaptureRequest request, CaptureCallback listener, Handler handler)
throws CameraAccessException {
throw new UnsupportedOperationException("Constrained high speed session doesn't support"
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index c594228..91d623e 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -679,6 +679,31 @@ public class CameraDeviceImpl extends CameraDevice {
}
}
+ public void tearDown(Surface surface) throws CameraAccessException {
+ if (surface == null) throw new IllegalArgumentException("Surface is null");
+
+ synchronized(mInterfaceLock) {
+ int streamId = -1;
+ for (int i = 0; i < mConfiguredOutputs.size(); i++) {
+ if (surface == mConfiguredOutputs.valueAt(i).getSurface()) {
+ streamId = mConfiguredOutputs.keyAt(i);
+ break;
+ }
+ }
+ if (streamId == -1) {
+ throw new IllegalArgumentException("Surface is not part of this session");
+ }
+ try {
+ mRemoteDevice.tearDown(streamId);
+ } catch (CameraRuntimeException e) {
+ throw e.asChecked();
+ } catch (RemoteException e) {
+ // impossible
+ return;
+ }
+ }
+ }
+
public int capture(CaptureRequest request, CaptureCallback callback, Handler handler)
throws CameraAccessException {
if (DEBUG) {
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index f5314da..e20eaa7 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -636,6 +636,20 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
return CameraBinderDecorator.NO_ERROR;
}
+ public int tearDown(int streamId) {
+ if (DEBUG) {
+ Log.d(TAG, "tearDown called.");
+ }
+ if (mLegacyDevice.isClosed()) {
+ Log.e(TAG, "Cannot tear down stream, device has been closed.");
+ return CameraBinderDecorator.ENODEV;
+ }
+
+ // LEGACY doesn't support actual teardown, so just a no-op
+
+ return CameraBinderDecorator.NO_ERROR;
+ }
+
@Override
public IBinder asBinder() {
// This is solely intended to be used for in-process binding.
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index c5f142a..ee37047 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -321,6 +321,14 @@ public class FingerprintManager {
* Called when a fingerprint is valid but not recognized.
*/
public void onAuthenticationFailed() { }
+
+ /**
+ * Called when a fingerprint image has been acquired, but wasn't processed yet.
+ *
+ * @param acquireInfo one of FINGERPRINT_ACQUIRED_* constants
+ * @hide
+ */
+ public void onAuthenticationAcquired(int acquireInfo) {}
};
/**
@@ -737,9 +745,13 @@ public class FingerprintManager {
}
private void sendAcquiredResult(long deviceId, int acquireInfo) {
+ if (mAuthenticationCallback != null) {
+ mAuthenticationCallback.onAuthenticationAcquired(acquireInfo);
+ }
final String msg = getAcquiredString(acquireInfo);
- if (msg == null) return;
-
+ if (msg == null) {
+ return;
+ }
if (mEnrollmentCallback != null) {
mEnrollmentCallback.onEnrollmentHelp(acquireInfo, msg);
} else if (mAuthenticationCallback != null) {
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index b039fc7..a2c1d18 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -103,8 +103,12 @@ public class ExtractEditText extends EditText {
}
@Override public boolean onTextContextMenuItem(int id) {
- // Select all shouldn't be handled by the original edit text, but by the extracted one.
- if (id != android.R.id.selectAll && mIME != null && mIME.onExtractTextContextMenuItem(id)) {
+ // Select all and Replace text shouldn't be handled by the original edit text, but by the
+ // extracted one.
+ if (id == android.R.id.selectAll || id == android.R.id.replaceText) {
+ return super.onTextContextMenuItem(id);
+ }
+ if (mIME != null && mIME.onExtractTextContextMenuItem(id)) {
// Mode was started on Extracted, needs to be stopped here.
// Cut will change the text, which stops selection mode.
if (id == android.R.id.copy || id == android.R.id.paste) stopTextActionMode();
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 864225a..af4c2bc 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.NonNull;
import android.provider.DocumentsContract.Document;
import android.system.ErrnoException;
import android.system.Os;
@@ -69,6 +70,8 @@ public class FileUtils {
/** Regular expression for safe filenames: no spaces or metacharacters */
private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+");
+ private static final File[] EMPTY = new File[0];
+
/**
* Set owner and mode of of given {@link File}.
*
@@ -634,4 +637,13 @@ public class FileUtils {
return new File(parent, name + "." + ext);
}
}
+
+ public static @NonNull File[] listFilesOrEmpty(File dir) {
+ File[] res = dir.listFiles();
+ if (res != null) {
+ return res;
+ } else {
+ return EMPTY;
+ }
+ }
}
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index b768852..d3eec1e 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -29,5 +29,6 @@ interface IDeviceIdleController {
boolean isPowerSaveWhitelistApp(String name);
void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason);
long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason);
+ long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason);
void exitIdle(String reason);
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index b104135..79fb805 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -45,7 +45,9 @@ public class UserManager {
private final Context mContext;
/**
- * Specifies if a user is disallowed from adding and removing accounts.
+ * Specifies if a user is disallowed from adding and removing accounts, unless they are
+ * {@link android.accounts.AccountManager#addAccountExplicitly programmatically} added by
+ * Authenticator.
* The default value is <code>false</code>.
*
* <p/>Key for user restrictions.
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index d743484..aa22041 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -2393,7 +2393,7 @@ public final class CalendarContract {
intent.setData(ContentUris.withAppendedId(CalendarContract.CONTENT_URI, alarmTime));
intent.putExtra(ALARM_TIME, alarmTime);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
- manager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pi);
+ manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pi);
}
/**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index d547a60..8ce1cbf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -5957,9 +5957,7 @@ public final class ContactsContract {
*/
public static final CharSequence getTypeLabel(Resources res, int type,
CharSequence label) {
- if (type == TYPE_CUSTOM) {
- return (label != null ? label : "");
- } else if (type == TYPE_ASSISTANT && !TextUtils.isEmpty(label)) {
+ if ((type == TYPE_CUSTOM || type == TYPE_ASSISTANT) && !TextUtils.isEmpty(label)) {
return label;
} else {
final int labelRes = getTypeLabelResource(type);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 6979bee..5a341fc 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -640,7 +640,7 @@ public abstract class DocumentsProvider extends ContentProvider {
final Bundle out = new Bundle();
try {
if (METHOD_CREATE_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), null);
final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
@@ -654,7 +654,7 @@ public abstract class DocumentsProvider extends ContentProvider {
out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
} else if (METHOD_RENAME_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), null);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
final String newDocumentId = renameDocument(documentId, displayName);
@@ -678,7 +678,7 @@ public abstract class DocumentsProvider extends ContentProvider {
}
} else if (METHOD_DELETE_DOCUMENT.equals(method)) {
- enforceWritePermissionInner(documentUri, null);
+ enforceWritePermissionInner(documentUri, getCallingPackage(), null);
deleteDocument(documentId);
// Document no longer exists, clean up any grants
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fff355b..a79970c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7578,14 +7578,6 @@ public final class Settings {
public static final String WFC_IMS_ROAMING_ENABLED = "wfc_ims_roaming_enabled";
/**
- * Global override to disable VoLTE (independent of user setting)
- * <p>
- * Type: int (1 for disable VoLTE, 0 to use user configuration)
- * @hide
- */
- public static final String VOLTE_FEATURE_DISABLED = "volte_feature_disabled";
-
- /**
* Whether user can enable/disable LTE as a preferred network. A carrier might control
* this via gservices, OMA-DM, carrier app, etc.
* <p>
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index e1b5a6d..76eaea9 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -314,11 +314,16 @@ public class VoicemailContract {
contentValues.put(Voicemails.IS_READ, voicemail.isRead() ? 1 : 0);
PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount();
- if (voicemail.getPhoneAccount() != null) {
+ if (phoneAccount != null) {
contentValues.put(Voicemails.PHONE_ACCOUNT_COMPONENT_NAME,
phoneAccount.getComponentName().flattenToString());
contentValues.put(Voicemails.PHONE_ACCOUNT_ID, phoneAccount.getId());
}
+
+ if (voicemail.getTranscription() != null) {
+ contentValues.put(Voicemails.TRANSCRIPTION, voicemail.getTranscription());
+ }
+
return contentValues;
}
}
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index bae5455..04d5952 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -51,6 +51,7 @@ public final class KeymasterDefs {
public static final int KM_TAG_DIGEST = KM_ENUM_REP | 5;
public static final int KM_TAG_PADDING = KM_ENUM_REP | 6;
public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 7;
+ public static final int KM_TAG_MIN_MAC_LENGTH = KM_UINT | 8;
public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101;
public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102;
@@ -194,6 +195,9 @@ public final class KeymasterDefs {
public static final int KM_ERROR_KEY_RATE_LIMIT_EXCEEDED = -54;
public static final int KM_ERROR_CALLER_NONCE_PROHIBITED = -55;
public static final int KM_ERROR_KEY_MAX_OPS_EXCEEDED = -56;
+ public static final int KM_ERROR_INVALID_MAC_LENGTH = -57;
+ public static final int KM_ERROR_MISSING_MIN_MAC_LENGTH = -58;
+ public static final int KM_ERROR_UNSUPPORTED_MIN_MAC_LENGTH = -59;
public static final int KM_ERROR_UNIMPLEMENTED = -100;
public static final int KM_ERROR_VERSION_MISMATCH = -101;
public static final int KM_ERROR_UNKNOWN_ERROR = -1000;
@@ -237,6 +241,8 @@ public final class KeymasterDefs {
sErrorCodeToString.put(KM_ERROR_INVALID_NONCE, "Invalid IV");
sErrorCodeToString.put(KM_ERROR_CALLER_NONCE_PROHIBITED,
"Caller-provided IV not permitted");
+ sErrorCodeToString.put(KM_ERROR_INVALID_MAC_LENGTH,
+ "Invalid MAC or authentication tag length");
sErrorCodeToString.put(KM_ERROR_UNIMPLEMENTED, "Not implemented");
sErrorCodeToString.put(KM_ERROR_UNKNOWN_ERROR, "Unknown error");
}
diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java
index 50c435a..c2f70cc 100644
--- a/core/java/android/service/chooser/ChooserTarget.java
+++ b/core/java/android/service/chooser/ChooserTarget.java
@@ -17,20 +17,14 @@
package android.service.chooser;
-import android.app.Activity;
-import android.app.PendingIntent;
+import android.annotation.Nullable;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.UserHandle;
-import android.util.Log;
/**
* A ChooserTarget represents a deep-link into an application as returned by a
@@ -62,52 +56,21 @@ public final class ChooserTarget implements Parcelable {
private Icon mIcon;
/**
- * The IntentSender that will be used to deliver the intent to the target.
- * It will be {@link android.content.Intent#fillIn(android.content.Intent, int)} filled in}
- * by the real intent sent by the application.
+ * The ComponentName of the Activity to be invoked. Must be part of the target creator's
+ * own package or an Activity exported by its package.
*/
- private IntentSender mIntentSender;
+ private ComponentName mComponentName;
/**
- * The score given to this item. It can be normalized.
+ * A Bundle to merge with the extras of the intent sent to this target.
+ * Any extras here will override the extras from the original intent.
*/
- private float mScore;
+ private Bundle mIntentExtras;
/**
- * Construct a deep link target for presentation by a chooser UI.
- *
- * <p>A target is composed of a title and an icon for presentation to the user.
- * The UI presenting this target may truncate the title if it is too long to be presented
- * in the available space, as well as crop, resize or overlay the supplied icon.</p>
- *
- * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
- * to the other targets supplied by the same
- * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
- * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
- * Scores for a set of targets do not need to sum to 1.</p>
- *
- * <p>Before being sent, the PendingIntent supplied will be
- * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
- * to the chooser. When constructing a PendingIntent for use in a ChooserTarget, make sure
- * that you permit the relevant fields to be filled in using the appropriate flags such as
- * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES},
- * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that
- * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants
- * for {@link Intent#ACTION_SEND} intents.</p>
- *
- * <p>Take care not to place custom {@link android.os.Parcelable} types into
- * the PendingIntent as extras, as the system will not be able to unparcel it to merge
- * additional extras.</p>
- *
- * @param title title of this target that will be shown to a user
- * @param icon icon to represent this target
- * @param score ranking score for this target between 0.0f and 1.0f, inclusive
- * @param pendingIntent PendingIntent to fill in and send if the user chooses this target
+ * The score given to this item. It can be normalized.
*/
- public ChooserTarget(CharSequence title, Icon icon, float score,
- PendingIntent pendingIntent) {
- this(title, icon, score, pendingIntent.getIntentSender());
- }
+ private float mScore;
/**
* Construct a deep link target for presentation by a chooser UI.
@@ -122,25 +85,23 @@ public final class ChooserTarget implements Parcelable {
* Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
* Scores for a set of targets do not need to sum to 1.</p>
*
- * <p>Before being sent, the IntentSender supplied will be
- * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
- * to the chooser. When constructing an IntentSender for use in a ChooserTarget, make sure
- * that you permit the relevant fields to be filled in using the appropriate flags such as
- * {@link Intent#FILL_IN_ACTION}, {@link Intent#FILL_IN_CATEGORIES},
- * {@link Intent#FILL_IN_DATA} and {@link Intent#FILL_IN_CLIP_DATA}. Note that
- * {@link Intent#FILL_IN_CLIP_DATA} is required to appropriately receive URI permission grants
- * for {@link Intent#ACTION_SEND} intents.</p>
+ * <p>The ComponentName must be the name of an Activity component in the creator's own
+ * package, or an exported component from any other package. You may provide an optional
+ * Bundle of extras that will be merged into the final intent before it is sent to the
+ * target Activity; use this to add any additional data about the deep link that the target
+ * activity will read. e.g. conversation IDs, email addresses, etc.</p>
*
* <p>Take care not to place custom {@link android.os.Parcelable} types into
- * the IntentSender as extras, as the system will not be able to unparcel it to merge
- * additional extras.</p>
+ * the extras bundle, as the system will not be able to unparcel them to merge them.</p>
*
* @param title title of this target that will be shown to a user
* @param icon icon to represent this target
* @param score ranking score for this target between 0.0f and 1.0f, inclusive
- * @param intentSender IntentSender to fill in and send if the user chooses this target
+ * @param componentName Name of the component to be launched if this target is chosen
+ * @param intentExtras Bundle of extras to merge with the extras of the launched intent
*/
- public ChooserTarget(CharSequence title, Icon icon, float score, IntentSender intentSender) {
+ public ChooserTarget(CharSequence title, Icon icon, float score,
+ ComponentName componentName, @Nullable Bundle intentExtras) {
mTitle = title;
mIcon = icon;
if (score > 1.f || score < 0.f) {
@@ -148,7 +109,8 @@ public final class ChooserTarget implements Parcelable {
+ "must be between 0.0f and 1.0f");
}
mScore = score;
- mIntentSender = intentSender;
+ mComponentName = componentName;
+ mIntentExtras = intentExtras;
}
ChooserTarget(Parcel in) {
@@ -159,7 +121,8 @@ public final class ChooserTarget implements Parcelable {
mIcon = null;
}
mScore = in.readFloat();
- mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in);
+ mComponentName = ComponentName.readFromParcel(in);
+ mIntentExtras = in.readBundle();
}
/**
@@ -194,49 +157,29 @@ public final class ChooserTarget implements Parcelable {
}
/**
- * Returns the raw IntentSender supplied by the ChooserTarget's creator.
- * This may be null if the creator specified a regular Intent instead.
- *
- * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
+ * Returns the ComponentName of the Activity that should be launched for this ChooserTarget.
*
- * @return the IntentSender supplied by the ChooserTarget's creator
+ * @return the name of the target Activity to launch
*/
- public IntentSender getIntentSender() {
- return mIntentSender;
+ public ComponentName getComponentName() {
+ return mComponentName;
}
/**
- * Fill in the IntentSender supplied by the ChooserTarget's creator and send it.
+ * Returns the Bundle of extras to be added to an intent launched to this target.
*
- * @param context the sending Context; generally the Activity presenting the chooser UI
- * @param fillInIntent the Intent provided to the Chooser to be sent to a selected target
- * @return true if sending the Intent was successful
+ * @return the extras to merge with the extras of the intent being launched
*/
- public boolean sendIntent(Context context, Intent fillInIntent) {
- if (fillInIntent != null) {
- fillInIntent.migrateExtraStreamToClipData();
- fillInIntent.prepareToLeaveProcess();
- }
- if (mIntentSender != null) {
- try {
- mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
- return true;
- } catch (IntentSender.SendIntentException e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
- } else {
- Log.e(TAG, "sendIntent " + this + " failed - no IntentSender to send");
- return false;
- }
+ public Bundle getIntentExtras() {
+ return mIntentExtras;
}
@Override
public String toString() {
return "ChooserTarget{"
- + (mIntentSender != null ? mIntentSender.getCreatorPackage() : null)
- + ", "
- + "'" + mTitle
+ + mComponentName
+ + ", " + mIntentExtras
+ + ", '" + mTitle
+ "', " + mScore + "}";
}
@@ -255,7 +198,8 @@ public final class ChooserTarget implements Parcelable {
dest.writeInt(0);
}
dest.writeFloat(mScore);
- IntentSender.writeIntentSenderOrNullToParcel(mIntentSender, dest);
+ ComponentName.writeToParcel(mComponentName, dest);
+ dest.writeBundle(mIntentExtras);
}
public static final Creator<ChooserTarget> CREATOR
diff --git a/core/java/android/service/chooser/ChooserTargetService.java b/core/java/android/service/chooser/ChooserTargetService.java
index a3bfece..e054185 100644
--- a/core/java/android/service/chooser/ChooserTargetService.java
+++ b/core/java/android/service/chooser/ChooserTargetService.java
@@ -105,9 +105,8 @@ public abstract class ChooserTargetService extends Service {
* can handle an intent.
*
* <p>The returned list should be sorted such that the most relevant targets appear first.
- * Any PendingIntents used to construct the resulting ChooserTargets should always be prepared
- * to have the relevant data fields filled in by the sender. See
- * {@link ChooserTarget#ChooserTarget(CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent) ChooserTarget}.</p>
+ * The score for each ChooserTarget will be combined with the system's score for the original
+ * target Activity to sort and filter targets presented to the user.</p>
*
* <p><em>Important:</em> Calls to this method from other applications will occur on
* a binder thread, not on your app's main thread. Make sure that access to relevant data
diff --git a/core/java/android/service/chooser/IChooserTargetResult.aidl b/core/java/android/service/chooser/IChooserTargetResult.aidl
index dbd7cbd..6c648a2 100644
--- a/core/java/android/service/chooser/IChooserTargetResult.aidl
+++ b/core/java/android/service/chooser/IChooserTargetResult.aidl
@@ -21,7 +21,7 @@ import android.service.chooser.ChooserTarget;
/**
* @hide
*/
-interface IChooserTargetResult
+oneway interface IChooserTargetResult
{
void sendResult(in List<ChooserTarget> targets);
}
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 8fe84e1..dbc28f7 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -35,5 +35,6 @@ oneway interface IVoiceInteractionSession {
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
void closeSystemDialogs();
+ void onLockscreenShown();
void destroy();
}
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 95f96e8..f647aa6 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -91,6 +91,12 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
*/
public static final int SHOW_SOURCE_ASSIST_GESTURE = 1<<2;
+ /**
+ * Flag for use with {@link #onShow}: indicates that the application itself has invoked
+ * the assistant.
+ */
+ public static final int SHOW_SOURCE_APPLICATION = 1<<3;
+
final Context mContext;
final HandlerCaller mHandlerCaller;
@@ -259,6 +265,11 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
@Override
+ public void onLockscreenShown() {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_ON_LOCKSCREEN_SHOWN));
+ }
+
+ @Override
public void destroy() {
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_DESTROY));
}
@@ -316,6 +327,22 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
return mExtras;
}
+ /**
+ * Check whether this request is currently active. A request becomes inactive after
+ * calling {@link #cancel} or a final result method that completes the request. After
+ * this point, further interactions with the request will result in
+ * {@link java.lang.IllegalStateException} errors; you should not catch these errors,
+ * but can use this method if you need to determine the state of the request. Returns
+ * true if the request is still active.
+ */
+ public boolean isActive() {
+ VoiceInteractionSession session = mSession.get();
+ if (session == null) {
+ return false;
+ }
+ return session.isRequestActive(mInterface.asBinder());
+ }
+
void finishRequest() {
VoiceInteractionSession session = mSession.get();
if (session == null) {
@@ -332,6 +359,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* Ask the app to cancel this current request.
+ * This also finishes the request (it is no longer active).
*/
public void cancel() {
try {
@@ -383,6 +411,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* in a call to
* {@link android.app.VoiceInteractor.ConfirmationRequest#onConfirmationResult
* VoiceInteractor.ConfirmationRequest.onConfirmationResult}.
+ * This finishes the request (it is no longer active).
*/
public void sendConfirmationResult(boolean confirmed, Bundle result) {
try {
@@ -469,6 +498,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* and resulting in a call to
* {@link android.app.VoiceInteractor.PickOptionRequest#onPickOptionResult
* VoiceInteractor.PickOptionRequest.onPickOptionResult} with false for finished.
+ * This finishes the request (it is no longer active).
*/
public void sendPickOptionResult(
VoiceInteractor.PickOptionRequest.Option[] selections, Bundle result) {
@@ -516,6 +546,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* in a call to
* {@link android.app.VoiceInteractor.CompleteVoiceRequest#onCompleteResult
* VoiceInteractor.CompleteVoiceRequest.onCompleteResult}.
+ * This finishes the request (it is no longer active).
*/
public void sendCompleteResult(Bundle result) {
try {
@@ -564,7 +595,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* Report that the voice interactor has finished aborting the voice operation, resulting
* in a call to
* {@link android.app.VoiceInteractor.AbortVoiceRequest#onAbortResult
- * VoiceInteractor.AbortVoiceRequest.onAbortResult}.
+ * VoiceInteractor.AbortVoiceRequest.onAbortResult}. This finishes the request (it
+ * is no longer active).
*/
public void sendAbortResult(Bundle result) {
try {
@@ -624,6 +656,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
* Report the final result of the request, completing the request and resulting in a call to
* {@link android.app.VoiceInteractor.CommandRequest#onCommandResult
* VoiceInteractor.CommandRequest.onCommandResult} with true for isCompleted.
+ * This finishes the request (it is no longer active).
*/
public void sendResult(Bundle result) {
sendCommandResult(true, result);
@@ -646,6 +679,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
static final int MSG_HANDLE_SCREENSHOT = 105;
static final int MSG_SHOW = 106;
static final int MSG_HIDE = 107;
+ static final int MSG_ON_LOCKSCREEN_SHOWN = 108;
class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
@Override
@@ -724,6 +758,10 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
if (DEBUG) Log.d(TAG, "doHide");
doHide();
break;
+ case MSG_ON_LOCKSCREEN_SHOWN:
+ if (DEBUG) Log.d(TAG, "onLockscreenShown");
+ onLockscreenShown();
+ break;
}
if (args != null) {
args.recycle();
@@ -814,7 +852,15 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
void addRequest(Request req) {
- mActiveRequests.put(req.mInterface.asBinder(), req);
+ synchronized (this) {
+ mActiveRequests.put(req.mInterface.asBinder(), req);
+ }
+ }
+
+ boolean isRequestActive(IBinder reqInterface) {
+ synchronized (this) {
+ return mActiveRequests.containsKey(reqInterface);
+ }
}
Request removeRequest(IBinder reqInterface) {
@@ -936,6 +982,23 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
}
/**
+ * Return which show context flags have been disabled by the user through the system
+ * settings UI, so the session will never get this data. Returned flags are any combination of
+ * {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} and
+ * {@link VoiceInteractionSession#SHOW_WITH_SCREENSHOT
+ * VoiceInteractionSession.SHOW_WITH_SCREENSHOT}. Note that this only tells you about
+ * global user settings, not about restrictions that may be applied contextual based on
+ * the current application the user is in or other transient states.
+ */
+ public int getUserDisabledShowContext() {
+ try {
+ return mSystemService.getUserDisabledShowContext();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ /**
* Show the UI for this session. This asks the system to go through the process of showing
* your UI, which will eventually culminate in {@link #onShow}. This is similar to calling
* {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}.
@@ -1179,23 +1242,33 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
/**
* Called to receive data from the application that the user was currently viewing when
- * an assist session is started.
+ * an assist session is started. If the original show request did not specify
+ * {@link #SHOW_WITH_ASSIST}, this method will not be called.
*
* @param data Arbitrary data supplied by the app through
* {@link android.app.Activity#onProvideAssistData Activity.onProvideAssistData}.
+ * May be null if assist data has been disabled by the user or device policy.
* @param structure If available, the structure definition of all windows currently
- * displayed by the app; if structure has been turned off by the user, will be null.
+ * displayed by the app. May be null if assist data has been disabled by the user
+ * or device policy; will be an empty stub if the application has disabled assist
+ * by marking its window as secure.
* @param content Additional content data supplied by the app through
* {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}.
+ * May be null if assist data has been disabled by the user or device policy; will
+ * not be automatically filled in with data from the app if the app has marked its
+ * window as secure.
*/
- public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) {
+ public void onHandleAssist(@Nullable Bundle data, @Nullable AssistStructure structure,
+ @Nullable AssistContent content) {
}
/**
* Called to receive a screenshot of what the user was currently viewing when an assist
- * session is started. Will be null if screenshots are disabled by the user.
+ * session is started. May be null if screenshots are disabled by the user, policy,
+ * or application. If the original show request did not specify
+ * {@link #SHOW_WITH_SCREENSHOT}, this method will not be called.
*/
- public void onHandleScreenshot(Bitmap screenshot) {
+ public void onHandleScreenshot(@Nullable Bitmap screenshot) {
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
@@ -1233,6 +1306,13 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
hide();
}
+ /**
+ * Called when the lockscreen was shown.
+ */
+ public void onLockscreenShown() {
+ hide();
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
}
diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java
index 7ea9da1..5c088cd 100644
--- a/core/java/android/text/BidiFormatter.java
+++ b/core/java/android/text/BidiFormatter.java
@@ -173,7 +173,7 @@ public final class BidiFormatter {
/**
* Specifies whether the BidiFormatter to be built should also "reset" directionality before
- * a string being bidi-wrapped, not just after it. The default is false.
+ * a string being bidi-wrapped, not just after it. The default is true.
*/
public Builder stereoReset(boolean stereoReset) {
if (stereoReset) {
@@ -363,12 +363,13 @@ public final class BidiFormatter {
* If {@code isolate}, directionally isolates the string so that it does not garble its
* surroundings. Currently, this is done by "resetting" the directionality after the string by
* appending a trailing Unicode bidi mark matching the context directionality (LRM or RLM) when
- * either the overall directionality or the exit directionality of the string is opposite to that
- * of the context. If the formatter was built using {@link Builder#stereoReset(boolean)} and
- * passing "true" as an argument, also prepends a Unicode bidi mark matching the context
- * directionality when either the overall directionality or the entry directionality of the
- * string is opposite to that of the context. Note that as opposed to the overall
- * directionality, the entry and exit directionalities are determined from the string itself.
+ * either the overall directionality or the exit directionality of the string is opposite to
+ * that of the context. Unless the formatter was built using
+ * {@link Builder#stereoReset(boolean)} with a {@code false} argument, also prepends a Unicode
+ * bidi mark matching the context directionality when either the overall directionality or the
+ * entry directionality of the string is opposite to that of the context. Note that as opposed
+ * to the overall directionality, the entry and exit directionalities are determined from the
+ * string itself.
* <p>
* Does *not* do HTML-escaping.
*
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 605b91d..39e8694 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -741,11 +741,11 @@ class TextLine {
if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
if (mCharsValid) {
- ret = wp.getRunAdvance(mChars, start, contextEnd, contextStart, contextEnd,
+ ret = wp.getRunAdvance(mChars, start, end, contextStart, contextEnd,
runIsRtl, end);
} else {
int delta = mStart;
- ret = wp.getRunAdvance(mText, delta + start, delta + contextEnd,
+ ret = wp.getRunAdvance(mText, delta + start, delta + end,
delta + contextStart, delta + contextEnd, runIsRtl, delta + end);
}
}
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index 82689b9..b5068b2 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -16,12 +16,18 @@
package android.text.format;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
+import android.text.BidiFormatter;
+import android.text.TextUtils;
+import android.view.View;
import android.net.NetworkUtils;
import android.net.TrafficStats;
+import java.util.Locale;
+
/**
* Utility class to aid in formatting common values that are not covered
* by the {@link java.util.Formatter} class in {@link java.util}
@@ -46,8 +52,23 @@ public final class Formatter {
}
}
+ /* Wraps the source string in bidi formatting characters in RTL locales */
+ private static String bidiWrap(@NonNull Context context, String source) {
+ final Locale locale = context.getResources().getConfiguration().locale;
+ if (TextUtils.getLayoutDirectionFromLocale(locale) == View.LAYOUT_DIRECTION_RTL) {
+ return BidiFormatter.getInstance(true /* RTL*/).unicodeWrap(source);
+ } else {
+ return source;
+ }
+ }
+
/**
- * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc
+ * Formats a content size to be in the form of bytes, kilobytes, megabytes, etc.
+ *
+ * If the context has a right-to-left locale, the returned string is wrapped in bidi formatting
+ * characters to make sure it's displayed correctly if inserted inside a right-to-left string.
+ * (This is useful in cases where the unit strings, like "MB", are left-to-right, but the
+ * locale is right-to-left.)
*
* @param context Context to use to load the localized units
* @param sizeBytes size value to be formatted, in bytes
@@ -58,8 +79,8 @@ public final class Formatter {
return "";
}
final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
- return context.getString(com.android.internal.R.string.fileSizeSuffix,
- res.value, res.units);
+ return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units));
}
/**
@@ -71,8 +92,8 @@ public final class Formatter {
return "";
}
final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
- return context.getString(com.android.internal.R.string.fileSizeSuffix,
- res.value, res.units);
+ return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix,
+ res.value, res.units));
}
/** {@hide} */
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index 39f66a5..a405dab 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -30,20 +30,32 @@ public final class LocalLog {
private LinkedList<String> mLog;
private int mMaxLines;
private long mNow;
+ private final boolean mKeepFirst;
public LocalLog(int maxLines) {
mLog = new LinkedList<String>();
mMaxLines = maxLines;
+ mKeepFirst = false;
+ }
+
+ public LocalLog(int maxLines, boolean keepFirst) {
+ mLog = new LinkedList<String>();
+ mMaxLines = maxLines;
+ mKeepFirst = keepFirst;
}
public synchronized void log(String msg) {
+ mNow = System.currentTimeMillis();
+ StringBuilder sb = new StringBuilder();
+ Calendar c = Calendar.getInstance();
+ c.setTimeInMillis(mNow);
+ sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
+ logStraight(sb.toString() + " - " + msg);
+ }
+
+ private synchronized void logStraight(String msg) {
+ if (mKeepFirst == false || mLog.size() < mMaxLines) mLog.add(msg);
if (mMaxLines > 0) {
- mNow = System.currentTimeMillis();
- StringBuilder sb = new StringBuilder();
- Calendar c = Calendar.getInstance();
- c.setTimeInMillis(mNow);
- sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
- mLog.add(sb.toString() + " - " + msg);
while (mLog.size() > mMaxLines) mLog.remove();
}
}
@@ -74,4 +86,13 @@ public final class LocalLog {
public ReadOnlyLocalLog readOnlyLocalLog() {
return new ReadOnlyLocalLog(this);
}
+
+ public synchronized void copyTo(LocalLog other, int lines) {
+ int end = mLog.size()-1;
+ int begin = end - lines;
+ if (begin < 0) begin = 0;
+ for (; begin < end; begin++) {
+ other.logStraight(mLog.get(begin));
+ }
+ }
}
diff --git a/core/java/android/view/inputmethod/InputMethodManagerInternal.java b/core/java/android/view/inputmethod/InputMethodManagerInternal.java
new file mode 100644
index 0000000..c22127b
--- /dev/null
+++ b/core/java/android/view/inputmethod/InputMethodManagerInternal.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2015 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 android.view.inputmethod;
+
+/**
+ * Input method manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public interface InputMethodManagerInternal {
+ /**
+ * Called by the power manager to tell the input method manager whether it
+ * should start watching for wake events.
+ */
+ public void setInteractive(boolean interactive);
+}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index b2b98db..ed858e7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1556,13 +1556,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (accessibilityId == getAccessibilityViewId()) {
return this;
}
- // If the data changed the children are invalid since the data model changed.
- // Hence, we pretend they do not exist. After a layout the children will sync
- // with the model at which point we notify that the accessibility state changed,
- // so a service will be able to re-fetch the views.
- if (mDataChanged) {
- return null;
- }
return super.findViewByAccessibilityIdTraversal(accessibilityId);
}
@@ -2409,18 +2402,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
class ListItemAccessibilityDelegate extends AccessibilityDelegate {
@Override
- public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
- // If the data changed the children are invalid since the data model changed.
- // Hence, we pretend they do not exist. After a layout the children will sync
- // with the model at which point we notify that the accessibility state changed,
- // so a service will be able to re-fetch the views.
- if (mDataChanged) {
- return null;
- }
- return super.createAccessibilityNodeInfo(host);
- }
-
- @Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index e3ce6f2..a12b15e 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -533,6 +533,12 @@ public class AppSecurityPermissions {
int existingReqFlags) {
final int base = pInfo.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
final boolean isNormal = (base == PermissionInfo.PROTECTION_NORMAL);
+
+ // We do not show normal permissions in the UI.
+ if (isNormal) {
+ return false;
+ }
+
final boolean isDangerous = (base == PermissionInfo.PROTECTION_DANGEROUS)
|| ((pInfo.protectionLevel&PermissionInfo.PROTECTION_FLAG_PRE23) != 0);
final boolean isRequired =
@@ -546,7 +552,7 @@ public class AppSecurityPermissions {
// Dangerous and normal permissions are always shown to the user if the permission
// is required, or it was previously granted
- if ((isNormal || isDangerous) && (isRequired || wasGranted || isGranted)) {
+ if (isDangerous && (isRequired || wasGranted || isGranted)) {
return true;
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index d897f49..e169ceb 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1004,7 +1004,8 @@ public class Editor {
}
if (!handled && mTextActionMode != null) {
- if (touchPositionIsInSelection()) {
+ // TODO: Fix dragging in extracted mode.
+ if (touchPositionIsInSelection() && !mTextView.isInExtractedMode()) {
// Start a drag
final int start = mTextView.getSelectionStart();
final int end = mTextView.getSelectionEnd();
@@ -3225,7 +3226,8 @@ public class Editor {
}
private void updateReplaceItem(Menu menu) {
- boolean canReplace = mTextView.isSuggestionsEnabled() && shouldOfferToShowSuggestions();
+ boolean canReplace = mTextView.isSuggestionsEnabled() && shouldOfferToShowSuggestions()
+ && !(mTextView.isInExtractedMode() && mTextView.hasSelection());
boolean replaceItemExists = menu.findItem(TextView.ID_REPLACE) != null;
if (canReplace && !replaceItemExists) {
menu.add(Menu.NONE, TextView.ID_REPLACE, MENU_ITEM_ORDER_REPLACE,
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index dac02fa..6a561e6 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -731,7 +731,8 @@ public class RelativeLayout extends ViewGroup {
// Negative values in a mySize value in RelativeLayout
// measurement is code for, "we got an unspecified mode in the
// RelativeLayout's measure spec."
- if (mySize < 0 && !mAllowBrokenMeasureSpecs) {
+ final boolean isUnspecified = mySize < 0;
+ if (isUnspecified && !mAllowBrokenMeasureSpecs) {
if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) {
// Constraints fixed both edges, so child has an exact size.
childSpecSize = Math.max(0, childEnd - childStart);
@@ -767,7 +768,7 @@ public class RelativeLayout extends ViewGroup {
if (childStart != VALUE_NOT_SET && childEnd != VALUE_NOT_SET) {
// Constraints fixed both edges, so child must be an exact size.
- childSpecMode = MeasureSpec.EXACTLY;
+ childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
childSpecSize = Math.max(0, maxAvailable);
} else {
if (childSize >= 0) {
@@ -784,7 +785,7 @@ public class RelativeLayout extends ViewGroup {
} else if (childSize == LayoutParams.MATCH_PARENT) {
// Child wanted to be as big as possible. Give all available
// space.
- childSpecMode = MeasureSpec.EXACTLY;
+ childSpecMode = isUnspecified ? MeasureSpec.UNSPECIFIED : MeasureSpec.EXACTLY;
childSpecSize = Math.max(0, maxAvailable);
} else if (childSize == LayoutParams.WRAP_CONTENT) {
// Child wants to wrap content. Use AT_MOST to communicate
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index acf1df9..6e04eac 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -42,6 +42,7 @@ import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.internal.R;
import com.android.internal.widget.ExploreByTouchHelper;
+import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
@@ -73,6 +74,7 @@ class SimpleMonthView extends View {
private final SimpleDateFormat mTitleFormatter;
private final SimpleDateFormat mDayOfWeekFormatter;
+ private final NumberFormat mDayFormatter;
// Desired dimensions.
private final int mDesiredMonthHeight;
@@ -162,6 +164,7 @@ class SimpleMonthView extends View {
final String titleFormat = DateFormat.getBestDateTimePattern(locale, DEFAULT_TITLE_FORMAT);
mTitleFormatter = new SimpleDateFormat(titleFormat, locale);
mDayOfWeekFormatter = new SimpleDateFormat(DAY_OF_WEEK_FORMAT, locale);
+ mDayFormatter = NumberFormat.getIntegerInstance(locale);
initPaints(res);
}
@@ -454,7 +457,7 @@ class SimpleMonthView extends View {
}
p.setColor(dayTextColor);
- canvas.drawText(Integer.toString(day), colCenterRtl, rowCenter - halfLineHeight, p);
+ canvas.drawText(mDayFormatter.format(day), colCenterRtl, rowCenter - halfLineHeight, p);
col++;
@@ -866,7 +869,7 @@ class SimpleMonthView extends View {
*/
private CharSequence getDayText(int id) {
if (isValidDayOfMonth(id)) {
- return Integer.toString(id);
+ return mDayFormatter.format(id);
}
return null;