summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt3
-rw-r--r--api/system-current.txt3
-rw-r--r--api/test-current.txt3
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java60
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl3
-rw-r--r--core/java/android/widget/Spinner.java4
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java10
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java145
-rw-r--r--media/java/android/media/MediaCodec.java2
-rw-r--r--media/jni/android_media_MediaCodec.cpp67
-rw-r--r--media/jni/android_media_MediaCodec.h1
-rw-r--r--packages/SettingsLib/res/values/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java371
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java146
-rw-r--r--services/print/java/com/android/server/print/PrintManagerService.java10
-rw-r--r--services/print/java/com/android/server/print/UserState.java3
17 files changed, 709 insertions, 133 deletions
diff --git a/api/current.txt b/api/current.txt
index 418940918654..47d32077861a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5793,6 +5793,7 @@ package android.app.admin {
method public boolean getCameraDisabled(android.content.ComponentName);
method public java.lang.String getCertInstallerPackage(android.content.ComponentName) throws java.lang.SecurityException;
method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
+ method public boolean getCrossProfileContactsSearchDisabled(android.content.ComponentName);
method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
method public int getCurrentFailedPasswordAttempts();
method public java.lang.String getDeviceOwnerLockScreenInfo();
@@ -5857,6 +5858,7 @@ package android.app.admin {
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+ method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
@@ -12784,6 +12786,7 @@ package android.graphics.drawable {
method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
field public static final int PADDING_MODE_NEST = 0; // 0x0
field public static final int PADDING_MODE_STACK = 1; // 0x1
+ field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
}
public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
diff --git a/api/system-current.txt b/api/system-current.txt
index a63a0731d7cf..dbbc04be2730 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5919,6 +5919,7 @@ package android.app.admin {
method public boolean getCameraDisabled(android.content.ComponentName);
method public java.lang.String getCertInstallerPackage(android.content.ComponentName) throws java.lang.SecurityException;
method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
+ method public boolean getCrossProfileContactsSearchDisabled(android.content.ComponentName);
method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
method public int getCurrentFailedPasswordAttempts();
method public deprecated java.lang.String getDeviceInitializerApp();
@@ -5992,6 +5993,7 @@ package android.app.admin {
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+ method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
@@ -13139,6 +13141,7 @@ package android.graphics.drawable {
method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
field public static final int PADDING_MODE_NEST = 0; // 0x0
field public static final int PADDING_MODE_STACK = 1; // 0x1
+ field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
}
public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
diff --git a/api/test-current.txt b/api/test-current.txt
index f15ab581877b..6eba6bd7a2df 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5795,6 +5795,7 @@ package android.app.admin {
method public boolean getCameraDisabled(android.content.ComponentName);
method public java.lang.String getCertInstallerPackage(android.content.ComponentName) throws java.lang.SecurityException;
method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
+ method public boolean getCrossProfileContactsSearchDisabled(android.content.ComponentName);
method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
method public int getCurrentFailedPasswordAttempts();
method public java.lang.String getDeviceOwnerLockScreenInfo();
@@ -5859,6 +5860,7 @@ package android.app.admin {
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
+ method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
@@ -12792,6 +12794,7 @@ package android.graphics.drawable {
method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
field public static final int PADDING_MODE_NEST = 0; // 0x0
field public static final int PADDING_MODE_STACK = 1; // 0x1
+ field public static final int UNDEFINED_INSET = -2147483648; // 0x80000000
}
public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 08e9b1e897af..4de3ceb4792e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -3540,6 +3540,66 @@ public class DevicePolicyManager {
}
/**
+ * Called by a profile owner of a managed profile to set whether contacts search from
+ * the managed profile will be shown in the parent profile, for incoming calls.
+ *
+ * <p>The calling device admin must be a profile owner. If it is not, a
+ * security exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param disabled If true contacts search in the managed profile is not displayed.
+ */
+ public void setCrossProfileContactsSearchDisabled(@NonNull ComponentName admin,
+ boolean disabled) {
+ if (mService != null) {
+ try {
+ mService.setCrossProfileContactsSearchDisabled(admin, disabled);
+ } catch (RemoteException e) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+ }
+ }
+ }
+
+ /**
+ * Called by a profile owner of a managed profile to determine whether or not contacts search
+ * has been disabled.
+ *
+ * <p>The calling device admin must be a profile owner. If it is not, a
+ * security exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ */
+ public boolean getCrossProfileContactsSearchDisabled(@NonNull ComponentName admin) {
+ if (mService != null) {
+ try {
+ return mService.getCrossProfileContactsSearchDisabled(admin);
+ } catch (RemoteException e) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Determine whether or not contacts search has been disabled.
+ *
+ * @param userHandle The user for whom to check the contacts search permission
+ * @hide
+ */
+ public boolean getCrossProfileContactsSearchDisabled(@NonNull UserHandle userHandle) {
+ if (mService != null) {
+ try {
+ return mService
+ .getCrossProfileContactsSearchDisabledForUser(userHandle.getIdentifier());
+ } catch (RemoteException e) {
+ Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
+ }
+ }
+ return false;
+ }
+
+ /**
* Start Quick Contact on the managed profile for the user, if the policy allows.
* @hide
*/
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 754cb432bf7c..d3c32c51798a 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -202,6 +202,9 @@ interface IDevicePolicyManager {
void setCrossProfileCallerIdDisabled(in ComponentName who, boolean disabled);
boolean getCrossProfileCallerIdDisabled(in ComponentName who);
boolean getCrossProfileCallerIdDisabledForUser(int userId);
+ void setCrossProfileContactsSearchDisabled(in ComponentName who, boolean disabled);
+ boolean getCrossProfileContactsSearchDisabled(in ComponentName who);
+ boolean getCrossProfileContactsSearchDisabledForUser(int userId);
void startManagedQuickContact(String lookupKey, long contactId, long directoryId, in Intent originalIntent);
void setBluetoothContactSharingDisabled(in ComponentName who, boolean disabled);
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index c79e18449e39..09cf7049c04a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -271,6 +271,10 @@ public class Spinner extends AbsSpinner implements OnClickListener {
attrs, R.styleable.Spinner, defStyleAttr, defStyleRes);
mDropDownWidth = pa.getLayoutDimension(R.styleable.Spinner_dropDownWidth,
ViewGroup.LayoutParams.WRAP_CONTENT);
+ if (pa.hasValueOrEmpty(R.styleable.Spinner_dropDownSelector)) {
+ popup.setListSelector(pa.getDrawable(
+ R.styleable.Spinner_dropDownSelector));
+ }
popup.setBackgroundDrawable(pa.getDrawable(R.styleable.Spinner_popupBackground));
popup.setPromptText(a.getString(R.styleable.Spinner_prompt));
pa.recycle();
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index f159a4d71f20..b4c4ef506f46 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2677,20 +2677,16 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
invalidatePanelMenu(FEATURE_ACTION_BAR);
}
} else {
- mTitleView = (TextView)findViewById(R.id.title);
+ mTitleView = (TextView) findViewById(R.id.title);
if (mTitleView != null) {
- mTitleView.setLayoutDirection(mDecor.getLayoutDirection());
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
- View titleContainer = findViewById(
- R.id.title_container);
+ final View titleContainer = findViewById(R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
} else {
mTitleView.setVisibility(View.GONE);
}
- if (mContentParent instanceof FrameLayout) {
- ((FrameLayout)mContentParent).setForeground(null);
- }
+ mContentParent.setForeground(null);
} else {
mTitleView.setText(mTitle);
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 651b45334ee0..e2150c02c0e6 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -82,8 +82,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
*/
public static final int PADDING_MODE_STACK = 1;
- /** Value used for undefined start and end insets. */
- private static final int UNDEFINED_INSET = Integer.MIN_VALUE;
+ /**
+ * Value used for undefined start and end insets.
+ *
+ * @see #getLayerInsetStart(int)
+ * @see #getLayerInsetEnd(int)
+ */
+ public static final int UNDEFINED_INSET = Integer.MIN_VALUE;
LayerState mLayerState;
@@ -867,7 +872,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
/**
* @param index the index of the layer
- * @return number of pixels to inset from the start bound
+ * @return the number of pixels to inset from the start bound, or
+ * {@link #UNDEFINED_INSET} if not specified
* @attr ref android.R.styleable#LayerDrawableItem_start
*/
public int getLayerInsetStart(int index) {
@@ -877,7 +883,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
/**
* @param index the index of the layer to adjust
- * @param e number of pixels to inset from the end bound
+ * @param e number of pixels to inset from the end bound, or
+ * {@link #UNDEFINED_INSET} if not specified
* @attr ref android.R.styleable#LayerDrawableItem_end
*/
public void setLayerInsetEnd(int index, int e) {
@@ -977,34 +984,33 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
computeStackedPadding(padding);
}
+ final int paddingT = layerState.mPaddingTop;
+ final int paddingB = layerState.mPaddingBottom;
+
+ // Resolve padding for RTL. Relative padding overrides absolute
+ // padding.
+ final boolean isLayoutRtl = getLayoutDirection() == LayoutDirection.RTL;
+ final int paddingRtlL = isLayoutRtl ? layerState.mPaddingEnd : layerState.mPaddingStart;
+ final int paddingRtlR = isLayoutRtl ? layerState.mPaddingStart : layerState.mPaddingEnd;
+ final int paddingL = paddingRtlL >= 0 ? paddingRtlL : layerState.mPaddingLeft;
+ final int paddingR = paddingRtlR >= 0 ? paddingRtlR : layerState.mPaddingRight;
+
// If padding was explicitly specified (e.g. not -1) then override the
// computed padding in that dimension.
- if (layerState.mPaddingTop >= 0) {
- padding.top = layerState.mPaddingTop;
- }
-
- if (layerState.mPaddingBottom >= 0) {
- padding.bottom = layerState.mPaddingBottom;
+ if (paddingL >= 0) {
+ padding.left = paddingL;
}
- final int paddingRtlLeft;
- final int paddingRtlRight;
- if (getLayoutDirection() == LayoutDirection.RTL) {
- paddingRtlLeft = layerState.mPaddingEnd;
- paddingRtlRight = layerState.mPaddingStart;
- } else {
- paddingRtlLeft = layerState.mPaddingStart;
- paddingRtlRight = layerState.mPaddingEnd;
+ if (paddingT >= 0) {
+ padding.top = paddingT;
}
- final int paddingLeft = paddingRtlLeft >= 0 ? paddingRtlLeft : layerState.mPaddingLeft;
- if (paddingLeft >= 0) {
- padding.left = paddingLeft;
+ if (paddingR >= 0) {
+ padding.right = paddingR;
}
- final int paddingRight = paddingRtlRight >= 0 ? paddingRtlRight : layerState.mPaddingRight;
- if (paddingRight >= 0) {
- padding.right = paddingRight;
+ if (paddingB >= 0) {
+ padding.bottom = paddingB;
}
return padding.left != 0 || padding.top != 0 || padding.right != 0 || padding.bottom != 0;
@@ -1471,58 +1477,59 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
private void updateLayerBounds(Rect bounds) {
- int padL = 0;
- int padT = 0;
- int padR = 0;
- int padB = 0;
+ int paddingL = 0;
+ int paddingT = 0;
+ int paddingR = 0;
+ int paddingB = 0;
final Rect outRect = mTmpOutRect;
final int layoutDirection = getLayoutDirection();
- final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
+ final boolean isLayoutRtl = layoutDirection == LayoutDirection.RTL;
+ final boolean isPaddingNested = mLayerState.mPaddingMode == PADDING_MODE_NEST;
final ChildDrawable[] array = mLayerState.mChildren;
- final int N = mLayerState.mNum;
- for (int i = 0; i < N; i++) {
+
+ for (int i = 0, count = mLayerState.mNum; i < count; i++) {
final ChildDrawable r = array[i];
final Drawable d = r.mDrawable;
if (d == null) {
continue;
}
- final Rect container = mTmpContainer;
- container.set(d.getBounds());
+ final int insetT = r.mInsetT;
+ final int insetB = r.mInsetB;
- // Take the resolved layout direction into account. If start / end
- // padding are defined, they will be resolved (hence overriding) to
- // left / right or right / left depending on the resolved layout
- // direction. If start / end padding are not defined, use the
- // left / right ones.
- final int insetL, insetR;
- if (layoutDirection == LayoutDirection.RTL) {
- insetL = r.mInsetE == UNDEFINED_INSET ? r.mInsetL : r.mInsetE;
- insetR = r.mInsetS == UNDEFINED_INSET ? r.mInsetR : r.mInsetS;
- } else {
- insetL = r.mInsetS == UNDEFINED_INSET ? r.mInsetL : r.mInsetS;
- insetR = r.mInsetE == UNDEFINED_INSET ? r.mInsetR : r.mInsetE;
- }
+ // Resolve insets for RTL. Relative insets override absolute
+ // insets.
+ final int insetRtlL = isLayoutRtl ? r.mInsetE : r.mInsetS;
+ final int insetRtlR = isLayoutRtl ? r.mInsetS : r.mInsetE;
+ final int insetL = insetRtlL == UNDEFINED_INSET ? r.mInsetL : insetRtlL;
+ final int insetR = insetRtlR == UNDEFINED_INSET ? r.mInsetR : insetRtlR;
// Establish containing region based on aggregate padding and
// requested insets for the current layer.
- container.set(bounds.left + insetL + padL, bounds.top + r.mInsetT + padT,
- bounds.right - insetR - padR, bounds.bottom - r.mInsetB - padB);
-
- // Apply resolved gravity to drawable based on resolved size.
- final int gravity = resolveGravity(r.mGravity, r.mWidth, r.mHeight,
- d.getIntrinsicWidth(), d.getIntrinsicHeight());
- final int w = r.mWidth < 0 ? d.getIntrinsicWidth() : r.mWidth;
- final int h = r.mHeight < 0 ? d.getIntrinsicHeight() : r.mHeight;
- Gravity.apply(gravity, w, h, container, outRect, layoutDirection);
+ final Rect container = mTmpContainer;
+ container.set(bounds.left + insetL + paddingL, bounds.top + insetT + paddingT,
+ bounds.right - insetR - paddingR, bounds.bottom - insetB - paddingB);
+
+ // Compute a reasonable default gravity based on the intrinsic and
+ // explicit dimensions, if specified.
+ final int intrinsicW = d.getIntrinsicWidth();
+ final int intrinsicH = d.getIntrinsicHeight();
+ final int layerW = r.mWidth;
+ final int layerH = r.mHeight;
+ final int gravity = resolveGravity(r.mGravity, layerW, layerH, intrinsicW, intrinsicH);
+
+ // Explicit dimensions override intrinsic dimensions.
+ final int resolvedW = layerW < 0 ? intrinsicW : layerW;
+ final int resolvedH = layerH < 0 ? intrinsicH : layerH;
+ Gravity.apply(gravity, resolvedW, resolvedH, container, outRect, layoutDirection);
d.setBounds(outRect);
- if (nest) {
- padL += mPaddingL[i];
- padR += mPaddingR[i];
- padT += mPaddingT[i];
- padB += mPaddingB[i];
+ if (isPaddingNested) {
+ paddingL += mPaddingL[i];
+ paddingR += mPaddingR[i];
+ paddingT += mPaddingT[i];
+ paddingB += mPaddingB[i];
}
}
}
@@ -1578,6 +1585,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
int padR = 0;
final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
+ final boolean isLayoutRtl = getLayoutDirection() == LayoutDirection.RTL;
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNum;
for (int i = 0; i < N; i++) {
@@ -1591,15 +1599,10 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
// left / right or right / left depending on the resolved layout
// direction. If start / end padding are not defined, use the
// left / right ones.
- final int insetL, insetR;
- final int layoutDirection = getLayoutDirection();
- if (layoutDirection == LayoutDirection.RTL) {
- insetL = r.mInsetE == UNDEFINED_INSET ? r.mInsetL : r.mInsetE;
- insetR = r.mInsetS == UNDEFINED_INSET ? r.mInsetR : r.mInsetS;
- } else {
- insetL = r.mInsetS == UNDEFINED_INSET ? r.mInsetL : r.mInsetS;
- insetR = r.mInsetE == UNDEFINED_INSET ? r.mInsetR : r.mInsetE;
- }
+ final int insetRtlL = isLayoutRtl ? r.mInsetE : r.mInsetS;
+ final int insetRtlR = isLayoutRtl ? r.mInsetS : r.mInsetE;
+ final int insetL = insetRtlL == UNDEFINED_INSET ? r.mInsetL : insetRtlL;
+ final int insetR = insetRtlR == UNDEFINED_INSET ? r.mInsetR : insetRtlR;
// Don't apply padding and insets for children that don't have
// an intrinsic dimension.
@@ -1659,8 +1662,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
if (r.mDrawable != null) {
final Rect rect = mTmpRect;
r.mDrawable.getPadding(rect);
- if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
- rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
+ if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i]
+ || rect.right != mPaddingR[i] || rect.bottom != mPaddingB[i]) {
mPaddingL[i] = rect.left;
mPaddingT[i] = rect.top;
mPaddingR[i] = rect.right;
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 478fd992c3bd..f1f84375c36b 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2175,8 +2175,6 @@ final public class MediaCodec {
int offset, int size, long presentationTimeUs, int flags)
throws CryptoException;
- // The following mode constants MUST stay in sync with their equivalents
- // in media/hardware/CryptoAPI.h !
public static final int CRYPTO_MODE_UNENCRYPTED = 0;
public static final int CRYPTO_MODE_AES_CTR = 1;
public static final int CRYPTO_MODE_AES_CBC = 2;
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 49b579ce438d..2004a3aef2b8 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -85,6 +85,13 @@ static struct {
jmethodID setNativeObjectLocked;
} gPersistentSurfaceClassInfo;
+static struct {
+ jint Unencrypted;
+ jint AesCtr;
+ jint AesCbc;
+} gCryptoModes;
+
+
struct fields_t {
jfieldID context;
jmethodID postEventFromNativeID;
@@ -94,6 +101,9 @@ struct fields_t {
jfieldID cryptoInfoKeyID;
jfieldID cryptoInfoIVID;
jfieldID cryptoInfoModeID;
+ jfieldID cryptoInfoPatternID;
+ jfieldID patternEncryptBlocksID;
+ jfieldID patternSkipBlocksID;
};
static fields_t gFields;
@@ -325,11 +335,12 @@ status_t JMediaCodec::queueSecureInputBuffer(
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg) {
return mCodec->queueSecureInputBuffer(
- index, offset, subSamples, numSubSamples, key, iv, mode,
+ index, offset, subSamples, numSubSamples, key, iv, mode, pattern,
presentationTimeUs, flags, errorDetailMsg);
}
@@ -1275,7 +1286,26 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
jbyteArray ivObj =
(jbyteArray)env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoIVID);
- jint mode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
+ jint jmode = env->GetIntField(cryptoInfoObj, gFields.cryptoInfoModeID);
+ enum CryptoPlugin::Mode mode;
+ if (jmode == gCryptoModes.Unencrypted) {
+ mode = CryptoPlugin::kMode_Unencrypted;
+ } else if (jmode == gCryptoModes.AesCtr) {
+ mode = CryptoPlugin::kMode_AES_CTR;
+ } else if (jmode == gCryptoModes.AesCbc) {
+ mode = CryptoPlugin::kMode_AES_CBC;
+ } else {
+ throwExceptionAsNecessary(env, INVALID_OPERATION);
+ return;
+ }
+
+ jobject patternObj = env->GetObjectField(cryptoInfoObj, gFields.cryptoInfoPatternID);
+
+ CryptoPlugin::Pattern pattern;
+ if (patternObj != NULL) {
+ pattern.mEncryptBlocks = env->GetIntField(patternObj, gFields.patternEncryptBlocksID);
+ pattern.mSkipBlocks = env->GetIntField(patternObj, gFields.patternSkipBlocksID);
+ }
status_t err = OK;
@@ -1360,7 +1390,8 @@ static void android_media_MediaCodec_queueSecureInputBuffer(
index, offset,
subSamples, numSubSamples,
(const uint8_t *)key, (const uint8_t *)iv,
- (CryptoPlugin::Mode)mode,
+ mode,
+ pattern,
timestampUs,
flags,
&errorDetailMsg);
@@ -1658,6 +1689,22 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
CHECK(gFields.postEventFromNativeID != NULL);
+ jfieldID field;
+ field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_UNENCRYPTED", "I");
+ CHECK(field != NULL);
+ gCryptoModes.Unencrypted =
+ env->GetStaticIntField(clazz.get(), field);
+
+ field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CTR", "I");
+ CHECK(field != NULL);
+ gCryptoModes.AesCtr =
+ env->GetStaticIntField(clazz.get(), field);
+
+ field = env->GetStaticFieldID(clazz.get(), "CRYPTO_MODE_AES_CBC", "I");
+ CHECK(field != NULL);
+ gCryptoModes.AesCbc =
+ env->GetStaticIntField(clazz.get(), field);
+
clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
CHECK(clazz.get() != NULL);
@@ -1682,10 +1729,22 @@ static void android_media_MediaCodec_native_init(JNIEnv *env) {
gFields.cryptoInfoModeID = env->GetFieldID(clazz.get(), "mode", "I");
CHECK(gFields.cryptoInfoModeID != NULL);
+ gFields.cryptoInfoPatternID = env->GetFieldID(clazz.get(), "pattern",
+ "Landroid/media/MediaCodec$CryptoInfo$Pattern;");
+ CHECK(gFields.cryptoInfoPatternID != NULL);
+
+ clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo$Pattern"));
+ CHECK(clazz.get() != NULL);
+
+ gFields.patternEncryptBlocksID = env->GetFieldID(clazz.get(), "mEncryptBlocks", "I");
+ CHECK(gFields.patternEncryptBlocksID != NULL);
+
+ gFields.patternSkipBlocksID = env->GetFieldID(clazz.get(), "mSkipBlocks", "I");
+ CHECK(gFields.patternSkipBlocksID != NULL);
+
clazz.reset(env->FindClass("android/media/MediaCodec$CryptoException"));
CHECK(clazz.get() != NULL);
- jfieldID field;
field = env->GetStaticFieldID(clazz.get(), "ERROR_NO_KEY", "I");
CHECK(field != NULL);
gCryptoErrorCodes.cryptoErrorNoKey =
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 6650cf9254e1..c0c47ef2aeda 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -81,6 +81,7 @@ struct JMediaCodec : public AHandler {
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg);
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index ac19cf50d62a..6dfa9ad2d26e 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -684,6 +684,8 @@
<string name="select_webview_provider_title">WebView implementation</string>
<!-- Developer settings: select WebView provider dialog title -->
<string name="select_webview_provider_dialog_title">Set WebView implementation</string>
+ <!-- Developer settings: confirmation dialog text for the WebView provider selection dialog -->
+ <string name="select_webview_provider_confirmation_text">The chosen WebView implementation is disabled, and must be enabled to be used, do you wish to enable it?</string>
<!-- Developer settings screen, convert userdata to file encryption option name -->
<string name="convert_to_file_encryption">Convert to file encryption</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
new file mode 100644
index 000000000000..f1beb103d6c4
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2016 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 com.android.settingslib.users;
+
+import android.app.AppGlobals;
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class AppRestrictionsHelper {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "AppRestrictionsHelper";
+
+ private final Context mContext;
+ private final PackageManager mPackageManager;
+ private final IPackageManager mIPm;
+ private final UserManager mUserManager;
+ private final UserHandle mUser;
+ private final boolean mRestrictedProfile;
+
+ HashMap<String,Boolean> mSelectedPackages = new HashMap<>();
+ private List<SelectableAppInfo> mVisibleApps;
+
+ public AppRestrictionsHelper(Context context, UserHandle user) {
+ mContext = context;
+ mPackageManager = context.getPackageManager();
+ mIPm = AppGlobals.getPackageManager();
+ mUser = user;
+ mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+ mRestrictedProfile = mUserManager.getUserInfo(mUser.getIdentifier()).isRestricted();
+ }
+
+ public void setPackageSelected(String packageName, boolean selected) {
+ mSelectedPackages.put(packageName, selected);
+ }
+
+ public boolean isPackageSelected(String packageName) {
+ return mSelectedPackages.get(packageName);
+ }
+
+ public List<SelectableAppInfo> getVisibleApps() {
+ return mVisibleApps;
+ }
+
+ public void applyUserAppsStates(OnDisableUiForPackageListener listener) {
+ final int userId = mUser.getIdentifier();
+ if (!mUserManager.getUserInfo(userId).isRestricted() && userId != UserHandle.myUserId()) {
+ Log.e(TAG, "Cannot apply application restrictions on another user!");
+ return;
+ }
+ for (Map.Entry<String,Boolean> entry : mSelectedPackages.entrySet()) {
+ String packageName = entry.getKey();
+ boolean enabled = entry.getValue();
+ applyUserAppState(packageName, enabled, listener);
+ }
+ }
+
+ public void applyUserAppState(String packageName, boolean enabled,
+ OnDisableUiForPackageListener listener) {
+ final int userId = mUser.getIdentifier();
+ if (enabled) {
+ // Enable selected apps
+ try {
+ ApplicationInfo info = mIPm.getApplicationInfo(packageName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ if (info == null || !info.enabled
+ || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier());
+ if (DEBUG) {
+ Log.d(TAG, "Installing " + packageName);
+ }
+ }
+ if (info != null && (info.privateFlags&ApplicationInfo.PRIVATE_FLAG_HIDDEN) != 0
+ && (info.flags&ApplicationInfo.FLAG_INSTALLED) != 0) {
+ listener.onDisableUiForPackage(packageName);
+ mIPm.setApplicationHiddenSettingAsUser(packageName, false, userId);
+ if (DEBUG) {
+ Log.d(TAG, "Unhiding " + packageName);
+ }
+ }
+ } catch (RemoteException re) {
+ // Ignore
+ }
+ } else {
+ // Blacklist all other apps, system or downloaded
+ try {
+ ApplicationInfo info = mIPm.getApplicationInfo(packageName, 0, userId);
+ if (info != null) {
+ if (mRestrictedProfile) {
+ mIPm.deletePackageAsUser(packageName, null, mUser.getIdentifier(),
+ PackageManager.DELETE_SYSTEM_APP);
+ if (DEBUG) {
+ Log.d(TAG, "Uninstalling " + packageName);
+ }
+ } else {
+ listener.onDisableUiForPackage(packageName);
+ mIPm.setApplicationHiddenSettingAsUser(packageName, true, userId);
+ if (DEBUG) {
+ Log.d(TAG, "Hiding " + packageName);
+ }
+ }
+ }
+ } catch (RemoteException re) {
+ // Ignore
+ }
+ }
+ }
+
+ public void fetchAndMergeApps() {
+ mVisibleApps = new ArrayList<>();
+ final PackageManager pm = mPackageManager;
+ final IPackageManager ipm = mIPm;
+
+ final HashSet<String> excludePackages = new HashSet<>();
+ addSystemImes(excludePackages);
+
+ // Add launchers
+ Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
+ launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ addSystemApps(mVisibleApps, launcherIntent, excludePackages);
+
+ // Add widgets
+ Intent widgetIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
+ addSystemApps(mVisibleApps, widgetIntent, excludePackages);
+
+ List<ApplicationInfo> installedApps = pm.getInstalledApplications(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ for (ApplicationInfo app : installedApps) {
+ // If it's not installed, skip
+ if ((app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) continue;
+
+ if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) {
+ // Downloaded app
+ SelectableAppInfo info = new SelectableAppInfo();
+ info.packageName = app.packageName;
+ info.appName = app.loadLabel(pm);
+ info.activityName = info.appName;
+ info.icon = app.loadIcon(pm);
+ mVisibleApps.add(info);
+ } else {
+ try {
+ PackageInfo pi = pm.getPackageInfo(app.packageName, 0);
+ // If it's a system app that requires an account and doesn't see restricted
+ // accounts, mark for removal. It might get shown in the UI if it has an icon
+ // but will still be marked as false and immutable.
+ if (mRestrictedProfile
+ && pi.requiredAccountType != null && pi.restrictedAccountType == null) {
+ mSelectedPackages.put(app.packageName, false);
+ }
+ } catch (PackageManager.NameNotFoundException re) {
+ // Skip
+ }
+ }
+ }
+
+ // Get the list of apps already installed for the user
+ List<ApplicationInfo> userApps = null;
+ try {
+ ParceledListSlice<ApplicationInfo> listSlice = ipm.getInstalledApplications(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, mUser.getIdentifier());
+ if (listSlice != null) {
+ userApps = listSlice.getList();
+ }
+ } catch (RemoteException re) {
+ // Ignore
+ }
+
+ if (userApps != null) {
+ for (ApplicationInfo app : userApps) {
+ if ((app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) continue;
+
+ if ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0) {
+ // Downloaded app
+ SelectableAppInfo info = new SelectableAppInfo();
+ info.packageName = app.packageName;
+ info.appName = app.loadLabel(pm);
+ info.activityName = info.appName;
+ info.icon = app.loadIcon(pm);
+ mVisibleApps.add(info);
+ }
+ }
+ }
+
+ // Sort the list of visible apps
+ Collections.sort(mVisibleApps, new AppLabelComparator());
+
+ // Remove dupes
+ Set<String> dedupPackageSet = new HashSet<String>();
+ for (int i = mVisibleApps.size() - 1; i >= 0; i--) {
+ SelectableAppInfo info = mVisibleApps.get(i);
+ if (DEBUG) Log.i(TAG, info.toString());
+ String both = info.packageName + "+" + info.activityName;
+ if (!TextUtils.isEmpty(info.packageName)
+ && !TextUtils.isEmpty(info.activityName)
+ && dedupPackageSet.contains(both)) {
+ mVisibleApps.remove(i);
+ } else {
+ dedupPackageSet.add(both);
+ }
+ }
+
+ // Establish master/slave relationship for entries that share a package name
+ HashMap<String,SelectableAppInfo> packageMap = new HashMap<String,SelectableAppInfo>();
+ for (SelectableAppInfo info : mVisibleApps) {
+ if (packageMap.containsKey(info.packageName)) {
+ info.masterEntry = packageMap.get(info.packageName);
+ } else {
+ packageMap.put(info.packageName, info);
+ }
+ }
+ }
+
+ /**
+ * Find all pre-installed input methods that are marked as default
+ * and add them to an exclusion list so that they aren't
+ * presented to the user for toggling.
+ * Don't add non-default ones, as they may include other stuff that we
+ * don't need to auto-include.
+ * @param excludePackages the set of package names to append to
+ */
+ private void addSystemImes(Set<String> excludePackages) {
+ InputMethodManager imm = (InputMethodManager)
+ mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+ List<InputMethodInfo> imis = imm.getInputMethodList();
+ for (InputMethodInfo imi : imis) {
+ try {
+ if (imi.isDefault(mContext) && isSystemPackage(imi.getPackageName())) {
+ excludePackages.add(imi.getPackageName());
+ }
+ } catch (Resources.NotFoundException rnfe) {
+ // Not default
+ }
+ }
+ }
+
+ /**
+ * Add system apps that match an intent to the list, excluding any packages in the exclude list.
+ * @param visibleApps list of apps to append the new list to
+ * @param intent the intent to match
+ * @param excludePackages the set of package names to be excluded, since they're required
+ */
+ private void addSystemApps(List<SelectableAppInfo> visibleApps, Intent intent,
+ Set<String> excludePackages) {
+ final PackageManager pm = mPackageManager;
+ List<ResolveInfo> launchableApps = pm.queryIntentActivities(intent,
+ PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ for (ResolveInfo app : launchableApps) {
+ if (app.activityInfo != null && app.activityInfo.applicationInfo != null) {
+ final String packageName = app.activityInfo.packageName;
+ int flags = app.activityInfo.applicationInfo.flags;
+ if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ || (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+ // System app
+ // Skip excluded packages
+ if (excludePackages.contains(packageName)) continue;
+ int enabled = pm.getApplicationEnabledSetting(packageName);
+ if (enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ || enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ // Check if the app is already enabled for the target user
+ ApplicationInfo targetUserAppInfo = getAppInfoForUser(packageName,
+ 0, mUser);
+ if (targetUserAppInfo == null
+ || (targetUserAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ continue;
+ }
+ }
+ SelectableAppInfo info = new SelectableAppInfo();
+ info.packageName = app.activityInfo.packageName;
+ info.appName = app.activityInfo.applicationInfo.loadLabel(pm);
+ info.icon = app.activityInfo.loadIcon(pm);
+ info.activityName = app.activityInfo.loadLabel(pm);
+ if (info.activityName == null) info.activityName = info.appName;
+
+ visibleApps.add(info);
+ }
+ }
+ }
+ }
+
+ private boolean isSystemPackage(String packageName) {
+ try {
+ final PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
+ if (pi.applicationInfo == null) return false;
+ final int flags = pi.applicationInfo.flags;
+ if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ || (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException nnfe) {
+ // Missing package?
+ }
+ return false;
+ }
+
+ private ApplicationInfo getAppInfoForUser(String packageName, int flags, UserHandle user) {
+ try {
+ return mIPm.getApplicationInfo(packageName, flags, user.getIdentifier());
+ } catch (RemoteException re) {
+ return null;
+ }
+ }
+
+ public interface OnDisableUiForPackageListener {
+ void onDisableUiForPackage(String packageName);
+ }
+
+ public static class SelectableAppInfo {
+ public String packageName;
+ public CharSequence appName;
+ public CharSequence activityName;
+ public Drawable icon;
+ public SelectableAppInfo masterEntry;
+
+ @Override
+ public String toString() {
+ return packageName + ": appName=" + appName + "; activityName=" + activityName
+ + "; icon=" + icon + "; masterEntry=" + masterEntry;
+ }
+ }
+
+ private static class AppLabelComparator implements Comparator<SelectableAppInfo> {
+
+ @Override
+ public int compare(SelectableAppInfo lhs, SelectableAppInfo rhs) {
+ String lhsLabel = lhs.activityName.toString();
+ String rhsLabel = rhs.activityName.toString();
+ return lhsLabel.toLowerCase().compareTo(rhsLabel.toLowerCase());
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4f75810678a5..b27b92d50d0f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18330,9 +18330,12 @@ public final class ActivityManagerService extends ActivityManagerNative
* dialog / global actions also might want different behaviors.
*/
private static final boolean shouldShowDialogs(Configuration config) {
- return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
- && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
- && config.navigation == Configuration.NAVIGATION_NONAV);
+ final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
+ && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
+ && config.navigation == Configuration.NAVIGATION_NONAV);
+ final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
+ == Configuration.UI_MODE_TYPE_CAR);
+ return inputMethodExists && uiIsNotCarType;
}
@Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index dd58b3c4443e..380763abf6e3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -388,6 +388,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features";
private static final String TAG_DISABLE_CAMERA = "disable-camera";
private static final String TAG_DISABLE_CALLER_ID = "disable-caller-id";
+ private static final String TAG_DISABLE_CONTACTS_SEARCH = "disable-contacts-search";
private static final String TAG_DISABLE_BLUETOOTH_CONTACT_SHARING
= "disable-bt-contacts-sharing";
private static final String TAG_DISABLE_SCREEN_CAPTURE = "disable-screen-capture";
@@ -476,6 +477,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
boolean encryptionRequested = false;
boolean disableCamera = false;
boolean disableCallerId = false;
+ boolean disableContactsSearch = false;
boolean disableBluetoothContactSharing = true;
boolean disableScreenCapture = false; // Can only be set by a device/profile owner.
boolean requireAutoTime = false; // Can only be set by a device owner.
@@ -638,6 +640,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
out.attribute(null, ATTR_VALUE, Boolean.toString(disableCallerId));
out.endTag(null, TAG_DISABLE_CALLER_ID);
}
+ if (disableContactsSearch) {
+ out.startTag(null, TAG_DISABLE_CONTACTS_SEARCH);
+ out.attribute(null, ATTR_VALUE, Boolean.toString(disableContactsSearch));
+ out.endTag(null, TAG_DISABLE_CONTACTS_SEARCH);
+ }
if (disableBluetoothContactSharing) {
out.startTag(null, TAG_DISABLE_BLUETOOTH_CONTACT_SHARING);
out.attribute(null, ATTR_VALUE,
@@ -809,6 +816,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if (TAG_DISABLE_CALLER_ID.equals(tag)) {
disableCallerId = Boolean.parseBoolean(
parser.getAttributeValue(null, ATTR_VALUE));
+ } else if (TAG_DISABLE_CONTACTS_SEARCH.equals(tag)) {
+ disableContactsSearch = Boolean.parseBoolean(
+ parser.getAttributeValue(null, ATTR_VALUE));
} else if (TAG_DISABLE_BLUETOOTH_CONTACT_SHARING.equals(tag)) {
disableBluetoothContactSharing = Boolean.parseBoolean(parser
.getAttributeValue(null, ATTR_VALUE));
@@ -1034,6 +1044,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
pw.println(disableCamera);
pw.print(prefix); pw.print("disableCallerId=");
pw.println(disableCallerId);
+ pw.print(prefix); pw.print("disableContactsSearch=");
+ pw.println(disableContactsSearch);
pw.print(prefix); pw.print("disableBluetoothContactSharing=");
pw.println(disableBluetoothContactSharing);
pw.print(prefix); pw.print("disableScreenCapture=");
@@ -1808,7 +1820,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return null;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
Intent resolveIntent = new Intent();
resolveIntent.setComponent(adminName);
List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceiversAsUser(
@@ -2411,7 +2423,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Bundle onEnableData) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
DevicePolicyData policy = getUserData(userHandle);
DeviceAdminInfo info = findAdmin(adminReceiver, userHandle,
@@ -2457,7 +2469,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
}
@@ -2468,7 +2480,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
DevicePolicyData policyData = getUserData(userHandle);
return policyData.mRemovingAdmins.contains(adminReceiver);
@@ -2480,7 +2492,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (administrator == null) {
@@ -2497,7 +2509,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return Collections.EMPTY_LIST;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
final int N = policy.mAdminList.size();
@@ -2517,7 +2529,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
final int N = policy.mAdminList.size();
@@ -2535,7 +2547,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
if (admin == null) {
@@ -2594,7 +2606,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
@@ -2664,7 +2676,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -2711,7 +2723,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -2771,7 +2783,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0L;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
long timeout = 0L;
@@ -2898,7 +2910,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0L;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
return getPasswordExpirationLocked(who, userHandle);
}
@@ -2926,7 +2938,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -2970,7 +2982,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -3017,7 +3029,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -3067,7 +3079,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -3117,7 +3129,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -3167,7 +3179,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int length = 0;
@@ -3200,7 +3212,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return true;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
int id = getCredentialOwner(userHandle);
@@ -3272,7 +3284,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
ActiveAdmin admin = (who != null) ? getActiveAdminUncheckedLocked(who, userHandle)
: getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
@@ -3285,7 +3297,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return UserHandle.USER_NULL;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked(userHandle);
return admin != null ? admin.getUserHandle().getIdentifier() : UserHandle.USER_NULL;
@@ -3584,7 +3596,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
long time = 0;
@@ -3906,7 +3918,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return;
}
final int userHandle = mInjector.userHandleGetCallingUserId();
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
@@ -3985,7 +3997,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
@@ -4014,7 +4026,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
// Managed Profile password can only be changed when per user encryption is present.
if (!LockPatternUtils.isSeparateWorkChallengeEnabled()) {
enforceNotManagedProfile(userHandle, "set the active password");
@@ -4083,7 +4095,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void reportFailedPasswordAttempt(int userHandle) {
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
enforceNotManagedProfile(userHandle, "report failed password attempt");
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
@@ -4125,7 +4137,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void reportSuccessfulPasswordAttempt(int userHandle) {
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
@@ -4209,7 +4221,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return null;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized(this) {
DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM);
// Scan through active admins and find if anyone has already
@@ -4346,7 +4358,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return false;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
// Check for permissions if a particular caller is specified
if (who != null) {
@@ -4376,7 +4388,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
// Ok to return current status.
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
return getEncryptionStatus();
}
@@ -4624,7 +4636,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
if (!mHasFeature) {
return 0;
}
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
long ident = mInjector.binderClearCallingIdentity();
try {
synchronized (this) {
@@ -5185,17 +5197,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
- private void enforceCrossUserPermission(int userHandle) {
+ private void enforceFullCrossUsersPermission(int userHandle) {
+ enforceSystemUserOrPermission(userHandle,
+ android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
+ }
+
+ private void enforceCrossUsersPermission(int userHandle) {
+ enforceSystemUserOrPermission(userHandle,
+ android.Manifest.permission.INTERACT_ACROSS_USERS);
+ }
+
+ private void enforceSystemUserOrPermission(int userHandle, String permission) {
if (userHandle < 0) {
throw new IllegalArgumentException("Invalid userId " + userHandle);
}
final int callingUid = mInjector.binderGetCallingUid();
- if (userHandle == UserHandle.getUserId(callingUid)) return;
+ if (userHandle == UserHandle.getUserId(callingUid)) {
+ return;
+ }
if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
|| callingUid == Process.ROOT_UID)) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
- + " INTERACT_ACROSS_USERS_FULL permission");
+ mContext.enforceCallingOrSelfPermission(permission,
+ "Must be system or have " + permission + " permission");
}
}
@@ -5405,7 +5428,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return null;
}
Preconditions.checkNotNull(agent, "agent null");
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
final String componentName = agent.flattenToString();
@@ -6068,7 +6091,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public Bundle getUserRestrictions(ComponentName who, int userHandle) {
Preconditions.checkNotNull(who, "ComponentName is null");
- enforceCrossUserPermission(userHandle);
+ enforceFullCrossUsersPermission(userHandle);
synchronized (this) {
ActiveAdmin activeAdmin = getActiveAdminUncheckedLocked(who, userHandle);
if (activeAdmin == null) {
@@ -6260,7 +6283,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public String[] getAccountTypesWithManagementDisabledAsUser(int userId) {
- enforceCrossUserPermission(userId);
+ enforceFullCrossUsersPermission(userId);
if (!mHasFeature) {
return null;
}
@@ -6332,7 +6355,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
if (admin.disableCallerId != disabled) {
admin.disableCallerId = disabled;
- saveSettingsLocked(UserHandle.getCallingUserId());
+ saveSettingsLocked(mInjector.userHandleGetCallingUserId());
}
}
}
@@ -6352,8 +6375,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public boolean getCrossProfileCallerIdDisabledForUser(int userId) {
- // TODO: Should there be a check to make sure this relationship is within a profile group?
- //enforceSystemProcess("getCrossProfileCallerIdDisabled can only be called by system");
+ enforceCrossUsersPermission(userId);
synchronized (this) {
ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
return (admin != null) ? admin.disableCallerId : false;
@@ -6361,6 +6383,44 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
+ public void setCrossProfileContactsSearchDisabled(ComponentName who, boolean disabled) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ if (admin.disableContactsSearch != disabled) {
+ admin.disableContactsSearch = disabled;
+ saveSettingsLocked(mInjector.userHandleGetCallingUserId());
+ }
+ }
+ }
+
+ @Override
+ public boolean getCrossProfileContactsSearchDisabled(ComponentName who) {
+ if (!mHasFeature) {
+ return false;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ synchronized (this) {
+ ActiveAdmin admin = getActiveAdminForCallerLocked(who,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ return admin.disableContactsSearch;
+ }
+ }
+
+ @Override
+ public boolean getCrossProfileContactsSearchDisabledForUser(int userId) {
+ enforceCrossUsersPermission(userId);
+ synchronized (this) {
+ ActiveAdmin admin = getProfileOwnerAdminLocked(userId);
+ return (admin != null) ? admin.disableContactsSearch : false;
+ }
+ }
+
+ @Override
public void startManagedQuickContact(String actualLookupKey, long actualContactId,
long actualDirectoryId, Intent originalIntent) {
final Intent intent = QuickContact.rebuildManagedQuickContactsIntent(
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index 2e0866cc130a..5abb6e7d9367 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -555,8 +555,14 @@ public final class PrintManagerService extends SystemService {
// to handle it as the change may affect ongoing print jobs.
UserState userState = getOrCreateUserStateLocked(getChangingUserId());
boolean stoppedSomePackages = false;
- Iterator<PrintServiceInfo> iterator = userState.getEnabledPrintServices()
- .iterator();
+
+ List<PrintServiceInfo> enabledServices = userState
+ .getEnabledPrintServices();
+ if (enabledServices == null) {
+ return false;
+ }
+
+ Iterator<PrintServiceInfo> iterator = enabledServices.iterator();
while (iterator.hasNext()) {
ComponentName componentName = iterator.next().getComponentName();
String componentPackage = componentName.getPackageName();
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index 41982170c84c..78edc4df08fa 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.GET_META_DATA;
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
+import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -336,7 +337,7 @@ final class UserState implements PrintSpoolerCallbacks, PrintServiceCallbacks {
mSpooler.setPrintJobState(printJobId, PrintJobInfo.STATE_QUEUED, null);
}
- public List<PrintServiceInfo> getEnabledPrintServices() {
+ public @Nullable List<PrintServiceInfo> getEnabledPrintServices() {
synchronized (mLock) {
List<PrintServiceInfo> enabledServices = null;
final int installedServiceCount = mInstalledServices.size();