diff options
33 files changed, 312 insertions, 159 deletions
diff --git a/api/current.txt b/api/current.txt index dea5255d1573..a0dccd5963a1 100644 --- a/api/current.txt +++ b/api/current.txt @@ -15863,6 +15863,10 @@ package android.media { ctor public MediaDrmException(java.lang.String); } + public class MediaDrmResetException extends java.lang.IllegalStateException { + ctor public MediaDrmResetException(java.lang.String); + } + public final class MediaExtractor { ctor public MediaExtractor(); method public boolean advance(); @@ -34575,6 +34579,7 @@ package android.view { method public abstract void invalidate(); method public void invalidateContentRect(); method public boolean isTitleOptional(); + method public void onWindowFocusChanged(boolean); method public abstract void setCustomView(android.view.View); method public abstract void setSubtitle(java.lang.CharSequence); method public abstract void setSubtitle(int); diff --git a/api/system-current.txt b/api/system-current.txt index d0225e175d68..7e3e051e6a4a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -17118,6 +17118,10 @@ package android.media { ctor public MediaDrmException(java.lang.String); } + public class MediaDrmResetException extends java.lang.IllegalStateException { + ctor public MediaDrmResetException(java.lang.String); + } + public final class MediaExtractor { ctor public MediaExtractor(); method public boolean advance(); @@ -36856,6 +36860,7 @@ package android.view { method public abstract void invalidate(); method public void invalidateContentRect(); method public boolean isTitleOptional(); + method public void onWindowFocusChanged(boolean); method public abstract void setCustomView(android.view.View); method public abstract void setSubtitle(java.lang.CharSequence); method public abstract void setSubtitle(int); diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index 146138007138..e17808744408 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -35,6 +35,9 @@ import android.os.RemoteException; import android.os.IBinder; import android.os.Parcel; import android.os.ParcelFileDescriptor; +import android.os.TransactionTooLargeException; +import android.util.Log; + import com.android.internal.app.IVoiceInteractor; import com.android.internal.content.ReferrerIntent; @@ -921,8 +924,13 @@ class ApplicationThreadProxy implements IApplicationThread { info.writeToParcel(data, 0); compatInfo.writeToParcel(data, 0); data.writeInt(processState); - mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, - IBinder.FLAG_ONEWAY); + try { + mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, + IBinder.FLAG_ONEWAY); + } catch (TransactionTooLargeException e) { + Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info); + throw e; + } data.recycle(); } diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 08c52365c750..d83dfc5eb54f 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -1480,7 +1480,11 @@ public class IntentFilter implements Parcelable { * Write the contents of the IntentFilter as an XML stream. */ public void writeToXml(XmlSerializer serializer) throws IOException { - serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(getAutoVerify())); + + if (getAutoVerify()) { + serializer.attribute(null, AUTO_VERIFY_STR, Boolean.toString(true)); + } + int N = countActions(); for (int i=0; i<N; i++) { serializer.startTag(null, ACTION_STR); diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index f8db6d9e3010..c656fb8b8352 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -667,7 +667,7 @@ public abstract class CameraMetadata<TKey> { * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }. * The fps range can be controlled via {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}.</p> * <p>In this capability, the camera device will override aeMode, awbMode, and afMode to - * ON, ON, and CONTINUOUS_VIDEO, respectively. All post-processing block mode + * ON, AUTO, and CONTINUOUS_VIDEO, respectively. All post-processing block mode * controls will be overridden to be FAST. Therefore, no manual control of capture * and post-processing parameters is possible. All other controls operate the * same as when {@link CaptureRequest#CONTROL_MODE android.control.mode} == AUTO. This means that all other @@ -1666,9 +1666,9 @@ public abstract class CameraMetadata<TKey> { * <p>Enabling this disables control.aeMode, control.awbMode and * control.afMode controls; the camera device will ignore * those settings while USE_SCENE_MODE is active (except for - * FACE_PRIORITY scene mode). Other control entries are still - * active. This setting can only be used if scene mode is - * supported (i.e. {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes} + * FACE_PRIORITY scene mode). Other control entries are still active. + * This setting can only be used if scene mode is supported (i.e. + * {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes} * contain some modes other than DISABLED).</p> * * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES @@ -1940,6 +1940,40 @@ public abstract class CameraMetadata<TKey> { */ public static final int CONTROL_SCENE_MODE_HDR = 18; + /** + * <p>Same as FACE_PRIORITY scene mode, except that the camera + * device will choose higher sensivity values ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}) + * under low light conditions.</p> + * <p>The camera device may be tuned to expose the images in a reduced + * sensitivity range to produce the best quality images. For example, + * if the {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} gives range of [100, 1600], + * the camera device auto-exposure routine tuning process may limit the actual + * exposure sensivity range to [100, 1200] to ensure that the noise level isn't + * exessive to compromise the image quality. Under this situation, the image under + * low light may be under-exposed when the sensor max exposure time (bounded by the + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange} when {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of the + * ON_* modes) and effecitve max sensitivity are reached. This scene mode allows the + * camera device auto-exposure routine to increase the sensitivity up to the max + * sensitivity specified by {@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange} when the scene is too + * dark and the max exposure time is reached. The captured images may be noisier + * compared with the images captured in normal FACE_PRIORITY mode, therefore, it is + * recommended that the application only use this scene mode when it is capable of + * reducing the noise level of the captured images.</p> + * <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, + * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} + * remain active when FACE_PRIORITY_LOW_LIGHT is set.</p> + * + * @see CaptureRequest#CONTROL_AE_MODE + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see CaptureRequest#CONTROL_AF_MODE + * @see CaptureRequest#CONTROL_AWB_MODE + * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE + * @see CaptureRequest#SENSOR_SENSITIVITY + * @see CaptureRequest#CONTROL_SCENE_MODE + * @hide + */ + public static final int CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19; + // // Enumeration values for CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE // diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index bc625dd31168..9fa66879629d 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -1448,9 +1448,9 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>> * <p>Scene modes are custom camera modes optimized for a certain set of conditions and * capture settings.</p> * <p>This is the mode that that is active when - * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, - * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, - * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p> + * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will + * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} + * while in use.</p> * <p>The interpretation and implementation of these scene modes is left * to the implementor of the camera device. Their behavior will not be * consistent across all devices, and any given device may only implement diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index da216aaa4418..b1fb615821c7 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -1960,9 +1960,9 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * <p>Scene modes are custom camera modes optimized for a certain set of conditions and * capture settings.</p> * <p>This is the mode that that is active when - * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, - * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, - * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p> + * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY, these modes will + * disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}, {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} + * while in use.</p> * <p>The interpretation and implementation of these scene modes is left * to the implementor of the camera device. Their behavior will not be * consistent across all devices, and any given device may only implement diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index dbb51464cb87..f9c50f320dbb 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -635,8 +635,8 @@ public class Process { if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) { argsForZygote.add("--enable-jit"); } - if ((debugFlags & Zygote.DEBUG_GENERATE_CFI) != 0) { - argsForZygote.add("--generate-cfi"); + if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) { + argsForZygote.add("--generate-debug-info"); } if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) { argsForZygote.add("--enable-assert"); diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index e4fab12e9ced..62c28ac14255 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -191,8 +191,9 @@ public final class KeymasterDefs { public static final int KM_ERROR_MISSING_NONCE = -51; public static final int KM_ERROR_INVALID_NONCE = -52; public static final int KM_ERROR_MISSING_MAC_LENGTH = -53; - public static final int KM_ERROR_RESCOPABLE_KEY_NOT_USABLE = -54; + 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_UNIMPLEMENTED = -100; public static final int KM_ERROR_VERSION_MISMATCH = -101; public static final int KM_ERROR_UNKNOWN_ERROR = -1000; diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 8c6cd09a8144..0309d24c8e56 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -41,6 +41,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -463,15 +464,28 @@ public abstract class NotificationListenerService extends Service { ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface() .getActiveNotificationsFromListener(mWrapper, keys, trim); List<StatusBarNotification> list = parceledList.getList(); - + ArrayList<StatusBarNotification> corruptNotifications = null; int N = list.size(); for (int i = 0; i < N; i++) { - Notification notification = list.get(i).getNotification(); - Builder.rebuild(getContext(), notification); - // convert icon metadata to legacy format for older clients - createLegacyIconExtras(notification); + StatusBarNotification sbn = list.get(i); + Notification notification = sbn.getNotification(); + try { + Builder.rebuild(getContext(), notification); + // convert icon metadata to legacy format for older clients + createLegacyIconExtras(notification); + } catch (IllegalArgumentException e) { + if (corruptNotifications == null) { + corruptNotifications = new ArrayList<>(N); + } + corruptNotifications.add(sbn); + Log.w(TAG, "onNotificationPosted: can't rebuild notification from " + + sbn.getPackageName()); + } } - return list.toArray(new StatusBarNotification[N]); + if (corruptNotifications != null) { + list.removeAll(corruptNotifications); + } + return list.toArray(new StatusBarNotification[list.size()]); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); } @@ -671,16 +685,28 @@ public abstract class NotificationListenerService extends Service { Log.w(TAG, "onNotificationPosted: Error receiving StatusBarNotification", e); return; } - Notification.Builder.rebuild(getContext(), sbn.getNotification()); - // convert icon metadata to legacy format for older clients - createLegacyIconExtras(sbn.getNotification()); + try { + Notification.Builder.rebuild(getContext(), sbn.getNotification()); + // convert icon metadata to legacy format for older clients + createLegacyIconExtras(sbn.getNotification()); + } catch (IllegalArgumentException e) { + // drop corrupt notification + sbn = null; + Log.w(TAG, "onNotificationPosted: can't rebuild notification from " + + sbn.getPackageName()); + } // protect subclass from concurrent modifications of (@link mNotificationKeys}. synchronized (mWrapper) { applyUpdate(update); try { - NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap); + if (sbn != null) { + NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap); + } else { + // still pass along the ranking map, it may contain other information + NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap); + } } catch (Throwable t) { Log.w(TAG, "Error running onNotificationPosted", t); } diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index 80dcecce8bc2..ea979c8b4621 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -261,6 +261,16 @@ public abstract class ActionMode { public abstract MenuInflater getMenuInflater(); /** + * Called when the window containing the view that started this action mode gains or loses + * focus. + * + * @param hasWindowFocus True if the window containing the view that started this action mode + * now has focus, false otherwise. + * + */ + public void onWindowFocusChanged(boolean hasWindowFocus) {} + + /** * Returns whether the UI presenting this action mode can take focus or not. * This is used by internal components within the framework that would otherwise * present an action mode UI that requires focus, such as an EditText as a custom view. diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 339038eddf3f..affc5daa35f7 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -522,7 +522,7 @@ public class RelativeLayout extends ViewGroup { View baselineView = null; LayoutParams baselineParams = null; for (int i = 0; i < count; i++) { - final View child = views[i]; + final View child = getChildAt(i); if (child.getVisibility() != GONE) { final LayoutParams childParams = (LayoutParams) child.getLayoutParams(); if (baselineView == null || baselineParams == null @@ -548,9 +548,9 @@ public class RelativeLayout extends ViewGroup { if (offsetHorizontalAxis) { for (int i = 0; i < count; i++) { - final View child = views[i]; + View child = getChildAt(i); if (child.getVisibility() != GONE) { - final LayoutParams params = (LayoutParams) child.getLayoutParams(); + LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_HORIZONTAL] != 0) { centerHorizontal(child, params, width); @@ -578,9 +578,9 @@ public class RelativeLayout extends ViewGroup { if (offsetVerticalAxis) { for (int i = 0; i < count; i++) { - final View child = views[i]; + View child = getChildAt(i); if (child.getVisibility() != GONE) { - final LayoutParams params = (LayoutParams) child.getLayoutParams(); + LayoutParams params = (LayoutParams) child.getLayoutParams(); final int[] rules = params.getRules(layoutDirection); if (rules[CENTER_IN_PARENT] != 0 || rules[CENTER_VERTICAL] != 0) { centerVertical(child, params, height); @@ -607,9 +607,9 @@ public class RelativeLayout extends ViewGroup { final int verticalOffset = contentBounds.top - top; if (horizontalOffset != 0 || verticalOffset != 0) { for (int i = 0; i < count; i++) { - final View child = views[i]; + View child = getChildAt(i); if (child.getVisibility() != GONE && child != ignore) { - final LayoutParams params = (LayoutParams) child.getLayoutParams(); + LayoutParams params = (LayoutParams) child.getLayoutParams(); if (horizontalGravity) { params.mLeft += horizontalOffset; params.mRight += horizontalOffset; @@ -626,9 +626,9 @@ public class RelativeLayout extends ViewGroup { if (isLayoutRtl()) { final int offsetWidth = myWidth - width; for (int i = 0; i < count; i++) { - final View child = views[i]; + View child = getChildAt(i); if (child.getVisibility() != GONE) { - final LayoutParams params = (LayoutParams) child.getLayoutParams(); + LayoutParams params = (LayoutParams) child.getLayoutParams(); params.mLeft -= offsetWidth; params.mRight -= offsetWidth; } diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java index 4f6d78187578..c97fdf46cda9 100644 --- a/core/java/com/android/internal/os/Zygote.java +++ b/core/java/com/android/internal/os/Zygote.java @@ -41,8 +41,8 @@ public final class Zygote { public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4; /** enable the JIT compiler */ public static final int DEBUG_ENABLE_JIT = 1 << 5; - /** Force generation of CFI code */ - public static final int DEBUG_GENERATE_CFI = 1 << 6; + /** Force generation of native debugging information. */ + public static final int DEBUG_GENERATE_DEBUG_INFO = 1 << 6; /** No external storage should be mounted. */ public static final int MOUNT_EXTERNAL_NONE = 0; diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index 1a0345bcac04..fa870b9ddedf 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -322,7 +322,7 @@ class ZygoteConnection { /** * From --enable-debugger, --enable-checkjni, --enable-assert, - * --enable-safemode, --enable-jit, --generate-cfi and --enable-jni-logging. + * --enable-safemode, --enable-jit, --generate-debug-info and --enable-jni-logging. */ int debugFlags; @@ -434,8 +434,8 @@ class ZygoteConnection { debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; } else if (arg.equals("--enable-jit")) { debugFlags |= Zygote.DEBUG_ENABLE_JIT; - } else if (arg.equals("--generate-cfi")) { - debugFlags |= Zygote.DEBUG_GENERATE_CFI; + } else if (arg.equals("--generate-debug-info")) { + debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; } else if (arg.equals("--enable-jni-logging")) { debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; } else if (arg.equals("--enable-assert")) { diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index 66f6079b47e9..15ed5bd0b539 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -3223,12 +3223,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { cb.onWindowFocusChanged(hasWindowFocus); } - if (mFloatingToolbar != null) { - if (hasWindowFocus) { - mFloatingToolbar.show(); - } else { - mFloatingToolbar.dismiss(); - } + if (mPrimaryActionMode != null) { + mPrimaryActionMode.onWindowFocusChanged(hasWindowFocus); + } + if (mFloatingActionMode != null) { + mFloatingActionMode.onWindowFocusChanged(hasWindowFocus); } } @@ -3441,8 +3440,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mFloatingActionMode = mode; mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this); ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar); - mFloatingActionMode.invalidate(); - mFloatingToolbar.show(); + mFloatingActionMode.invalidate(); // Will show the floating toolbar if necessary. mFloatingActionModeOriginatingView.getViewTreeObserver() .addOnPreDrawListener(mFloatingToolbarPreDrawListener); } diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index 784b256728ca..863506b0a63a 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -197,6 +197,13 @@ public class FloatingActionMode extends ActionMode { } @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + checkToolbarInitialized(); + mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus); + mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); + } + + @Override public void finish() { checkToolbarInitialized(); reset(); @@ -237,6 +244,7 @@ public class FloatingActionMode extends ActionMode { } private void reset() { + mFloatingToolbar.dismiss(); mFloatingToolbarVisibilityHelper.deactivate(); mOriginatingView.removeCallbacks(mMovingOff); mOriginatingView.removeCallbacks(mHideOff); @@ -253,6 +261,7 @@ public class FloatingActionMode extends ActionMode { private boolean mHideRequested; private boolean mMoving; private boolean mOutOfBounds; + private boolean mWindowFocused = true; private boolean mActive; @@ -264,6 +273,7 @@ public class FloatingActionMode extends ActionMode { mHideRequested = false; mMoving = false; mOutOfBounds = false; + mWindowFocused = true; mActive = true; } @@ -285,12 +295,16 @@ public class FloatingActionMode extends ActionMode { mOutOfBounds = outOfBounds; } + public void setWindowFocused(boolean windowFocused) { + mWindowFocused = windowFocused; + } + public void updateToolbarVisibility() { if (!mActive) { return; } - if (mHideRequested || mMoving || mOutOfBounds) { + if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) { mToolbar.hide(); } else { mToolbar.show(); diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 65f2f53f8987..523663c0e6e4 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -546,25 +546,25 @@ public final class FloatingToolbar { private void refreshCoordinatesAndOverflowDirection(Rect contentRect) { refreshViewPort(); - int availableHeightAboveContent = - contentRect.top - mViewPort.top - 2 * mMarginVertical; - int availableHeightBelowContent = - mViewPort.bottom - contentRect.bottom - 2 * mMarginVertical; - int availableHeightThroughContent = - mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin(); - int x = contentRect.centerX() - getWidth() / 2; // Update x so that the toolbar isn't rendered behind the nav bar in landscape. x = Math.max(0, Math.min(x, mViewPort.right - getWidth())); int y; + + int availableHeightAboveContent = contentRect.top - mViewPort.top; + int availableHeightBelowContent = mViewPort.bottom - contentRect.bottom; + if (mOverflowPanel == null) { // There is no overflow. - if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin()) { + if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin()) { // There is enough space at the top of the content. y = contentRect.top - getToolbarHeightWithVerticalMargin(); - } else if (availableHeightBelowContent > getToolbarHeightWithVerticalMargin()) { + } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) { // There is enough space at the bottom of the content. y = contentRect.bottom; + } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) { + // Just enough space to fit the toolbar with no vertical margins. + y = contentRect.bottom - mMarginVertical; } else { // Not enough space. Prefer to position as high as possible. y = Math.max( @@ -572,32 +572,47 @@ public final class FloatingToolbar { contentRect.top - getToolbarHeightWithVerticalMargin()); } } else { // There is an overflow. - if (availableHeightAboveContent > mOverflowPanel.getMinimumHeight()) { + int margin = 2 * mMarginVertical; + int minimumOverflowHeightWithMargin = mOverflowPanel.getMinimumHeight() + margin; + int availableHeightThroughContentDown = + mViewPort.bottom - contentRect.top + getToolbarHeightWithVerticalMargin(); + int availableHeightThroughContentUp = + contentRect.bottom - mViewPort.top + getToolbarHeightWithVerticalMargin(); + + if (availableHeightAboveContent >= minimumOverflowHeightWithMargin) { // There is enough space at the top of the content rect for the overflow. // Position above and open upwards. - updateOverflowHeight(availableHeightAboveContent); + updateOverflowHeight(availableHeightAboveContent - margin); y = contentRect.top - getHeight(); mOverflowDirection = OVERFLOW_DIRECTION_UP; - } else if (availableHeightAboveContent > getToolbarHeightWithVerticalMargin() - && availableHeightThroughContent > mOverflowPanel.getMinimumHeight()) { + } else if (availableHeightAboveContent >= getToolbarHeightWithVerticalMargin() + && availableHeightThroughContentDown >= minimumOverflowHeightWithMargin) { // There is enough space at the top of the content rect for the main panel // but not the overflow. // Position above but open downwards. - updateOverflowHeight(availableHeightThroughContent); + updateOverflowHeight(availableHeightThroughContentDown - margin); y = contentRect.top - getToolbarHeightWithVerticalMargin(); mOverflowDirection = OVERFLOW_DIRECTION_DOWN; - } else if (availableHeightBelowContent > mOverflowPanel.getMinimumHeight()) { + } else if (availableHeightBelowContent >= minimumOverflowHeightWithMargin) { // There is enough space at the bottom of the content rect for the overflow. // Position below and open downwards. - updateOverflowHeight(availableHeightBelowContent); + updateOverflowHeight(availableHeightBelowContent - margin); y = contentRect.bottom; mOverflowDirection = OVERFLOW_DIRECTION_DOWN; + } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin() + && mViewPort.height() >= minimumOverflowHeightWithMargin) { + // There is enough space at the bottom of the content rect for the main panel + // but not the overflow. + // Position below but open upwards. + updateOverflowHeight(availableHeightThroughContentUp - margin); + y = contentRect.bottom + getToolbarHeightWithVerticalMargin() - getHeight(); + mOverflowDirection = OVERFLOW_DIRECTION_UP; } else { // Not enough space. - // Position at the bottom of the view port and open upwards. - updateOverflowHeight(mViewPort.height()); - y = mViewPort.bottom - getHeight(); - mOverflowDirection = OVERFLOW_DIRECTION_UP; + // Position at the top of the view port and open downwards. + updateOverflowHeight(mViewPort.height() - margin); + y = mViewPort.top; + mOverflowDirection = OVERFLOW_DIRECTION_DOWN; } mOverflowPanel.setOverflowDirection(mOverflowDirection); } @@ -1422,7 +1437,6 @@ public final class FloatingToolbar { PopupWindow popupWindow = new PopupWindow(popupContentHolder); popupWindow.setWindowLayoutType( WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL); - popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); popupWindow.setAnimationStyle(0); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); content.setLayoutParams(new ViewGroup.LayoutParams( diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 7c2b28dcc2b1..2c35a8be98c2 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -876,16 +876,16 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) "-Xzygote-max-boot-retry="); /* - * When running with debug.gencfi, add --include-cfi to the compiler options so that the boot - * image, if it is compiled on device, will include CFI info, as well as other compilations - * started by the runtime. + * When running with debug.generate-debug-info, add --generate-debug-info to + * the compiler options so that the boot image, if it is compiled on device, + * will include native debugging information. */ - property_get("debug.gencfi", propBuf, ""); + property_get("debug.generate-debug-info", propBuf, ""); if (strcmp(propBuf, "true") == 0) { addOption("-Xcompiler-option"); - addOption("--include-cfi"); + addOption("--generate-debug-info"); addOption("-Ximage-compiler-option"); - addOption("--include-cfi"); + addOption("--generate-debug-info"); } initArgs.version = JNI_VERSION_1_4; diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 9acfee2d2309..ab61e2bfcbd3 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -89,10 +89,23 @@ import android.util.Log; * encrypted content, the samples returned from the extractor remain encrypted, they * are only decrypted when the samples are delivered to the decoder. * <p> - * MediaDrm methods throw {@link java.lang.IllegalStateException} - * when a method is called on a MediaDrm object that is in an invalid or inoperable - * state. This is typically due to incorrect application API usage, but may also - * be due to an unrecoverable failure in the DRM plugin or security hardware. + * MediaDrm methods throw {@link android.media.MediaDrm.MediaDrmStateException} + * when a method is called on a MediaDrm object that has had an unrecoverable failure + * in the DRM plugin or security hardware. + * {@link android.media.MediaDrm.MediaDrmStateException} extends + * {@link java.lang.IllegalStateException} with the addition of a developer-readable + * diagnostic information string associated with the exception. + * <p> + * In the event of a mediaserver process crash or restart while a MediaDrm object + * is active, MediaDrm methods may throw {@link android.media.MediaDrmResetException}. + * To recover, the app must release the MediaDrm object, then create and initialize + * a new one. + * <p> + * As {@link android.media.MediaDrmResetException} and + * {@link android.media.MediaDrm.MediaDrmStateException} both extend + * {@link java.lang.IllegalStateException}, they should be in an earlier catch() + * block than {@link java.lang.IllegalStateException} if handled separately. + * <p> * <a name="Callbacks"></a> * <h3>Callbacks</h3> * <p>Applications should register for informational events in order diff --git a/media/java/android/media/MediaDrmResetException.java b/media/java/android/media/MediaDrmResetException.java new file mode 100644 index 000000000000..3b2da1e8bd25 --- /dev/null +++ b/media/java/android/media/MediaDrmResetException.java @@ -0,0 +1,28 @@ +/* + * Copyright 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.media; + +/** + * This exception is thrown when the MediaDrm instance has become unusable + * due to a restart of the mediaserver process. To continue, the app must + * release the MediaDrm object, then create and initialize a new one. + */ +public class MediaDrmResetException extends IllegalStateException { + public MediaDrmResetException(String detailMessage) { + super(detailMessage); + } +} diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index d456dc1080d2..9ec0312d0f2a 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -308,6 +308,10 @@ static bool throwExceptionAsNecessary( } else if (err == ERROR_DRM_DEVICE_REVOKED) { jniThrowException(env, "android/media/DeniedByServerException", msg); return true; + } else if (err == DEAD_OBJECT) { + jniThrowException(env, "android/media/MediaDrmResetException", + "mediaserver died"); + return true; } else if (err != OK) { String8 errbuf; if (drmMessage != NULL) { diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp index fdc586b8a175..aba4bbeb1e70 100644 --- a/media/jni/audioeffect/android_media_AudioEffect.cpp +++ b/media/jni/audioeffect/android_media_AudioEffect.cpp @@ -472,6 +472,8 @@ static void android_media_AudioEffect_native_release(JNIEnv *env, jobject thiz) if (lpJniStorage) { ALOGV("deleting pJniStorage: %p\n", lpJniStorage); + env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class); + env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref); delete lpJniStorage; } } diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index 6098b4a47fa9..05570195752b 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -450,6 +450,8 @@ static void android_media_visualizer_native_release(JNIEnv *env, jobject thiz) if (lpJniStorage) { ALOGV("deleting pJniStorage: %p\n", lpJniStorage); + env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_class); + env->DeleteGlobalRef(lpJniStorage->mCallbackData.visualizer_ref); delete lpJniStorage; } } diff --git a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml b/packages/SystemUI/res/drawable/managed_profile_toast_background.xml deleted file mode 100644 index 5c77b9a1f660..000000000000 --- a/packages/SystemUI/res/drawable/managed_profile_toast_background.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -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. ---> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle"> - <corners android:radius="2dp" /> - <solid android:color="@color/managed_profile_toast_background" /> -</shape> diff --git a/packages/SystemUI/res/layout/managed_profile_toast.xml b/packages/SystemUI/res/layout/managed_profile_toast.xml deleted file mode 100644 index 5a01ca7f16a6..000000000000 --- a/packages/SystemUI/res/layout/managed_profile_toast.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - 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. ---> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:orientation="vertical" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:paddingTop="16dp" - android:paddingBottom="16dp" - android:paddingLeft="32dp" - android:paddingRight="32dp" - android:background="@drawable/managed_profile_toast_background"> - <ImageView - android:layout_width="32dp" - android:layout_height="32dp" - android:layout_gravity="center_horizontal" - android:layout_marginBottom="16dp" - android:src="@drawable/stat_sys_managed_profile_status"/> - <TextView android:text="@string/managed_profile_foreground_toast" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textColor="@android:color/white" - android:textSize="14sp" - android:layout_gravity="center_horizontal" /> -</LinearLayout> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 9a96939f700d..0dcbe884b30f 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -143,6 +143,4 @@ <color name="volume_icon_color">#ffffffff</color> <color name="volume_settings_icon_color">#7fffffff</color> <color name="volume_slider_inactive">#FFB0BEC5</color><!-- blue grey 200 --> - - <color name="managed_profile_toast_background">#E5000000</color><!-- 90% black --> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index b0e71f916f20..7af8b80cc27b 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -575,4 +575,7 @@ <!-- Standard image button size for volume dialog buttons --> <dimen name="volume_button_size">48dp</dimen> + + <!-- Padding between icon and text for managed profile toast --> + <dimen name="managed_profile_toast_padding">4dp</dimen> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index a4965488e34d..f8a1385944d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -393,13 +393,16 @@ public abstract class BaseStatusBar extends SystemUI implements if (recentTask != null && recentTask.size() > 0) { UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId); if (user != null && user.isManagedProfile()) { - LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - View layout = inflater.inflate(R.layout.managed_profile_toast, null); - Toast toast = new Toast(mContext); - toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); - toast.setDuration(Toast.LENGTH_SHORT); - toast.setView(layout); + Toast toast = Toast.makeText(mContext, + R.string.managed_profile_foreground_toast, + Toast.LENGTH_SHORT); + TextView text = (TextView) toast.getView().findViewById( + android.R.id.message); + text.setCompoundDrawablesRelativeWithIntrinsicBounds( + R.drawable.stat_sys_managed_profile_status, 0, 0, 0); + int paddingPx = mContext.getResources().getDimensionPixelSize( + R.dimen.managed_profile_toast_padding); + text.setCompoundDrawablePadding(paddingPx); toast.show(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java index 3cc92978d393..daa84ad80ccf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java @@ -154,6 +154,12 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa } private void updateConnected() { + // Make sure our connection state is up to date. + int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState(); + if (state != mConnectionState) { + mConnectionState = state; + mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED); + } if (mLastDevice != null && mLastDevice.isConnected()) { // Our current device is still valid. return; @@ -203,9 +209,9 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa @Override public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { - mConnectionState = state; mLastDevice = cachedDevice; updateConnected(); + mConnectionState = state; mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 970deba14134..1134556cccc3 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3264,9 +3264,9 @@ public final class ActivityManagerService extends ActivityManagerNative debugFlags |= Zygote.DEBUG_ENABLE_JIT; } } - String genCFIDebugProperty = SystemProperties.get("debug.gencfi"); - if ("true".equals(genCFIDebugProperty)) { - debugFlags |= Zygote.DEBUG_GENERATE_CFI; + String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); + if ("true".equals(genDebugInfoProperty)) { + debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; } if ("1".equals(SystemProperties.get("debug.jni.logging"))) { debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; @@ -8270,7 +8270,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { allowed = true; - Slog.w(TAG, caller + ": caller " + callingUid + if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid + " is using old GET_TASKS but privileged; allowing"); } } catch (RemoteException e) { @@ -8278,7 +8278,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (!allowed) { - Slog.w(TAG, caller + ": caller " + callingUid + if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid + " does not hold REAL_GET_TASKS; limiting output"); } return allowed; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 9e33f2a99607..4e98576e6fb9 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1915,7 +1915,12 @@ public final class ActivityStackSupervisor implements DisplayListener { ActivityRecord intentActivity = !launchSingleInstance ? findTaskLocked(r) : findActivityLocked(intent, r.info); if (intentActivity != null) { - if (isLockTaskModeViolation(intentActivity.task)) { + // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused + // but still needs to be a lock task mode violation since the task gets + // cleared out and the device would otherwise leave the locked task. + if (isLockTaskModeViolation(intentActivity.task, + (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK)) + == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) { showLockTaskToast(); Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode"); return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION; @@ -3780,7 +3785,11 @@ public final class ActivityStackSupervisor implements DisplayListener { } boolean isLockTaskModeViolation(TaskRecord task) { - if (getLockedTaskLocked() == task) { + return isLockTaskModeViolation(task, false); + } + + boolean isLockTaskModeViolation(TaskRecord task, boolean isNewClearTask) { + if (getLockedTaskLocked() == task && !isNewClearTask) { return false; } final int lockTaskAuth = task.mLockTaskAuth; diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 709ae54abbc6..e7fddb96249e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -12500,6 +12500,8 @@ public class PackageManagerService extends IPackageManager.Stub { if (clearPackagePreferredActivitiesLPw(packageName, removeUser)) { scheduleWritePackageRestrictionsLocked(removeUser); } + revokeRuntimePermissionsAndClearAllFlagsLocked(ps.getPermissionsState(), + removeUser); } return true; } @@ -12706,13 +12708,37 @@ public class PackageManagerService extends IPackageManager.Stub { | PackageManager.FLAG_PERMISSION_USER_FIXED | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE; + revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, userSetFlags); + } + + /** + * Revokes granted runtime permissions and clears all flags. + * + * @param permissionsState The permission state to reset. + * @param userId The device user for which to do a reset. + */ + private void revokeRuntimePermissionsAndClearAllFlagsLocked( + PermissionsState permissionsState, int userId) { + revokeRuntimePermissionsAndClearFlagsLocked(permissionsState, userId, + PackageManager.MASK_PERMISSION_FLAGS); + } + + /** + * Revokes granted runtime permissions and clears certain flags. + * + * @param permissionsState The permission state to reset. + * @param userId The device user for which to do a reset. + * @param flags The flags that is going to be reset. + */ + private void revokeRuntimePermissionsAndClearFlagsLocked( + PermissionsState permissionsState, int userId, int flags) { boolean needsWrite = false; for (PermissionState state : permissionsState.getRuntimePermissionStates(userId)) { BasePermission bp = mSettings.mPermissions.get(state.getName()); if (bp != null) { permissionsState.revokeRuntimePermission(bp, userId); - permissionsState.updatePermissionFlags(bp, userId, userSetFlags, 0); + permissionsState.updatePermissionFlags(bp, userId, flags, 0); needsWrite = true; } } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index cd50946567a7..4b36581df06f 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -2098,7 +2098,7 @@ final class Settings { } final ApplicationInfo ai = pkg.pkg.applicationInfo; - final String dataPath = ai.dataDir; + final String dataPath = new File(ai.dataDir).getCanonicalPath(); final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; final int[] gids = pkg.getPermissionsState().computeGids(userIds); |