summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt5
-rw-r--r--api/system-current.txt10
-rw-r--r--core/java/android/app/Activity.java7
-rw-r--r--core/java/android/app/Fragment.java7
-rw-r--r--core/java/android/app/VoiceInteractor.java32
-rw-r--r--core/java/android/content/pm/PackageManager.java32
-rw-r--r--core/java/android/text/Hyphenator.java15
-rw-r--r--core/java/android/view/ViewAnimationUtils.java6
-rw-r--r--docs/html/training/material/animations.jd8
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java19
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java7
-rw-r--r--packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java9
-rw-r--r--services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java13
-rw-r--r--services/core/java/com/android/server/pm/Settings.java17
14 files changed, 133 insertions, 54 deletions
diff --git a/api/current.txt b/api/current.txt
index 3304317..bb1070d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5430,7 +5430,6 @@ package android.app {
public static class VoiceInteractor.AbortVoiceRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.AbortVoiceRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.AbortVoiceRequest(java.lang.CharSequence, android.os.Bundle);
method public void onAbortResult(android.os.Bundle);
}
@@ -5441,24 +5440,20 @@ package android.app {
public static class VoiceInteractor.CompleteVoiceRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.CompleteVoiceRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.CompleteVoiceRequest(java.lang.CharSequence, android.os.Bundle);
method public void onCompleteResult(android.os.Bundle);
}
public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.ConfirmationRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle);
method public void onConfirmationResult(boolean, android.os.Bundle);
}
public static class VoiceInteractor.PickOptionRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.PickOptionRequest(android.app.VoiceInteractor.Prompt, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
- ctor public deprecated VoiceInteractor.PickOptionRequest(java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
method public void onPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
}
public static final class VoiceInteractor.PickOptionRequest.Option implements android.os.Parcelable {
- ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence);
ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence, int);
method public android.app.VoiceInteractor.PickOptionRequest.Option addSynonym(java.lang.CharSequence);
method public int countSynonyms();
diff --git a/api/system-current.txt b/api/system-current.txt
index e3f003c..5861560 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5546,7 +5546,6 @@ package android.app {
public static class VoiceInteractor.AbortVoiceRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.AbortVoiceRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.AbortVoiceRequest(java.lang.CharSequence, android.os.Bundle);
method public void onAbortResult(android.os.Bundle);
}
@@ -5557,24 +5556,20 @@ package android.app {
public static class VoiceInteractor.CompleteVoiceRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.CompleteVoiceRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.CompleteVoiceRequest(java.lang.CharSequence, android.os.Bundle);
method public void onCompleteResult(android.os.Bundle);
}
public static class VoiceInteractor.ConfirmationRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.ConfirmationRequest(android.app.VoiceInteractor.Prompt, android.os.Bundle);
- ctor public deprecated VoiceInteractor.ConfirmationRequest(java.lang.CharSequence, android.os.Bundle);
method public void onConfirmationResult(boolean, android.os.Bundle);
}
public static class VoiceInteractor.PickOptionRequest extends android.app.VoiceInteractor.Request {
ctor public VoiceInteractor.PickOptionRequest(android.app.VoiceInteractor.Prompt, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
- ctor public deprecated VoiceInteractor.PickOptionRequest(java.lang.CharSequence, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
method public void onPickOptionResult(boolean, android.app.VoiceInteractor.PickOptionRequest.Option[], android.os.Bundle);
}
public static final class VoiceInteractor.PickOptionRequest.Option implements android.os.Parcelable {
- ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence);
ctor public VoiceInteractor.PickOptionRequest.Option(java.lang.CharSequence, int);
method public android.app.VoiceInteractor.PickOptionRequest.Option addSynonym(java.lang.CharSequence);
method public int countSynonyms();
@@ -9675,11 +9670,6 @@ package android.content.pm {
field public static final java.lang.String FEATURE_WEBVIEW = "android.software.webview";
field public static final java.lang.String FEATURE_WIFI = "android.hardware.wifi";
field public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct";
- field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
- field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
- field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
- field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2
- field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
field public static final int GET_ACTIVITIES = 1; // 0x1
field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9c2e208..d07238a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3723,6 +3723,12 @@ public class Activity extends ContextThemeWrapper
* #checkSelfPermission(String)}.
* </p>
* <p>
+ * You cannot request a permission if your activity sets {@link
+ * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
+ * <code>true</code> because in this case the activity would not receive
+ * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
+ * </p>
+ * <p>
* A sample permissions request looks like this:
* </p>
* <code><pre><p>
@@ -3749,6 +3755,7 @@ public class Activity extends ContextThemeWrapper
* @param permissions The requested permissions.
* @param requestCode Application specific request code to match with a result
* reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
+ * Should be >= 0.
*
* @see #onRequestPermissionsResult(int, String[], int[])
* @see #checkSelfPermission(String)
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 95b3b8e..5490fe7 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1166,6 +1166,12 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
* android.content.Context#checkSelfPermission(String)}.
* </p>
* <p>
+ * You cannot request a permission if your activity sets {@link
+ * android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
+ * <code>true</code> because in this case the activity would not receive
+ * result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
+ * </p>
+ * <p>
* A sample permissions request looks like this:
* </p>
* <code><pre><p>
@@ -1192,6 +1198,7 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene
* @param permissions The requested permissions.
* @param requestCode Application specific request code to match with a result
* reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
+ * Should be >= 0.
*
* @see #onRequestPermissionsResult(int, String[], int[])
* @see android.content.Context#checkSelfPermission(String)
diff --git a/core/java/android/app/VoiceInteractor.java b/core/java/android/app/VoiceInteractor.java
index abb8244..bf7458c 100644
--- a/core/java/android/app/VoiceInteractor.java
+++ b/core/java/android/app/VoiceInteractor.java
@@ -253,7 +253,8 @@ public final class VoiceInteractor {
/**
* Report from voice interaction service: this operation has been canceled, typically
- * as a completion of a previous call to {@link #cancel}.
+ * as a completion of a previous call to {@link #cancel} or when the user explicitly
+ * cancelled.
*/
public void onCancel() {
}
@@ -288,7 +289,8 @@ public final class VoiceInteractor {
* would require the user to touch the screen when voice interaction mode is not enabled.
* The result of the confirmation will be returned through an asynchronous call to
* either {@link #onConfirmationResult(boolean, android.os.Bundle)} or
- * {@link #onCancel()}.
+ * {@link #onCancel()} - these methods should be overridden to define the application specific
+ * behavior.
*
* <p>In some cases this may be a simple yes / no confirmation or the confirmation could
* include context information about how the action will be completed
@@ -315,13 +317,19 @@ public final class VoiceInteractor {
* @param prompt Optional confirmation to speak to the user or null if nothing
* should be spoken.
* @param extras Additional optional information or null.
- * @deprecated Prefer the version that takes a {@link Prompt}.
+ * @hide
*/
public ConfirmationRequest(CharSequence prompt, Bundle extras) {
mPrompt = (prompt != null ? new Prompt(prompt) : null);
mExtras = extras;
}
+ /**
+ * Handle the confirmation result. Override this method to define
+ * the behavior when the user confirms or rejects the operation.
+ * @param confirmed Whether the user confirmed or rejected the operation.
+ * @param result Additional result information or null.
+ */
public void onConfirmationResult(boolean confirmed, Bundle result) {
}
@@ -336,7 +344,8 @@ public final class VoiceInteractor {
* VoiceInteractionService. Typically, the application would present this visually as
* a list view to allow selecting the option by touch.
* The result of the confirmation will be returned through an asynchronous call to
- * either {@link #onPickOptionResult} or {@link #onCancel()}.
+ * either {@link #onPickOptionResult} or {@link #onCancel()} - these methods should
+ * be overridden to define the application specific behavior.
*/
public static class PickOptionRequest extends Request {
final Prompt mPrompt;
@@ -344,7 +353,9 @@ public final class VoiceInteractor {
final Bundle mExtras;
/**
- * Represents a single option that the user may select using their voice.
+ * Represents a single option that the user may select using their voice. The
+ * {@link #getIndex()} method should be used as a unique ID to identify the option
+ * when it is returned from the voice interactor.
*/
public static final class Option implements Parcelable {
final CharSequence mLabel;
@@ -357,6 +368,7 @@ public final class VoiceInteractor {
* or one of several synonyms.
* @param label The label that will both be matched against what the user speaks
* and displayed visually.
+ * @hide
*/
public Option(CharSequence label) {
mLabel = label;
@@ -481,7 +493,7 @@ public final class VoiceInteractor {
* presented or null if nothing should be asked.
* @param options The set of {@link Option}s the user is selecting from.
* @param extras Additional optional information or null.
- * @deprecated Prefer the version that takes a {@link Prompt}.
+ * @hide
*/
public PickOptionRequest(CharSequence prompt, Option[] options, Bundle extras) {
mPrompt = (prompt != null ? new Prompt(prompt) : null);
@@ -490,7 +502,9 @@ public final class VoiceInteractor {
}
/**
- * Called when a single option is confirmed or narrowed to one of several options.
+ * Called when a single option is confirmed or narrowed to one of several options. Override
+ * this method to define the behavior when the user selects an option or narrows down the
+ * set of options.
* @param finished True if the voice interaction has finished making a selection, in
* which case {@code selections} contains the final result. If false, this request is
* still active and you will continue to get calls on it.
@@ -536,7 +550,7 @@ public final class VoiceInteractor {
* @param message Optional message to speak to the user about the completion status of
* the task or null if nothing should be spoken.
* @param extras Additional optional information or null.
- * @deprecated Prefer the version that takes a {@link Prompt}.
+ * @hide
*/
public CompleteVoiceRequest(CharSequence message, Bundle extras) {
mPrompt = (message != null ? new Prompt(message) : null);
@@ -583,7 +597,7 @@ public final class VoiceInteractor {
* @param message Optional message to speak to the user indicating why the task could
* not be completed by voice or null if nothing should be spoken.
* @param extras Additional optional information or null.
- * @deprecated Prefer the version that takes a {@link Prompt}.
+ * @hide
*/
public AbortVoiceRequest(CharSequence message, Bundle extras) {
mPrompt = (message != null ? new Prompt(message) : null);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index dd1c5c2..538007a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1924,7 +1924,6 @@ public abstract class PackageManager {
*
* @hide
*/
- @SystemApi
public static final int FLAG_PERMISSION_USER_SET = 1 << 0;
/**
@@ -1934,7 +1933,6 @@ public abstract class PackageManager {
*
* @hide
*/
- @SystemApi
public static final int FLAG_PERMISSION_USER_FIXED = 1 << 1;
/**
@@ -1944,7 +1942,6 @@ public abstract class PackageManager {
*
* @hide
*/
- @SystemApi
public static final int FLAG_PERMISSION_POLICY_FIXED = 1 << 2;
/**
@@ -1957,7 +1954,6 @@ public abstract class PackageManager {
*
* @hide
*/
- @SystemApi
public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 1 << 3;
/**
@@ -1966,9 +1962,19 @@ public abstract class PackageManager {
*
* @hide
*/
- @SystemApi
public static final int FLAG_PERMISSION_SYSTEM_FIXED = 1 << 4;
+
+ /**
+ * Permission flag: The permission is granted by default because it
+ * enables app functionality that is expected to work out-of-the-box
+ * for providing a smooth user experience. For example, the phone app
+ * is expected to have the phone permission.
+ *
+ * @hide
+ */
+ public static final int FLAG_PERMISSION_GRANTED_BY_DEFAULT = 1 << 5;
+
/**
* Mask for all permission flags.
*
@@ -2474,7 +2480,8 @@ public abstract class PackageManager {
FLAG_PERMISSION_USER_FIXED,
FLAG_PERMISSION_POLICY_FIXED,
FLAG_PERMISSION_REVOKE_ON_UPGRADE,
- FLAG_PERMISSION_SYSTEM_FIXED})
+ FLAG_PERMISSION_SYSTEM_FIXED,
+ FLAG_PERMISSION_GRANTED_BY_DEFAULT})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionFlags {}
@@ -4634,6 +4641,19 @@ public abstract class PackageManager {
}
/** {@hide} */
+ public static String permissionFlagToString(int flag) {
+ switch (flag) {
+ case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "FLAG_PERMISSION_GRANTED_BY_DEFAULT";
+ case FLAG_PERMISSION_POLICY_FIXED: return "FLAG_PERMISSION_POLICY_FIXED";
+ case FLAG_PERMISSION_SYSTEM_FIXED: return "FLAG_PERMISSION_SYSTEM_FIXED";
+ case FLAG_PERMISSION_USER_SET: return "FLAG_PERMISSION_USER_SET";
+ case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "FLAG_PERMISSION_REVOKE_ON_UPGRADE";
+ case FLAG_PERMISSION_USER_FIXED: return "FLAG_PERMISSION_USER_FIXED";
+ default: return Integer.toString(flag);
+ }
+ }
+
+ /** {@hide} */
public static class LegacyPackageInstallObserver extends PackageInstallObserver {
private final IPackageInstallObserver mLegacy;
diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java
index 67c36e3..1ee3827 100644
--- a/core/java/android/text/Hyphenator.java
+++ b/core/java/android/text/Hyphenator.java
@@ -21,9 +21,10 @@ import com.android.internal.annotations.GuardedBy;
import android.annotation.Nullable;
import android.util.Log;
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.IOException;
-import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Locale;
@@ -42,9 +43,9 @@ public class Hyphenator {
private final static Object sLock = new Object();
@GuardedBy("sLock")
- static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();
+ final static HashMap<Locale, Hyphenator> sMap = new HashMap<Locale, Hyphenator>();
- private long mNativePtr;
+ final private long mNativePtr;
private Hyphenator(long nativePtr) {
mNativePtr = nativePtr;
@@ -90,17 +91,13 @@ public class Hyphenator {
String patternFilename = "hyph-"+languageTag.toLowerCase(Locale.US)+".pat.txt";
File patternFile = new File(getSystemHyphenatorLocation(), patternFilename);
try {
- RandomAccessFile rf = new RandomAccessFile(patternFile, "r");
- byte[] buf = new byte[(int)rf.length()];
- rf.read(buf);
- rf.close();
- String patternData = new String(buf);
+ String patternData = IoUtils.readFileAsString(patternFile.getAbsolutePath());
long nativePtr = StaticLayout.nLoadHyphenator(patternData);
return new Hyphenator(nativePtr);
} catch (IOException e) {
Log.e(TAG, "error loading hyphenation " + patternFile, e);
+ return null;
}
- return null;
}
private static File getSystemHyphenatorLocation() {
diff --git a/core/java/android/view/ViewAnimationUtils.java b/core/java/android/view/ViewAnimationUtils.java
index d44df31..4c75935 100644
--- a/core/java/android/view/ViewAnimationUtils.java
+++ b/core/java/android/view/ViewAnimationUtils.java
@@ -43,8 +43,10 @@ public final class ViewAnimationUtils {
* on thread responsiveness.
*
* @param view The View will be clipped to the animating circle.
- * @param centerX The x coordinate of the center of the animating circle.
- * @param centerY The y coordinate of the center of the animating circle.
+ * @param centerX The x coordinate of the center of the animating circle, relative to
+ * <code>view</code>.
+ * @param centerY The y coordinate of the center of the animating circle, relative to
+ * <code>view</code>.
* @param startRadius The starting radius of the animating circle.
* @param endRadius The ending radius of the animating circle.
*/
diff --git a/docs/html/training/material/animations.jd b/docs/html/training/material/animations.jd
index 86e91a7..6f263db 100644
--- a/docs/html/training/material/animations.jd
+++ b/docs/html/training/material/animations.jd
@@ -81,8 +81,8 @@ reveal or hide a view.</p>
View myView = findViewById(R.id.my_view);
// get the center for the clipping circle
-int cx = (myView.getLeft() + myView.getRight()) / 2;
-int cy = (myView.getTop() + myView.getBottom()) / 2;
+int cx = myView.getWidth() / 2;
+int cy = myView.getHeight() / 2;
// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());
@@ -103,8 +103,8 @@ anim.start();
final View myView = findViewById(R.id.my_view);
// get the center for the clipping circle
-int cx = (myView.getLeft() + myView.getRight()) / 2;
-int cy = (myView.getTop() + myView.getBottom()) / 2;
+int cx = myView.getWidth() / 2;
+int cy = myView.getHeight() / 2;
// get the initial radius for the clipping circle
int initialRadius = myView.getWidth();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index f4be9c5..006f6e9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -50,6 +50,8 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
import android.os.OperationCanceledException;
import android.os.Parcelable;
import android.provider.DocumentsContract;
@@ -135,6 +137,8 @@ public class DirectoryFragment extends Fragment {
private final int mLoaderId = 42;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
public static void showNormal(FragmentManager fm, RootInfo root, DocumentInfo doc, int anim) {
show(fm, TYPE_NORMAL, root, doc, null, anim);
}
@@ -297,6 +301,21 @@ public class DirectoryFragment extends Fragment {
@Override
public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) {
+ if (result == null || result.exception != null) {
+ // onBackPressed does a fragment transaction, which can't be done inside
+ // onLoadFinished
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ final Activity activity = getActivity();
+ if (activity != null) {
+ activity.onBackPressed();
+ }
+ }
+ });
+ return;
+ }
+
if (!isAdded()) return;
mAdapter.swapResult(result);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index 8e4ec8c..a8a61d2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -31,7 +31,10 @@ import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
import android.os.OperationCanceledException;
+import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;
@@ -163,6 +166,10 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
cursor = client.query(
mUri, null, null, null, getQuerySortOrder(result.sortOrder), mSignal);
+ if (cursor == null) {
+ throw new RemoteException("Provider returned null");
+ }
+
cursor.registerContentObserver(mObserver);
cursor = new RootCursorWrapper(mUri.getAuthority(), mRoot.rootId, cursor, -1);
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 4143e15..4f0c6a41 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -62,6 +62,9 @@ public class ExternalStorageProvider extends DocumentsProvider {
public static final String AUTHORITY = "com.android.externalstorage.documents";
+ private static final Uri BASE_URI =
+ new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build();
+
// docId format: root:path/to/file
private static final String[] DEFAULT_ROOT_PROJECTION = new String[] {
@@ -170,8 +173,10 @@ public class ExternalStorageProvider extends DocumentsProvider {
Log.d(TAG, "After updating volumes, found " + mRoots.size() + " active roots");
- getContext().getContentResolver()
- .notifyChange(DocumentsContract.buildRootsUri(AUTHORITY), null, false);
+ // Note this affects content://com.android.externalstorage.documents/root/39BD-07C5
+ // as well as content://com.android.externalstorage.documents/document/*/children,
+ // so just notify on content://com.android.externalstorage.documents/.
+ getContext().getContentResolver().notifyChange(BASE_URI, null, false);
}
private static String[] resolveRootProjection(String[] projection) {
diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
index e459e26..453f123 100644
--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java
@@ -202,7 +202,8 @@ final class DefaultPermissionGrantPolicy {
mService.grantRuntimePermission(pkg.packageName, permission, userId);
mService.updatePermissionFlags(permission, pkg.packageName,
PackageManager.MASK_PERMISSION_FLAGS,
- PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
+ | PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, userId);
if (DEBUG) {
Log.i(TAG, "Granted " + permission + " to system component "
+ pkg.packageName);
@@ -439,7 +440,7 @@ final class DefaultPermissionGrantPolicy {
getDefaultSystemHandlerActivityPackageLPr(deviceProvisionIntent, userId);
if (deviceProvisionPackage != null
&& doesPackageSupportRuntimePermissions(deviceProvisionPackage)) {
- grantRuntimePermissionsLPw(contactsPackage, ACCOUNTS_PERMISSIONS, userId);
+ grantRuntimePermissionsLPw(deviceProvisionPackage, ACCOUNTS_PERMISSIONS, userId);
}
// Maps
@@ -768,11 +769,13 @@ final class DefaultPermissionGrantPolicy {
+ pkg.packageName);
}
+ int newFlags = PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
if (systemFixed) {
- mService.updatePermissionFlags(permission, pkg.packageName,
- PackageManager.FLAG_PERMISSION_SYSTEM_FIXED,
- PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, userId);
+ newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
}
+
+ mService.updatePermissionFlags(permission, pkg.packageName,
+ newFlags, newFlags, userId);
}
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 0ad2b4a..8ca8331 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4333,12 +4333,25 @@ final class Settings {
}
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
- pw.print(", flags=0x"); pw.println(Integer.toHexString(
+ pw.print(", flags="); pw.println(permissionFlagsToString(
permissionState.getFlags()));
}
}
}
+ private static String permissionFlagsToString(int flags) {
+ StringBuilder flagsString = new StringBuilder();
+ flagsString.append("[ ");
+ while (flags != 0) {
+ final int flag = 1 << Integer.numberOfTrailingZeros(flags);
+ flags &= ~flag;
+ flagsString.append(PackageManager.permissionFlagToString(flag));
+ flagsString.append(' ');
+ }
+ flagsString.append(']');
+ return flagsString.toString();
+ }
+
void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
PermissionsState permissionsState) {
List<PermissionState> permissionStates = permissionsState.getInstallPermissionStates();
@@ -4351,7 +4364,7 @@ final class Settings {
}
pw.print(prefix); pw.print(" "); pw.print(permissionState.getName());
pw.print(", granted="); pw.print(permissionState.isGranted());
- pw.print(", flags=0x"); pw.println(Integer.toHexString(
+ pw.print(", flags="); pw.println(permissionFlagsToString(
permissionState.getFlags()));
}
}