Merge "Protect runtime storage mount points." into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 05e494b..ac34c59 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3412,6 +3412,7 @@
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
+ method public void onStateNotSaved();
method protected void onStop();
method protected void onTitleChanged(java.lang.CharSequence, int);
method public boolean onTouchEvent(android.view.MotionEvent);
diff --git a/api/system-current.txt b/api/system-current.txt
index d9702ac..7987803 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3516,6 +3516,7 @@
method public boolean onSearchRequested(android.view.SearchEvent);
method public boolean onSearchRequested();
method protected void onStart();
+ method public void onStateNotSaved();
method protected void onStop();
method protected void onTitleChanged(java.lang.CharSequence, int);
method public boolean onTouchEvent(android.view.MotionEvent);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 3c8af0d..2cb3f39 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1172,6 +1172,16 @@
}
/**
+ * Called when an {@link #onResume} is coming up, prior to other pre-resume callbacks
+ * such as {@link #onNewIntent} and {@link #onActivityResult}. This is primarily intended
+ * to give the activity a hint that its state is no longer saved -- it will generally
+ * be called after {@link #onSaveInstanceState} and prior to the activity being
+ * resumed/started again.
+ */
+ public void onStateNotSaved() {
+ }
+
+ /**
* Called after {@link #onRestoreInstanceState}, {@link #onRestart}, or
* {@link #onPause}, for your activity to start interacting with the user.
* This is a good place to begin animations, open exclusive-access devices
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2b4d03b..fd88a05 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3079,6 +3079,7 @@
r.activity.mStartedActivity = false;
}
try {
+ r.activity.onStateNotSaved();
r.activity.mFragments.noteStateNotSaved();
if (r.pendingIntents != null) {
deliverNewIntents(r, r.pendingIntents);
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index b4cbf35..f9fa027 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -105,7 +105,10 @@
/** View that handles event dispatch and content transitions. */
private PopupDecorView mDecorView;
- /** The contents of the popup. */
+ /** View that holds the background and may animate during a transition. */
+ private View mBackgroundView;
+
+ /** The contents of the popup. May be identical to the background view. */
private View mContentView;
private boolean mFocusable;
@@ -1111,18 +1114,18 @@
if (aboveAnchor != mAboveAnchor) {
mAboveAnchor = aboveAnchor;
- if (mBackground != null) {
- // If the background drawable provided was a StateListDrawable with above-anchor
- // and below-anchor states, use those. Otherwise rely on refreshDrawableState to
- // do the job.
+ if (mBackground != null && mBackgroundView != null) {
+ // If the background drawable provided was a StateListDrawable
+ // with above-anchor and below-anchor states, use those.
+ // Otherwise, rely on refreshDrawableState to do the job.
if (mAboveAnchorBackgroundDrawable != null) {
if (mAboveAnchor) {
- mDecorView.setBackground(mAboveAnchorBackgroundDrawable);
+ mBackgroundView.setBackground(mAboveAnchorBackgroundDrawable);
} else {
- mDecorView.setBackground(mBelowAnchorBackgroundDrawable);
+ mBackgroundView.setBackground(mBelowAnchorBackgroundDrawable);
}
} else {
- mDecorView.refreshDrawableState();
+ mBackgroundView.refreshDrawableState();
}
}
}
@@ -1164,22 +1167,21 @@
// When a background is available, we embed the content view within
// another view that owns the background drawable.
- final View backgroundView;
if (mBackground != null) {
- backgroundView = createBackgroundView(mContentView);
- backgroundView.setBackground(mBackground);
+ mBackgroundView = createBackgroundView(mContentView);
+ mBackgroundView.setBackground(mBackground);
} else {
- backgroundView = mContentView;
+ mBackgroundView = mContentView;
}
- mDecorView = createDecorView(backgroundView);
+ mDecorView = createDecorView(mBackgroundView);
// The background owner should be elevated so that it casts a shadow.
- backgroundView.setElevation(mElevation);
+ mBackgroundView.setElevation(mElevation);
// We may wrap that in another view, so we'll need to manually specify
// the surface insets.
- final int surfaceInset = (int) Math.ceil(backgroundView.getZ() * 2);
+ final int surfaceInset = (int) Math.ceil(mBackgroundView.getZ() * 2);
p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
p.hasManualSurfaceInsets = true;
@@ -1650,6 +1652,7 @@
// This needs to stay until after all transitions have ended since we
// need the reference to cancel transitions in preparePopup().
mDecorView = null;
+ mBackgroundView = null;
mIsTransitioningToDismiss = false;
}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index d954b71..55493c3 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -28,6 +28,7 @@
public class MetricsLogger implements MetricsConstants {
// Temporary constants go here, to await migration to MetricsConstants.
// next value is 239;
+ public static final int ACTION_ASSIST_LONG_PRESS = 239;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 6104264..fef65ee 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.util.SparseIntArray;
+import java.util.TreeSet;
+
/**
* Class to provide information about the audio devices.
*/
@@ -109,6 +111,14 @@
* A device type connected over IP.
*/
public static final int TYPE_IP = 20;
+ /**
+ * @hide
+ * A remote-submix device.
+ * We need this for CTS, but it is not part of the external API.
+ * FIXME It has been suggested that CTS should only be testing public APIs.
+ * Consider this for a public API.
+ */
+ public static final int TYPE_REMOTE_SUBMIX = 0x7FFF;
private final AudioDevicePort mPort;
@@ -193,13 +203,24 @@
* Note: an empty array indicates that the device supports arbitrary channel counts.
*/
public @NonNull int[] getChannelCounts() {
- int[] masks = getChannelMasks();
- int[] counts = new int[masks.length];
- // TODO: consider channel index masks
- for (int mask_index = 0; mask_index < masks.length; mask_index++) {
- counts[mask_index] = isSink()
- ? AudioFormat.channelCountFromOutChannelMask(masks[mask_index])
- : AudioFormat.channelCountFromInChannelMask(masks[mask_index]);
+ TreeSet<Integer> countSet = new TreeSet<Integer>();
+
+ // Channel Masks
+ for (int mask : getChannelMasks()) {
+ countSet.add(isSink() ?
+ AudioFormat.channelCountFromOutChannelMask(mask)
+ : AudioFormat.channelCountFromInChannelMask(mask));
+ }
+
+ // Index Masks
+ for (int index_mask : getChannelIndexMasks()) {
+ countSet.add(Integer.bitCount(index_mask));
+ }
+
+ int[] counts = new int[countSet.size()];
+ int index = 0;
+ for (int count : countSet) {
+ counts[index++] = count;
}
return counts;
}
@@ -265,6 +286,7 @@
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
@@ -282,10 +304,7 @@
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, TYPE_LINE_DIGITAL);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP);
-
- // not covered here, legacy
- //AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
- //AudioSystem.DEVICE_IN_REMOTE_SUBMIX
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);
// privileges mapping to output device
EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 86755d1..6c0deb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1056,6 +1056,7 @@
if (shouldDisableNavbarGestures()) {
return false;
}
+ MetricsLogger.action(mContext, MetricsLogger.ACTION_ASSIST_LONG_PRESS);
mAssistManager.startAssist(new Bundle() /* args */);
awakenDreams();
if (mNavigationBarView != null) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 7e2ad29..9da30bf 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -786,7 +786,8 @@
}
boolean isLockTaskWhitelistedLocked() {
- if (mCallingPackage == null) {
+ String pkg = (realActivity != null) ? realActivity.getPackageName() : null;
+ if (pkg == null) {
return false;
}
String[] packages = mService.mLockTaskPackages.get(userId);
@@ -794,7 +795,7 @@
return false;
}
for (int i = packages.length - 1; i >= 0; --i) {
- if (mCallingPackage.equals(packages[i])) {
+ if (pkg.equals(packages[i])) {
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 3227ef8..71a2d59 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -34,6 +34,7 @@
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.provider.Telephony.Sms.Intents;
+import android.security.Credentials;
import android.util.ArraySet;
import android.util.Log;
@@ -298,6 +299,15 @@
grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId);
}
+ // CertInstaller
+ Intent certInstallerIntent = new Intent(Credentials.INSTALL_ACTION);
+ PackageParser.Package certInstallerPackage = getDefaultSystemHandlerActivityPackageLPr(
+ certInstallerIntent, userId);
+ if (certInstallerPackage != null
+ && doesPackageSupportRuntimePermissions(certInstallerPackage)) {
+ grantRuntimePermissionsLPw(certInstallerPackage, STORAGE_PERMISSIONS, true, userId);
+ }
+
// Dialer
if (dialerAppPackageNames == null) {
Intent dialerIntent = new Intent(Intent.ACTION_DIAL);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 04d6d98..1788e88 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -48,6 +48,7 @@
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.IResultReceiver;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -225,6 +226,7 @@
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& structureEnabled) {
try {
+ MetricsLogger.count(mContext, "assist_with_context", 1);
if (mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
mAssistReceiver, activityToken)) {
needDisclosure = true;
@@ -249,6 +251,7 @@
mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED
&& screenshotEnabled) {
try {
+ MetricsLogger.count(mContext, "assist_with_screen", 1);
needDisclosure = true;
mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
} catch (RemoteException e) {