Merge "Introducing M Land." into mnc-dev
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b39376c..9f385fe 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -19,6 +19,7 @@
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import android.app.ActivityManager;
@@ -840,7 +841,7 @@
return Integer.toString(result);
}
- // pm set-app-link [--user USER_ID] PACKAGE {always|ask|never|undefined}
+ // pm set-app-link [--user USER_ID] PACKAGE {always|ask|always-ask|never|undefined}
private int runSetAppLink() {
int userId = UserHandle.USER_OWNER;
@@ -889,6 +890,10 @@
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
break;
+ case "always-ask":
+ newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
+ break;
+
case "never":
newMode = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
break;
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 474154b..2caec369 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -43,6 +43,8 @@
void clearWindowAnimationFrameStats();
WindowAnimationFrameStats getWindowAnimationFrameStats();
void executeShellCommand(String command, in ParcelFileDescriptor fd);
+ void grantRuntimePermission(String packageName, String permission, int userId);
+ void revokeRuntimePermission(String packageName, String permission, int userId);
// Called from the system process.
oneway void shutdown();
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index a8494fb..efed2e0 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -30,6 +30,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.Log;
import android.view.Display;
import android.view.InputEvent;
@@ -846,6 +847,62 @@
}
/**
+ * Grants a runtime permission to a package for a user.
+ * @param packageName The package to which to grant.
+ * @param permission The permission to grant.
+ * @return Whether granting succeeded.
+ *
+ * @hide
+ */
+ public boolean grantRuntimePermission(String packageName, String permission,
+ UserHandle userHandle) {
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ }
+ try {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Granting runtime permission");
+ }
+ // Calling out without a lock held.
+ mUiAutomationConnection.grantRuntimePermission(packageName,
+ permission, userHandle.getIdentifier());
+ // TODO: The package manager API should return boolean.
+ return true;
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error granting runtime permission", re);
+ }
+ return false;
+ }
+
+ /**
+ * Revokes a runtime permission from a package for a user.
+ * @param packageName The package from which to revoke.
+ * @param permission The permission to revoke.
+ * @return Whether revoking succeeded.
+ *
+ * @hide
+ */
+ public boolean revokeRuntimePermission(String packageName, String permission,
+ UserHandle userHandle) {
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ }
+ try {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Revoking runtime permission");
+ }
+ // Calling out without a lock held.
+ mUiAutomationConnection.revokeRuntimePermission(packageName,
+ permission, userHandle.getIdentifier());
+ // TODO: The package manager API should return boolean.
+ return true;
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error revoking runtime permission", re);
+ }
+ return false;
+ }
+
+ /**
* Executes a shell command. This method returs a file descriptor that points
* to the standard output stream. The command execution is similar to running
* "adb shell <command>" from a host connected to the device.
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 39cd3bc..13e27e2 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -19,6 +19,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.content.Context;
+import android.content.pm.IPackageManager;
import android.graphics.Bitmap;
import android.hardware.input.InputManager;
import android.os.Binder;
@@ -60,6 +61,9 @@
private final IAccessibilityManager mAccessibilityManager = IAccessibilityManager.Stub
.asInterface(ServiceManager.getService(Service.ACCESSIBILITY_SERVICE));
+ private final IPackageManager mPackageManager = IPackageManager.Stub
+ .asInterface(ServiceManager.getService("package"));
+
private final Object mLock = new Object();
private final Binder mToken = new Binder();
@@ -227,6 +231,38 @@
}
@Override
+ public void grantRuntimePermission(String packageName, String permission, int userId)
+ throws RemoteException {
+ synchronized (mLock) {
+ throwIfCalledByNotTrustedUidLocked();
+ throwIfShutdownLocked();
+ throwIfNotConnectedLocked();
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mPackageManager.grantRuntimePermission(packageName, permission, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void revokeRuntimePermission(String packageName, String permission, int userId)
+ throws RemoteException {
+ synchronized (mLock) {
+ throwIfCalledByNotTrustedUidLocked();
+ throwIfShutdownLocked();
+ throwIfNotConnectedLocked();
+ }
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ mPackageManager.revokeRuntimePermission(packageName, permission, userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void executeShellCommand(final String command, final ParcelFileDescriptor sink)
throws RemoteException {
synchronized (mLock) {
diff --git a/core/java/android/content/pm/IntentFilterVerificationInfo.java b/core/java/android/content/pm/IntentFilterVerificationInfo.java
index 4dbac05..953b051 100644
--- a/core/java/android/content/pm/IntentFilterVerificationInfo.java
+++ b/core/java/android/content/pm/IntentFilterVerificationInfo.java
@@ -19,6 +19,7 @@
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import android.os.Parcel;
@@ -199,6 +200,10 @@
sb.append("never");
break;
+ case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK:
+ sb.append("always-ask");
+ break;
+
case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
default:
sb.append("undefined");
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0f936fd..c8e9402 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1073,6 +1073,18 @@
public static final int INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER = 3;
/**
+ * Used as the {@code status} argument for {@link PackageManager#updateIntentVerificationStatus}
+ * to indicate that this app should always be considered as an ambiguous candidate for
+ * handling the matching Intent even if there are other candidate apps in the "always"
+ * state. Put another way: if there are any 'always ask' apps in a set of more than
+ * one candidate app, then a disambiguation is *always* presented even if there is
+ * another candidate app with the 'always' state.
+ *
+ * @hide
+ */
+ public static final int INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK = 4;
+
+ /**
* Can be used as the {@code millisecondsToDelay} argument for
* {@link PackageManager#extendVerificationTimeout}. This is the
* maximum time {@code PackageManager} waits for the verification
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 20bcf62..bfca719 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -179,16 +179,16 @@
}
/**
- * Returns the app id for a given shared app gid.
+ * Returns the app id for a given shared app gid. Returns -1 if the ID is invalid.
* @hide
*/
public static final int getAppIdFromSharedAppGid(int gid) {
- final int noUserGid = getAppId(gid);
- if (noUserGid < Process.FIRST_SHARED_APPLICATION_GID ||
- noUserGid > Process.LAST_SHARED_APPLICATION_GID) {
- throw new IllegalArgumentException(Integer.toString(gid) + " is not a shared app gid");
+ final int appId = getAppId(gid) + Process.FIRST_APPLICATION_UID
+ - Process.FIRST_SHARED_APPLICATION_GID;
+ if (appId < 0 || appId >= Process.FIRST_SHARED_APPLICATION_GID) {
+ return -1;
}
- return (noUserGid + Process.FIRST_APPLICATION_UID) - Process.FIRST_SHARED_APPLICATION_GID;
+ return appId;
}
/**
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 49230c1..2595fe0 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -16,16 +16,23 @@
package com.android.internal.app;
+import android.animation.Animator;
import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
@@ -73,19 +80,54 @@
im.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- final int pad = (int) (8*dp);
- outline.setOval(pad, pad, view.getWidth()-pad, view.getHeight()-pad);
+ final int pad = (int) (8 * dp);
+ outline.setOval(pad, pad, view.getWidth() - pad, view.getHeight() - pad);
}
});
- final Drawable platlogo = getDrawable(com.android.internal.R.drawable.platlogo);
+ final float hue = (float) Math.random();
+ final Paint bgPaint = new Paint();
+ bgPaint.setColor(Color.HSBtoColor(hue, 0.4f, 1f));
+ final Paint fgPaint = new Paint();
+ fgPaint.setColor(Color.HSBtoColor(hue, 0.5f, 1f));
+ final Drawable M = getDrawable(com.android.internal.R.drawable.platlogo_m);
+ final Drawable platlogo = new Drawable() {
+ @Override
+ public void setAlpha(int alpha) { }
+
+ @Override
+ public void setColorFilter(@Nullable ColorFilter colorFilter) { }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public void draw(Canvas c) {
+ final float r = c.getWidth() / 2f;
+ c.drawCircle(r, r, r, bgPaint);
+ c.drawArc(0, 0, 2 * r, 2 * r, 135, 180, false, fgPaint);
+ M.setBounds(0, 0, c.getWidth(), c.getHeight());
+ M.draw(c);
+ }
+ };
im.setBackground(new RippleDrawable(
ColorStateList.valueOf(0xFFFFFFFF),
platlogo,
null));
+ im.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setOval(0, 0, view.getWidth(), view.getHeight());
+ }
+ });
im.setClickable(true);
im.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
+ if (mTapCount == 0) {
+ showMarshmallow(im);
+ }
im.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
@@ -132,6 +174,9 @@
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode != KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+ if (mKeyCount == 0) {
+ showMarshmallow(im);
+ }
++mKeyCount;
if (mKeyCount > 2) {
if (mTapCount > 5) {
@@ -155,4 +200,17 @@
.setStartDelay(800)
.start();
}
+
+ public void showMarshmallow(View im) {
+ final Drawable fg = getDrawable(com.android.internal.R.drawable.platlogo);
+ fg.setBounds(0, 0, im.getWidth(), im.getHeight());
+ fg.setAlpha(0);
+ im.getOverlay().add(fg);
+
+ final Animator fadeIn = ObjectAnimator.ofInt(fg, "alpha", 255);
+ fadeIn.setInterpolator(mInterpolator);
+ fadeIn.setDuration(300);
+ fadeIn.start();
+ }
+
}
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 9d0636a..f190d8c 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -294,6 +294,29 @@
}
/**
+ * Removes value from given array if present, providing set-like behavior.
+ */
+ public static @Nullable String[] removeString(@Nullable String[] cur, String val) {
+ if (cur == null) {
+ return null;
+ }
+ final int N = cur.length;
+ for (int i = 0; i < N; i++) {
+ if (Objects.equals(cur[i], val)) {
+ String[] ret = new String[N - 1];
+ if (i > 0) {
+ System.arraycopy(cur, 0, ret, 0, i);
+ }
+ if (i < (N - 1)) {
+ System.arraycopy(cur, i + 1, ret, i, N - i - 1);
+ }
+ return ret;
+ }
+ }
+ return cur;
+ }
+
+ /**
* Adds value to given array if not already present, providing set-like
* behavior.
*/
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index f5d945a..bb423fef5 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,5 +1,5 @@
<!--
-Copyright (C) 2014 The Android Open Source Project
+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.
@@ -14,30 +14,20 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="480dp"
- android:height="480dp"
+ android:width="48dp"
+ android:height="48dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
- android:pathData="M24.0,2.0C11.8,2.0 2.0,11.8 2.0,24.0c0.0,6.1 2.5,11.6 6.4,15.6L39.6,8.4C35.6,4.5 30.1,2.0 24.0,2.0z"
- android:fillColor="#F57C00"/>
- <path
- android:pathData="M39.6,8.4L8.4,39.6c4.0,4.0 9.5,6.4 15.6,6.4c12.2,0.0 22.0,-9.8 22.0,-22.0C46.0,17.9 43.5,12.4 39.6,8.4z"
- android:fillColor="#FF9800"/>
- <path
- android:pathData="M45.9,25.9L34.0,14.0L14.0,34.0l11.9,11.9C36.5,45.0 45.0,36.5 45.9,25.9z"
- android:fillAlpha="0.33"
- android:fillColor="#F57C00"/>
- <path
- android:pathData="M24.0,24.0c0.0,0.0 0.0,2.2 0.0,5.0s0.0,5.0 0.0,5.0l10.0,-10.0L34.0,14.0L24.0,24.0z"
+ android:pathData="M34.9,13.2c-0.8,-0.8,-4.2,-2.4,-10.9,-2.4s-10.1,1.6,-10.9,2.4c-0.8,0.8,-2.4,4.2,-2.4,10.9s1.6,10.1,2.4,10.9 c0.8,0.8,4.2,2.4,10.9,2.4s10.1,-1.6,10.9,-2.4c0.8,-0.8,2.4,-4.2,2.4,-10.9S35.6,14,34.9,13.2z"
android:fillColor="#FFFFFF"/>
<path
- android:pathData="M24.0,24.0L14.0,14.0l0.0,10.0l10.0,10.0c0.0,0.0 0.0,-2.2 0.0,-5.0S24.0,24.0 24.0,24.0z"
- android:fillColor="#EEEEEE"/>
+ android:pathData="M34.7,13.7c0,0.8,-1.2,1.5,-3.1,2.1c-1.9,0.5,-4.6,0.8,-7.6,0.8s-5.6,-0.3,-7.6,-0.8 c-1.9,-0.5,-3.1,-1.2,-3.1,-2.1s1.2,-1.5,3.1,-2.1c1.9,-0.5,4.6,-0.8,7.6,-0.8s5.6,0.3,7.6,0.8C33.5,12.1,34.7,12.9,34.7,13.7z"
+ android:fillColor="#EBEBEB"/>
<path
- android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z"
- android:fillColor="#DDDDDD"/>
+ android:pathData="M30,13c-0.1,0,-0.1,0,-0.2,0c-0.4,-0.1,-0.7,-0.6,-0.6,-1l1.3,-5.5c0.1,-0.4,0.6,-0.7,1,-0.6c0.4,0.1,0.7,0.6,0.6,1 l-1.3,5.5C30.7,12.7,30.4,13,30,13z"
+ android:fillColor="#FFFFFF"/>
<path
- android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z"
- android:fillColor="#DDDDDD"/>
+ android:pathData="M18,13c-0.4,0,-0.7,-0.3,-0.8,-0.6l-1.3,-5.5c-0.1,-0.4,0.2,-0.9,0.6,-1c0.4,-0.1,0.9,0.2,1,0.6l1.3,5.5 c0.1,0.4,-0.2,0.9,-0.6,1C18.1,13,18.1,13,18,13z"
+ android:fillColor="#FFFFFF"/>
</vector>
diff --git a/core/res/res/drawable-nodpi/platlogo_m.xml b/core/res/res/drawable-nodpi/platlogo_m.xml
new file mode 100644
index 0000000..f19e045
--- /dev/null
+++ b/core/res/res/drawable-nodpi/platlogo_m.xml
@@ -0,0 +1,37 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#08000000"
+ android:pathData="M13.5,34.5l13.3,13.3c11,-1.3,19.7,-10,21,-21L34.5,13.5L13.5,34.5z"
+ />
+ <path
+ android:pathData="M24,24c0,0,0,2.4,0,5.2s0,5.2,0,5.2L34.5,24V13.5L24,24z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M24,24L13.5,13.5V24L24,34.5c0,0,0,-2.4,0,-5.2S24,24,24,24z"
+ android:fillColor="#EEEEEE"/>
+ <path
+ android:pathData="M13.5,34.5l10.5,0.0l-10.5,-10.5z"
+ android:fillColor="#DDDDDD"/>
+ <path
+ android:pathData="M34.5,34.5l0.0,-10.5l-10.5,10.5z"
+ android:fillColor="#DDDDDD"/>
+</vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index 8f5109df..8cc9961 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -19,6 +19,18 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
- android:pathData="M12.0,12.0l-10.0,-10.0 0.0,10.0 0.0,10.0 10.0,0.0 10.0,0.0 0.0,-10.0 0.0,-10.0z"/>
+ android:pathData="M8.4,5.3c-0.2,0.0 -0.4,-0.2 -0.5,-0.4L7.1,1.6C7.0,1.4 7.2,1.1 7.4,1.0C7.7,0.9 8.0,1.1 8.0,1.4l0.8,3.3c0.1,0.3 -0.1,0.5 -0.4,0.6C8.5,5.3 8.4,5.3 8.4,5.3z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M15.6,5.3c0.0,0.0 -0.1,0.0 -0.1,0.0c-0.3,-0.1 -0.4,-0.3 -0.4,-0.6L16.0,1.4C16.0,1.1 16.3,0.9 16.6,1.0c0.3,0.1 0.4,0.3 0.4,0.6l-0.8,3.3C16.1,5.1 15.9,5.3 15.6,5.3z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M18.6,5.4c-0.1,-0.1 -0.2,-0.1 -0.3,-0.2c0.2,0.2 0.3,0.3 0.3,0.5c0.0,0.9 -2.9,1.7 -6.6,1.7S5.4,6.7 5.4,5.7c0.0,-0.2 0.1,-0.3 0.3,-0.5C5.6,5.3 5.5,5.4 5.4,5.4C5.0,5.9 4.0,8.0 4.0,12.0s1.0,6.1 1.4,6.6C5.9,19.0 8.0,20.0 12.0,20.0s6.1,-1.0 6.6,-1.4C19.0,18.1 20.0,16.0 20.0,12.0S19.0,5.9 18.6,5.4zM8.0,13.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0c0.0,-0.6 0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0C9.0,12.6 8.6,13.0 8.0,13.0zM16.0,13.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0c0.0,-0.6 0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0C17.0,12.6 16.6,13.0 16.0,13.0z"
+ android:fillColor="#FFFFFF"/>
+ <path
+ android:pathData="M5.35,5.7
+ a 6.6 1.75 0 1 1 13.25 0
+ a 6.6 1.75 0 1 1 -13.25 0
+ z"
+ android:fillColor="#BBFFFFFF" />
</vector>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ee61944..262aa76 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2318,4 +2318,6 @@
<java-symbol type="array" name="config_cell_retries_per_error_code" />
<java-symbol type="drawable" name="ic_more_items" />
+ <java-symbol type="drawable" name="platlogo_m" />
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
index fe876d7..7f68e29 100644
--- a/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
+++ b/packages/SystemUI/src/com/android/systemui/media/RingtonePlayer.java
@@ -159,7 +159,9 @@
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
throw new SecurityException("Async playback only available from system UID.");
}
-
+ if (UserHandle.ALL.equals(user)) {
+ user = UserHandle.OWNER;
+ }
mAsyncPlayer.play(getContextForUser(user), uri, looping, aa);
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index c13401f..b766894 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -157,7 +157,7 @@
mFactoryTest = factoryTest;
// Let the package manager query for the sync adapters for a given authority
- // as we grant default permissions to sync adapters for specifix authorities.
+ // as we grant default permissions to sync adapters for specific authorities.
PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
packageManagerInternal.setSyncAdapterPackagesprovider(
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 9426b76..4351798 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3615,22 +3615,28 @@
public ArraySet<String> getGrantedPackages() {
final ArraySet<String> pkgs = new ArraySet<>();
- final String setting = Settings.Secure.getStringForUser(
- getContext().getContentResolver(),
- Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
- ActivityManager.getCurrentUser());
- if (setting != null) {
- final String[] tokens = setting.split(SEPARATOR);
- for (int i = 0; i < tokens.length; i++) {
- String token = tokens[i];
- if (token != null) {
- token.trim();
+
+ long identity = Binder.clearCallingIdentity();
+ try {
+ final String setting = Settings.Secure.getStringForUser(
+ getContext().getContentResolver(),
+ Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
+ ActivityManager.getCurrentUser());
+ if (setting != null) {
+ final String[] tokens = setting.split(SEPARATOR);
+ for (int i = 0; i < tokens.length; i++) {
+ String token = tokens[i];
+ if (token != null) {
+ token.trim();
+ }
+ if (TextUtils.isEmpty(token)) {
+ continue;
+ }
+ pkgs.add(token);
}
- if (TextUtils.isEmpty(token)) {
- continue;
- }
- pkgs.add(token);
}
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
return pkgs;
}
diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java
index 18407c9..52d0928 100644
--- a/services/core/java/com/android/server/pm/BasePermission.java
+++ b/services/core/java/com/android/server/pm/BasePermission.java
@@ -88,4 +88,10 @@
return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS;
}
+
+ public boolean isDevelopment() {
+ return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+ == PermissionInfo.PROTECTION_SIGNATURE
+ && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
+ }
}
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index 71a2d59..d2a70df 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -296,7 +296,7 @@
PackageParser.Package storagePackage = getDefaultProviderAuthorityPackageLPr(
"com.android.externalstorage.documents", userId);
if (storagePackage != null) {
- grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(storagePackage, STORAGE_PERMISSIONS, true, userId);
}
// CertInstaller
@@ -360,7 +360,7 @@
PackageParser.Package cbrPackage =
getDefaultSystemHandlerActivityPackageLPr(cbrIntent, userId);
if (cbrPackage != null && doesPackageSupportRuntimePermissions(cbrPackage)) {
- grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, false, userId);
+ grantRuntimePermissionsLPw(cbrPackage, SMS_PERMISSIONS, userId);
}
// Calendar
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 21e256e8..f67f3f3 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -56,6 +56,7 @@
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
+import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
@@ -3432,14 +3433,14 @@
}
}
- private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg,
+ private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg,
BasePermission bp) {
int index = pkg.requestedPermissions.indexOf(bp.name);
if (index == -1) {
throw new SecurityException("Package " + pkg.packageName
+ " has not requested permission " + bp.name);
}
- if (!bp.isRuntime()) {
+ if (!bp.isRuntime() && !bp.isDevelopment()) {
throw new SecurityException("Permission " + bp.name
+ " is not a changeable permission type");
}
@@ -3473,7 +3474,7 @@
throw new IllegalArgumentException("Unknown permission: " + name);
}
- enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
+ enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
sb = (SettingBase) pkg.mExtras;
@@ -3489,6 +3490,16 @@
+ name + " for package: " + packageName);
}
+ if (bp.isDevelopment()) {
+ // Development permissions must be handled specially, since they are not
+ // normal runtime permissions. For now they apply to all users.
+ if (permissionsState.grantInstallPermission(bp) !=
+ PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ scheduleWriteSettingsLocked();
+ }
+ return;
+ }
+
final int result = permissionsState.grantRuntimePermission(bp, userId);
switch (result) {
case PermissionsState.PERMISSION_OPERATION_FAILURE: {
@@ -3557,7 +3568,7 @@
throw new IllegalArgumentException("Unknown permission: " + name);
}
- enforceDeclaredAsUsedAndRuntimePermission(pkg, bp);
+ enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) {
@@ -3572,6 +3583,16 @@
+ name + " for package: " + packageName);
}
+ if (bp.isDevelopment()) {
+ // Development permissions must be handled specially, since they are not
+ // normal runtime permissions. For now they apply to all users.
+ if (permissionsState.revokeInstallPermission(bp) !=
+ PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ scheduleWriteSettingsLocked();
+ }
+ return;
+ }
+
if (permissionsState.revokeRuntimePermission(bp, userId) ==
PermissionsState.PERMISSION_OPERATION_FAILURE) {
return;
@@ -3799,21 +3820,6 @@
return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
}
- void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) {
- BasePermission bp = mSettings.mPermissions.get(permission);
- if (bp == null) {
- throw new SecurityException("Missing " + permission + " permission");
- }
-
- SettingBase sb = (SettingBase) pkg.mExtras;
- PermissionsState permissionsState = sb.getPermissionsState();
-
- if (permissionsState.grantInstallPermission(bp) !=
- PermissionsState.PERMISSION_OPERATION_FAILURE) {
- scheduleWriteSettingsLocked();
- }
- }
-
@Override
public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
mContext.enforceCallingOrSelfPermission(
@@ -4701,6 +4707,7 @@
ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
+ ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
@@ -4737,6 +4744,11 @@
Slog.i(TAG, " + never: " + info.activityInfo.packageName);
}
neverList.add(info);
+ } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, " + always-ask: " + info.activityInfo.packageName);
+ }
+ alwaysAskList.add(info);
} else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
if (DEBUG_DOMAIN_VERIFICATION) {
@@ -4746,6 +4758,10 @@
}
}
}
+
+ // We'll want to include browser possibilities in a few cases
+ boolean includeBrowser = false;
+
// First try to add the "always" resolution(s) for the current user, if any
if (alwaysList.size() > 0) {
result.addAll(alwaysList);
@@ -4754,7 +4770,7 @@
== INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
result.add(xpDomainInfo.resolveInfo);
} else {
- // Add all undefined Apps as we want them to appear in the Disambiguation dialog.
+ // Add all undefined apps as we want them to appear in the disambiguation dialog.
result.addAll(undefinedList);
if (xpDomainInfo != null && (
xpDomainInfo.bestDomainVerificationStatus
@@ -4763,7 +4779,25 @@
== INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK)) {
result.add(xpDomainInfo.resolveInfo);
}
- // Also add Browsers (all of them or only the default one)
+ includeBrowser = true;
+ }
+
+ // The presence of any 'always ask' alternatives means we'll also offer browsers.
+ // If there were 'always' entries their preferred order has been set, so we also
+ // back that off to make the alternatives equivalent
+ if (alwaysAskList.size() > 0) {
+ for (ResolveInfo i : result) {
+ i.preferredOrder = 0;
+ }
+ result.addAll(alwaysAskList);
+ includeBrowser = true;
+ }
+
+ if (includeBrowser) {
+ // Also add browsers (all of them or only the default one)
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.v(TAG, " ...including browsers in candidate set");
+ }
if ((matchFlags & MATCH_ALL) != 0) {
result.addAll(matchAllList);
} else {
@@ -14764,6 +14798,7 @@
pw.println(" version: print database version info");
pw.println(" write: write current settings now");
pw.println(" installs: details about install sessions");
+ pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
pw.println(" <package.name>: info about given package");
return;
} else if ("--checkin".equals(opt)) {
@@ -14785,6 +14820,31 @@
// When dumping a single package, we always dump all of its
// filter information since the amount of data will be reasonable.
dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
+ } else if ("check-permission".equals(cmd)) {
+ if (opti >= args.length) {
+ pw.println("Error: check-permission missing permission argument");
+ return;
+ }
+ String perm = args[opti];
+ opti++;
+ if (opti >= args.length) {
+ pw.println("Error: check-permission missing package argument");
+ return;
+ }
+ String pkg = args[opti];
+ opti++;
+ int user = UserHandle.getUserId(Binder.getCallingUid());
+ if (opti < args.length) {
+ try {
+ user = Integer.parseInt(args[opti]);
+ } catch (NumberFormatException e) {
+ pw.println("Error: check-permission user argument is not a number: "
+ + args[opti]);
+ return;
+ }
+ }
+ pw.println(checkPermission(perm, pkg, user));
+ return;
} else if ("l".equals(cmd) || "libraries".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_LIBS);
} else if ("f".equals(cmd) || "features".equals(cmd)) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 00d0fe1..a762014 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3949,7 +3949,7 @@
void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
- Date date, List<UserInfo> users) {
+ Date date, List<UserInfo> users, boolean dumpAll) {
if (checkinTag != null) {
pw.print(checkinTag);
pw.print(",");
@@ -4151,7 +4151,7 @@
pw.print(", COSTS_MONEY");
}
if ((perm.info.flags&PermissionInfo.FLAG_HIDDEN) != 0) {
- pw.print(", COSTS_HIDDEN");
+ pw.print(", HIDDEN");
}
if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
pw.print(", INSTALLED");
@@ -4160,7 +4160,21 @@
}
}
- if (ps.sharedUser == null || permissionNames != null) {
+ if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null
+ && ps.pkg.requestedPermissions.size() > 0) {
+ final ArrayList<String> perms = ps.pkg.requestedPermissions;
+ pw.print(prefix); pw.println(" requested permissions:");
+ for (int i=0; i<perms.size(); i++) {
+ String perm = perms.get(i);
+ if (permissionNames != null
+ && !permissionNames.contains(perm)) {
+ continue;
+ }
+ pw.print(prefix); pw.print(" "); pw.println(perm);
+ }
+ }
+
+ if (ps.sharedUser == null || permissionNames != null || dumpAll) {
PermissionsState permissionsState = ps.getPermissionsState();
dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
}
@@ -4187,7 +4201,7 @@
PermissionsState permissionsState = ps.getPermissionsState();
dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id));
dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState
- .getRuntimePermissionStates(user.id));
+ .getRuntimePermissionStates(user.id), dumpAll);
}
if (permissionNames == null) {
@@ -4235,11 +4249,12 @@
pw.println("Packages:");
printedSomething = true;
}
- dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users);
+ dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
+ packageName != null);
}
printedSomething = false;
- if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) {
+ if (mRenamedPackages.size() > 0 && permissionNames == null) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) {
@@ -4276,7 +4291,7 @@
printedSomething = true;
}
dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date,
- users);
+ users, packageName != null);
}
}
}
@@ -4361,7 +4376,8 @@
if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
dumpGidsLPr(pw, prefix + " ", gids);
- dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions);
+ dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions,
+ packageName != null);
}
}
} else {
@@ -4407,8 +4423,8 @@
}
void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
- List<PermissionState> permissionStates) {
- if (!permissionStates.isEmpty()) {
+ List<PermissionState> permissionStates, boolean dumpAll) {
+ if (!permissionStates.isEmpty() || dumpAll) {
pw.print(prefix); pw.println("runtime permissions:");
for (PermissionState permissionState : permissionStates) {
if (permissionNames != null
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index 3d49308..5852b8e 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -97,7 +97,7 @@
* @hide
* */
public static String getDefaultDialerApplication(Context context) {
- return getDefaultDialerApplication(context, ActivityManager.getCurrentUser());
+ return getDefaultDialerApplication(context, context.getUserId());
}
/**
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index 36d5d98..fe17c6e 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -2,6 +2,7 @@
package="com.android.test.voiceinteraction">
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
+ <uses-permission android:name="android.permission.READ_LOGS" />
<application>
<activity android:name="VoiceInteractionMain" android:label="Voice Interaction"