diff options
Diffstat (limited to 'core/java')
25 files changed, 317 insertions, 151 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 7572799..e782fb8 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -3771,6 +3771,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 +3982,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/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index fc408a8..bfb92c4 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; @@ -2675,7 +2677,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 +2702,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(); diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 66e2733..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. diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 1d87d77..5eb3961 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, 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..b0d8541 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); @@ -2725,7 +2768,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 +3168,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 +4311,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 +4437,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/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/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/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/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/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/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index c4f57c7..6af2e8b 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -471,6 +471,36 @@ public class ChooserActivity extends ResolverActivity { return false; } + void filterServiceTargets(String packageName, List<ChooserTarget> targets) { + if (targets == null) { + return; + } + + final PackageManager pm = getPackageManager(); + for (int i = targets.size() - 1; i >= 0; i--) { + final ChooserTarget target = targets.get(i); + final ComponentName targetName = target.getComponentName(); + if (packageName != null && packageName.equals(targetName.getPackageName())) { + // Anything from the original target's package is fine. + continue; + } + + boolean remove; + try { + final ActivityInfo ai = pm.getActivityInfo(targetName, 0); + remove = !ai.exported || ai.permission != null; + } catch (NameNotFoundException e) { + Log.e(TAG, "Target " + target + " returned by " + packageName + + " component not found"); + remove = true; + } + + if (remove) { + targets.remove(i); + } + } + } + @Override ResolveListAdapter createAdapter(Context context, List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid, @@ -554,11 +584,11 @@ public class ChooserActivity extends ResolverActivity { return null; } - private Intent getFillInIntent() { + private Intent getBaseIntentToSend() { Intent result = mSourceInfo != null ? mSourceInfo.getResolvedIntent() : getTargetIntent(); if (result == null) { - Log.e(TAG, "ChooserTargetInfo#getFillInIntent: no fillIn intent available"); + Log.e(TAG, "ChooserTargetInfo: no base intent available to send"); } else { result = new Intent(result); if (mFillInIntent != null) { @@ -571,31 +601,24 @@ public class ChooserActivity extends ResolverActivity { @Override public boolean start(Activity activity, Bundle options) { - final Intent intent = getFillInIntent(); - if (intent == null) { - return false; - } - return mChooserTarget.sendIntent(activity, intent); + throw new RuntimeException("ChooserTargets should be started as caller."); } @Override public boolean startAsCaller(Activity activity, Bundle options, int userId) { - final Intent intent = getFillInIntent(); + final Intent intent = getBaseIntentToSend(); if (intent == null) { return false; } - // ChooserTargets will launch with their IntentSender's identity - return mChooserTarget.sendIntent(activity, intent); + intent.setComponent(mChooserTarget.getComponentName()); + intent.putExtras(mChooserTarget.getIntentExtras()); + activity.startActivityAsCaller(intent, options, true, userId); + return true; } @Override public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { - final Intent intent = getFillInIntent(); - if (intent == null) { - return false; - } - // ChooserTargets will launch with their IntentSender's identity - return mChooserTarget.sendIntent(activity, intent); + throw new RuntimeException("ChooserTargets should be started as caller."); } @Override @@ -998,6 +1021,8 @@ public class ChooserActivity extends ResolverActivity { private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() { @Override public void sendResult(List<ChooserTarget> targets) throws RemoteException { + filterServiceTargets(mOriginalTarget.getResolveInfo().activityInfo.packageName, + targets); final Message msg = Message.obtain(); msg.what = CHOOSER_TARGET_SERVICE_RESULT; msg.obj = new ServiceResultInfo(mOriginalTarget, targets, diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 233bee3..39b66aa 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -103,7 +103,7 @@ public class IntentForwarderActivity extends Activity { || ChooserActivity.class.getName().equals(ri.activityInfo.name)); try { - startActivityAsCaller(newIntent, null, targetUserId); + startActivityAsCaller(newIntent, null, false, targetUserId); } catch (RuntimeException e) { int launchedFromUid = -1; String launchedFromPackage = "?"; diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 7bc18f3..ba19131 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -973,7 +973,7 @@ public class ResolverActivity extends Activity { @Override public boolean startAsCaller(Activity activity, Bundle options, int userId) { - activity.startActivityAsCaller(mResolvedIntent, options, userId); + activity.startActivityAsCaller(mResolvedIntent, options, false, userId); return true; } diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java index 32746c2..6393fba 100644 --- a/core/java/com/android/internal/util/XmlUtils.java +++ b/core/java/com/android/internal/util/XmlUtils.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Bitmap.CompressFormat; import android.net.Uri; +import android.text.TextUtils; import android.util.ArrayMap; import android.util.Base64; import android.util.Xml; @@ -45,6 +46,8 @@ import java.util.Set; /** {@hide} */ public class XmlUtils { + private static final String STRING_ARRAY_SEPARATOR = ":"; + public static void skipCurrentTag(XmlPullParser parser) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); |
