summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-06-04 23:34:12 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-06-04 23:34:12 +0000
commitcec6edbc18f98d5a1efc7b3cc4d2825cb79d96a6 (patch)
tree05d306c1a05921d9608495bd7aad03dc4a739ccd
parent09e997bcb4391d3340270da9d44465966d4bfffb (diff)
parent0e17a350827b2e02dc8191a21a0dd1be682f62ac (diff)
downloadbase-oreo-m4-s8-release.tar.gz
Merge cherrypicks of [4255363, 4255364, 4254607, 4254608, 4254909, 4254910, 4254911, 4255904, 4255905, 4255906, 4255907, 4254912, 4254624, 4255365, 4254609, 4254610, 4254611, 4254612, 4254613, 4254614, 4254615, 4254691, 4254692, 4254693, 4254694, 4254695, 4254696, 4254697, 4254698, 4254699, 4254700, 4255981, 4254913, 4255282, 4255283, 4255284, 4255366, 4256001, 4256002, 4254616, 4255367, 4256003, 4254957, 4254958, 4255403, 4255404, 4255405, 4255406, 4255407, 4255408, 4255409, 4255410, 4255411, 4255412, 4255413, 4255414, 4255415, 4255416, 4253350, 4256013, 4254991, 4256014, 4254959, 4254960, 4254992, 4254993, 4254994] into sparse-4732991-L15500000179240506android-8.1.0_r38oreo-m4-s8-release
Change-Id: I469557015f594be0279ce16b2aabb927101258c2
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl10
-rw-r--r--core/java/android/app/ActivityManagerInternal.java5
-rw-r--r--core/java/android/appwidget/AppWidgetManagerInternal.java36
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java6
-rw-r--r--core/java/android/os/Parcel.java15
-rw-r--r--core/java/android/provider/MediaStore.java4
-rw-r--r--core/java/android/service/autofill/Dataset.java9
-rw-r--r--core/java/android/service/autofill/SaveRequest.java8
-rw-r--r--core/java/android/view/ViewRootImpl.java1
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java118
-rw-r--r--core/java/android/view/accessibility/AccessibilityManager.java5
-rw-r--r--core/java/android/view/accessibility/IAccessibilityManager.aidl2
-rw-r--r--libs/androidfw/ResourceTypes.cpp18
-rw-r--r--media/java/android/media/MediaScanner.java52
-rw-r--r--media/java/android/media/MiniThumbFile.java54
-rw-r--r--packages/Osu/src/com/android/hotspot2/flow/OSUInfo.java12
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java291
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java25
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java105
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java2
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl4
23 files changed, 608 insertions, 203 deletions
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 7a1931718888..037aeb058f15 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -35,23 +35,23 @@ interface IAccessibilityServiceConnection {
void setServiceInfo(in AccessibilityServiceInfo info);
- boolean findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
+ String[] findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
long accessibilityNodeId, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags, long threadId,
in Bundle arguments);
- boolean findAccessibilityNodeInfosByText(int accessibilityWindowId, long accessibilityNodeId,
+ String[] findAccessibilityNodeInfosByText(int accessibilityWindowId, long accessibilityNodeId,
String text, int interactionId, IAccessibilityInteractionConnectionCallback callback,
long threadId);
- boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
+ String[] findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
long accessibilityNodeId, String viewId, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long threadId);
- boolean findFocus(int accessibilityWindowId, long accessibilityNodeId, int focusType,
+ String[] findFocus(int accessibilityWindowId, long accessibilityNodeId, int focusType,
int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId);
- boolean focusSearch(int accessibilityWindowId, long accessibilityNodeId, int direction,
+ String[] focusSearch(int accessibilityWindowId, long accessibilityNodeId, int direction,
int interactionId, IAccessibilityInteractionConnectionCallback callback, long threadId);
boolean performAccessibilityAction(int accessibilityWindowId, long accessibilityNodeId,
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index c8d983933fc6..9dceb7f9e433 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -268,4 +268,9 @@ public abstract class ActivityManagerInternal {
* @param token The IApplicationToken for the activity
*/
public abstract void setFocusedActivity(IBinder token);
+
+ /**
+ * Returns {@code true} if {@code uid} is running an activity from {@code packageName}.
+ */
+ public abstract boolean hasRunningActivity(int uid, @Nullable String packageName);
}
diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java
new file mode 100644
index 000000000000..5562c550fe18
--- /dev/null
+++ b/core/java/android/appwidget/AppWidgetManagerInternal.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appwidget;
+
+import android.annotation.Nullable;
+import android.util.ArraySet;
+
+/**
+ * App widget manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class AppWidgetManagerInternal {
+
+ /**
+ * Gets the packages from which the uid hosts widgets.
+ *
+ * @param uid The potential host UID.
+ * @return Whether the UID hosts widgets from the package.
+ */
+ public abstract @Nullable ArraySet<String> getHostedWidgetPackages(int uid);
+}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 98cd319a399a..9498f125c2a6 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -808,7 +808,11 @@ public final class BluetoothDevice implements Parcelable {
return null;
}
try {
- return service.getRemoteName(this);
+ String name = service.getRemoteName(this);
+ if (name != null) {
+ return name.replaceAll("[\\t\\n\\r]+", " ");
+ }
+ return null;
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index fae9d5310f8e..c6d3860c6600 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1340,6 +1340,13 @@ public final class Parcel {
* @see Parcelable
*/
public final <T extends Parcelable> void writeTypedList(List<T> val) {
+ writeTypedList(val, 0);
+ }
+
+ /**
+ * @hide
+ */
+ public <T extends Parcelable> void writeTypedList(List<T> val, int parcelableFlags) {
if (val == null) {
writeInt(-1);
return;
@@ -1348,13 +1355,7 @@ public final class Parcel {
int i=0;
writeInt(N);
while (i < N) {
- T item = val.get(i);
- if (item != null) {
- writeInt(1);
- item.writeToParcel(this, 0);
- } else {
- writeInt(0);
- }
+ writeTypedObject(val.get(i), parcelableFlags);
i++;
}
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 13e1e26b51c3..ff4f358529a4 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -694,8 +694,8 @@ public final class MediaStore {
// Log.v(TAG, "getThumbnail: origId="+origId+", kind="+kind+", isVideo="+isVideo);
// If the magic is non-zero, we simply return thumbnail if it does exist.
// querying MediaProvider and simply return thumbnail.
- MiniThumbFile thumbFile = new MiniThumbFile(isVideo ? Video.Media.EXTERNAL_CONTENT_URI
- : Images.Media.EXTERNAL_CONTENT_URI);
+ MiniThumbFile thumbFile = MiniThumbFile.instance(
+ isVideo ? Video.Media.EXTERNAL_CONTENT_URI : Images.Media.EXTERNAL_CONTENT_URI);
Cursor c = null;
try {
long magic = thumbFile.getMagic(origId);
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 65b0efcbe032..21a3df89e0f8 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -316,8 +316,8 @@ public final class Dataset implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeParcelable(mPresentation, flags);
- parcel.writeTypedArrayList(mFieldIds, flags);
- parcel.writeTypedArrayList(mFieldValues, flags);
+ parcel.writeTypedList(mFieldIds, flags);
+ parcel.writeTypedList(mFieldValues, flags);
parcel.writeParcelableList(mFieldPresentations, flags);
parcel.writeParcelable(mAuthentication, flags);
parcel.writeString(mId);
@@ -333,8 +333,9 @@ public final class Dataset implements Parcelable {
final Builder builder = (presentation == null)
? new Builder()
: new Builder(presentation);
- final ArrayList<AutofillId> ids = parcel.readTypedArrayList(null);
- final ArrayList<AutofillValue> values = parcel.readTypedArrayList(null);
+ final ArrayList<AutofillId> ids = parcel.createTypedArrayList(AutofillId.CREATOR);
+ final ArrayList<AutofillValue> values =
+ parcel.createTypedArrayList(AutofillValue.CREATOR);
final ArrayList<RemoteViews> presentations = new ArrayList<>();
parcel.readParcelableList(presentations, null);
final int idCount = (ids != null) ? ids.size() : 0;
diff --git a/core/java/android/service/autofill/SaveRequest.java b/core/java/android/service/autofill/SaveRequest.java
index 9de931542cb9..fc4272dd7742 100644
--- a/core/java/android/service/autofill/SaveRequest.java
+++ b/core/java/android/service/autofill/SaveRequest.java
@@ -19,9 +19,9 @@ package android.service.autofill;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Bundle;
-import android.os.CancellationSignal;
import android.os.Parcel;
import android.os.Parcelable;
+
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
@@ -45,7 +45,7 @@ public final class SaveRequest implements Parcelable {
}
private SaveRequest(@NonNull Parcel parcel) {
- this(parcel.readTypedArrayList(null), parcel.readBundle());
+ this(parcel.createTypedArrayList(FillContext.CREATOR), parcel.readBundle());
}
/**
@@ -57,7 +57,7 @@ public final class SaveRequest implements Parcelable {
/**
* Gets the extra client state returned from the last {@link
- * AutofillService#onFillRequest(FillRequest, CancellationSignal, FillCallback)}
+ * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)}
* fill request}.
*
* @return The client state.
@@ -73,7 +73,7 @@ public final class SaveRequest implements Parcelable {
@Override
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeTypedArrayList(mFillContexts, flags);
+ parcel.writeTypedList(mFillContexts, flags);
parcel.writeBundle(mClientState);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8f250a9e9f15..3f1ea34c37ab 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -7733,6 +7733,7 @@ public final class ViewRootImpl implements ViewParent,
if (!registered) {
mAttachInfo.mAccessibilityWindowId =
mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
+ mContext.getPackageName(),
new AccessibilityInteractionConnection(ViewRootImpl.this));
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 19213ca06c5e..980a2c926c1a 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -28,6 +28,8 @@ import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
+import com.android.internal.util.ArrayUtils;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -283,14 +285,19 @@ public final class AccessibilityInteractionClient
}
final int interactionId = mInteractionIdCounter.getAndIncrement();
final long identityToken = Binder.clearCallingIdentity();
- final boolean success = connection.findAccessibilityNodeInfoByAccessibilityId(
- accessibilityWindowId, accessibilityNodeId, interactionId, this,
- prefetchFlags, Thread.currentThread().getId(), arguments);
- Binder.restoreCallingIdentity(identityToken);
- if (success) {
+ final String[] packageNames;
+ try {
+ packageNames = connection.findAccessibilityNodeInfoByAccessibilityId(
+ accessibilityWindowId, accessibilityNodeId, interactionId, this,
+ prefetchFlags, Thread.currentThread().getId(), arguments);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
+ if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
- finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
+ finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
+ bypassCache, packageNames);
if (infos != null && !infos.isEmpty()) {
for (int i = 1; i < infos.size(); i++) {
infos.get(i).recycle();
@@ -333,15 +340,21 @@ public final class AccessibilityInteractionClient
if (connection != null) {
final int interactionId = mInteractionIdCounter.getAndIncrement();
final long identityToken = Binder.clearCallingIdentity();
- final boolean success = connection.findAccessibilityNodeInfosByViewId(
- accessibilityWindowId, accessibilityNodeId, viewId, interactionId, this,
- Thread.currentThread().getId());
- Binder.restoreCallingIdentity(identityToken);
- if (success) {
+ final String[] packageNames;
+ try {
+ packageNames = connection.findAccessibilityNodeInfosByViewId(
+ accessibilityWindowId, accessibilityNodeId, viewId, interactionId, this,
+ Thread.currentThread().getId());
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
+
+ if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
if (infos != null) {
- finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
+ finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
+ false, packageNames);
return infos;
}
}
@@ -381,15 +394,21 @@ public final class AccessibilityInteractionClient
if (connection != null) {
final int interactionId = mInteractionIdCounter.getAndIncrement();
final long identityToken = Binder.clearCallingIdentity();
- final boolean success = connection.findAccessibilityNodeInfosByText(
- accessibilityWindowId, accessibilityNodeId, text, interactionId, this,
- Thread.currentThread().getId());
- Binder.restoreCallingIdentity(identityToken);
- if (success) {
+ final String[] packageNames;
+ try {
+ packageNames = connection.findAccessibilityNodeInfosByText(
+ accessibilityWindowId, accessibilityNodeId, text, interactionId, this,
+ Thread.currentThread().getId());
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
+
+ if (packageNames != null) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
if (infos != null) {
- finalizeAndCacheAccessibilityNodeInfos(infos, connectionId);
+ finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
+ false, packageNames);
return infos;
}
}
@@ -428,14 +447,19 @@ public final class AccessibilityInteractionClient
if (connection != null) {
final int interactionId = mInteractionIdCounter.getAndIncrement();
final long identityToken = Binder.clearCallingIdentity();
- final boolean success = connection.findFocus(accessibilityWindowId,
- accessibilityNodeId, focusType, interactionId, this,
- Thread.currentThread().getId());
- Binder.restoreCallingIdentity(identityToken);
- if (success) {
+ final String[] packageNames;
+ try {
+ packageNames = connection.findFocus(accessibilityWindowId,
+ accessibilityNodeId, focusType, interactionId, this,
+ Thread.currentThread().getId());
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
+
+ if (packageNames != null) {
AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
interactionId);
- finalizeAndCacheAccessibilityNodeInfo(info, connectionId);
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId, false, packageNames);
return info;
}
} else {
@@ -472,14 +496,19 @@ public final class AccessibilityInteractionClient
if (connection != null) {
final int interactionId = mInteractionIdCounter.getAndIncrement();
final long identityToken = Binder.clearCallingIdentity();
- final boolean success = connection.focusSearch(accessibilityWindowId,
- accessibilityNodeId, direction, interactionId, this,
- Thread.currentThread().getId());
- Binder.restoreCallingIdentity(identityToken);
- if (success) {
+ final String[] packageNames;
+ try {
+ packageNames = connection.focusSearch(accessibilityWindowId,
+ accessibilityNodeId, direction, interactionId, this,
+ Thread.currentThread().getId());
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
+
+ if (packageNames != null) {
AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
interactionId);
- finalizeAndCacheAccessibilityNodeInfo(info, connectionId);
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId, false, packageNames);
return info;
}
} else {
@@ -580,7 +609,7 @@ public final class AccessibilityInteractionClient
int interactionId) {
synchronized (mInstanceLock) {
final boolean success = waitForResultTimedLocked(interactionId);
- List<AccessibilityNodeInfo> result = null;
+ final List<AccessibilityNodeInfo> result;
if (success) {
result = mFindAccessibilityNodeInfosResult;
} else {
@@ -696,13 +725,28 @@ public final class AccessibilityInteractionClient
*
* @param info The info.
* @param connectionId The id of the connection to the system.
+ * @param bypassCache Whether or not to bypass the cache. The node is added to the cache if
+ * this value is {@code false}
+ * @param packageNames The valid package names a node can come from.
*/
private void finalizeAndCacheAccessibilityNodeInfo(AccessibilityNodeInfo info,
- int connectionId) {
+ int connectionId, boolean bypassCache, String[] packageNames) {
if (info != null) {
info.setConnectionId(connectionId);
+ // Empty array means any package name is Okay
+ if (!ArrayUtils.isEmpty(packageNames)) {
+ CharSequence packageName = info.getPackageName();
+ if (packageName == null
+ || !ArrayUtils.contains(packageNames, packageName.toString())) {
+ // If the node package not one of the valid ones, pick the top one - this
+ // is one of the packages running in the introspected UID.
+ info.setPackageName(packageNames[0]);
+ }
+ }
info.setSealed(true);
- sAccessibilityCache.add(info);
+ if (!bypassCache) {
+ sAccessibilityCache.add(info);
+ }
}
}
@@ -711,14 +755,18 @@ public final class AccessibilityInteractionClient
*
* @param infos The {@link AccessibilityNodeInfo}s.
* @param connectionId The id of the connection to the system.
+ * @param bypassCache Whether or not to bypass the cache. The nodes are added to the cache if
+ * this value is {@code false}
+ * @param packageNames The valid package names a node can come from.
*/
private void finalizeAndCacheAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos,
- int connectionId) {
+ int connectionId, boolean bypassCache, String[] packageNames) {
if (infos != null) {
final int infosCount = infos.size();
for (int i = 0; i < infosCount; i++) {
AccessibilityNodeInfo info = infos.get(i);
- finalizeAndCacheAccessibilityNodeInfo(info, connectionId);
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId,
+ bypassCache, packageNames);
}
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 0b9bc5760fa8..2478281efcd1 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -885,7 +885,7 @@ public final class AccessibilityManager {
* @hide
*/
public int addAccessibilityInteractionConnection(IWindow windowToken,
- IAccessibilityInteractionConnection connection) {
+ String packageName, IAccessibilityInteractionConnection connection) {
final IAccessibilityManager service;
final int userId;
synchronized (mLock) {
@@ -896,7 +896,8 @@ public final class AccessibilityManager {
userId = mUserId;
}
try {
- return service.addAccessibilityInteractionConnection(windowToken, connection, userId);
+ return service.addAccessibilityInteractionConnection(windowToken, connection,
+ packageName, userId);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re);
}
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 3f499abd2e4d..6329c1141bd5 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -45,7 +45,7 @@ interface IAccessibilityManager {
List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType, int userId);
int addAccessibilityInteractionConnection(IWindow windowToken,
- in IAccessibilityInteractionConnection connection, int userId);
+ in IAccessibilityInteractionConnection connection, String packageName, int userId);
void removeAccessibilityInteractionConnection(IWindow windowToken);
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 733ffb180b3b..401c7b070188 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -457,6 +457,22 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
uninit();
+ // The chunk must be at least the size of the string pool header.
+ if (size < sizeof(ResStringPool_header)) {
+ LOG_ALWAYS_FATAL("Bad string block: data size %zu is too small to be a string block", size);
+ return (mError=BAD_TYPE);
+ }
+
+ // The data is at least as big as a ResChunk_header, so we can safely validate the other
+ // header fields.
+ // `data + size` is safe because the source of `size` comes from the kernel/filesystem.
+ if (validate_chunk(reinterpret_cast<const ResChunk_header*>(data), sizeof(ResStringPool_header),
+ reinterpret_cast<const uint8_t*>(data) + size,
+ "ResStringPool_header") != NO_ERROR) {
+ LOG_ALWAYS_FATAL("Bad string block: malformed block dimensions");
+ return (mError=BAD_TYPE);
+ }
+
const bool notDeviceEndian = htods(0xf0) != 0xf0;
if (copyData || notDeviceEndian) {
@@ -468,6 +484,8 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData)
data = mOwnedData;
}
+ // The size has been checked, so it is safe to read the data in the ResStringPool_header
+ // data structure.
mHeader = (const ResStringPool_header*)data;
if (notDeviceEndian) {
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index cb4e46fe945a..e66945bd7ec4 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -323,7 +323,6 @@ public class MediaScanner implements AutoCloseable {
private final Uri mAudioUri;
private final Uri mVideoUri;
private final Uri mImagesUri;
- private final Uri mThumbsUri;
private final Uri mPlaylistsUri;
private final Uri mFilesUri;
private final Uri mFilesUriNoNotify;
@@ -419,7 +418,6 @@ public class MediaScanner implements AutoCloseable {
mAudioUri = Audio.Media.getContentUri(volumeName);
mVideoUri = Video.Media.getContentUri(volumeName);
mImagesUri = Images.Media.getContentUri(volumeName);
- mThumbsUri = Images.Thumbnails.getContentUri(volumeName);
mFilesUri = Files.getContentUri(volumeName);
mFilesUriNoNotify = mFilesUri.buildUpon().appendQueryParameter("nonotify", "1").build();
@@ -1283,53 +1281,6 @@ public class MediaScanner implements AutoCloseable {
}
}
- private void pruneDeadThumbnailFiles() {
- HashSet<String> existingFiles = new HashSet<String>();
- String directory = "/sdcard/DCIM/.thumbnails";
- String [] files = (new File(directory)).list();
- Cursor c = null;
- if (files == null)
- files = new String[0];
-
- for (int i = 0; i < files.length; i++) {
- String fullPathString = directory + "/" + files[i];
- existingFiles.add(fullPathString);
- }
-
- try {
- c = mMediaProvider.query(
- mThumbsUri,
- new String [] { "_data" },
- null,
- null,
- null, null);
- Log.v(TAG, "pruneDeadThumbnailFiles... " + c);
- if (c != null && c.moveToFirst()) {
- do {
- String fullPathString = c.getString(0);
- existingFiles.remove(fullPathString);
- } while (c.moveToNext());
- }
-
- for (String fileToDelete : existingFiles) {
- if (false)
- Log.v(TAG, "fileToDelete is " + fileToDelete);
- try {
- (new File(fileToDelete)).delete();
- } catch (SecurityException ex) {
- }
- }
-
- Log.v(TAG, "/pruneDeadThumbnailFiles... " + c);
- } catch (RemoteException e) {
- // We will soon be killed...
- } finally {
- if (c != null) {
- c.close();
- }
- }
- }
-
static class MediaBulkDeleter {
StringBuilder whereClause = new StringBuilder();
ArrayList<String> whereArgs = new ArrayList<String>(100);
@@ -1373,9 +1324,6 @@ public class MediaScanner implements AutoCloseable {
processPlayLists();
}
- if (mOriginalCount == 0 && mImagesUri.equals(Images.Media.getContentUri("external")))
- pruneDeadThumbnailFiles();
-
// allow GC to clean up
mPlayLists.clear();
}
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index 664308c45bf9..98993676ce43 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -44,13 +44,14 @@ import java.util.Hashtable;
*/
public class MiniThumbFile {
private static final String TAG = "MiniThumbFile";
- private static final int MINI_THUMB_DATA_FILE_VERSION = 3;
+ private static final int MINI_THUMB_DATA_FILE_VERSION = 4;
public static final int BYTES_PER_MINTHUMB = 10000;
private static final int HEADER_SIZE = 1 + 8 + 4;
private Uri mUri;
private RandomAccessFile mMiniThumbFile;
private FileChannel mChannel;
private ByteBuffer mBuffer;
+ private ByteBuffer mEmptyBuffer;
private static final Hashtable<String, MiniThumbFile> sThumbFiles =
new Hashtable<String, MiniThumbFile>();
@@ -127,9 +128,10 @@ public class MiniThumbFile {
return mMiniThumbFile;
}
- public MiniThumbFile(Uri uri) {
+ private MiniThumbFile(Uri uri) {
mUri = uri;
mBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
+ mEmptyBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
}
public synchronized void deactivate() {
@@ -184,6 +186,54 @@ public class MiniThumbFile {
return 0;
}
+ public synchronized void eraseMiniThumb(long id) {
+ RandomAccessFile r = miniThumbDataFile();
+ if (r != null) {
+ long pos = id * BYTES_PER_MINTHUMB;
+ FileLock lock = null;
+ try {
+ mBuffer.clear();
+ mBuffer.limit(1 + 8);
+
+ lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);
+ // check that we can read the following 9 bytes
+ // (1 for the "status" and 8 for the long)
+ if (mChannel.read(mBuffer, pos) == 9) {
+ mBuffer.position(0);
+ if (mBuffer.get() == 1) {
+ long currentMagic = mBuffer.getLong();
+ if (currentMagic == 0) {
+ // there is no thumbnail stored here
+ Log.i(TAG, "no thumbnail for id " + id);
+ return;
+ }
+ // zero out the thumbnail slot
+ // Log.v(TAG, "clearing slot " + id + ", magic " + currentMagic
+ // + " at offset " + pos);
+ mChannel.write(mEmptyBuffer, pos);
+ }
+ } else {
+ // Log.v(TAG, "No slot");
+ }
+ } catch (IOException ex) {
+ Log.v(TAG, "Got exception checking file magic: ", ex);
+ } catch (RuntimeException ex) {
+ // Other NIO related exception like disk full, read only channel..etc
+ Log.e(TAG, "Got exception when reading magic, id = " + id +
+ ", disk full or mount read-only? " + ex.getClass());
+ } finally {
+ try {
+ if (lock != null) lock.release();
+ }
+ catch (IOException ex) {
+ // ignore it.
+ }
+ }
+ } else {
+ // Log.v(TAG, "No data file");
+ }
+ }
+
public synchronized void saveMiniThumbToFile(byte[] data, long id, long magic)
throws IOException {
RandomAccessFile r = miniThumbDataFile();
diff --git a/packages/Osu/src/com/android/hotspot2/flow/OSUInfo.java b/packages/Osu/src/com/android/hotspot2/flow/OSUInfo.java
index 401eccb96d05..ae47ddd22fc3 100644
--- a/packages/Osu/src/com/android/hotspot2/flow/OSUInfo.java
+++ b/packages/Osu/src/com/android/hotspot2/flow/OSUInfo.java
@@ -42,6 +42,7 @@ public class OSUInfo implements Parcelable {
private HSIconFileElement mIconFileElement;
private String mIconFileName;
private IconInfo mIconInfo;
+ private int mIconIndex;
public OSUInfo(ScanResult scanResult, OSUProvider osuProvider, int osuID) {
mOsuID = osuID;
@@ -50,6 +51,7 @@ public class OSUInfo implements Parcelable {
mAnqpDomID = scanResult.anqpDomainId;
mAdvertisingSSID = scanResult.SSID;
mOSUProvider = osuProvider;
+ mIconIndex = -1;
}
public long getOSUBssid() {
@@ -157,12 +159,15 @@ public class OSUInfo implements Parcelable {
public void setIconFileElement(HSIconFileElement iconFileElement, String fileName) {
synchronized (mOSUProvider) {
mIconFileElement = iconFileElement;
+ int index = 0;
for (IconInfo iconInfo : mOSUProvider.getIcons()) {
if (iconInfo.getFileName().equals(fileName)) {
mIconInfo = iconInfo;
mIconFileName = fileName;
+ mIconIndex = index;
break;
}
+ index++;
}
mIconStatus = IconStatus.Available;
}
@@ -285,9 +290,9 @@ public class OSUInfo implements Parcelable {
return;
}
mIconFileElement = new HSIconFileElement(in);
- int iconIndex = in.readInt();
- mIconInfo = iconIndex >= 0 && iconIndex < mOSUProvider.getIcons().size()
- ? mOSUProvider.getIcons().get(iconIndex) : null;
+ mIconIndex = in.readInt();
+ mIconInfo = mIconIndex >= 0 && mIconIndex < mOSUProvider.getIcons().size()
+ ? mOSUProvider.getIcons().get(mIconIndex) : null;
}
public static final Parcelable.Creator<OSUInfo> CREATOR = new Parcelable.Creator<OSUInfo>() {
@@ -317,5 +322,6 @@ public class OSUInfo implements Parcelable {
dest.writeInt(mIconStatus.ordinal());
mOSUProvider.writeParcel(dest);
mIconFileElement.writeParcel(dest);
+ dest.writeInt(mIconIndex);
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 83dfccb57ebf..8b4076af7759 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -34,6 +34,7 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.app.UiAutomation;
+import android.appwidget.AppWidgetManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -82,6 +83,7 @@ import android.text.TextUtils.SimpleStringSplitter;
import android.util.IntArray;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.ArraySet;
import android.view.Display;
import android.view.IWindow;
import android.view.InputDevice;
@@ -110,10 +112,11 @@ import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
+import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.policy.AccessibilityShortcutController;
import com.android.server.statusbar.StatusBarManagerInternal;
-
+import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParserException;
import java.io.FileDescriptor;
@@ -199,6 +202,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final WindowManagerInternal mWindowManagerService;
+ private AppWidgetManagerInternal mAppWidgetService;
+
private final SecurityPolicy mSecurityPolicy;
private final MainHandler mMainHandler;
@@ -229,10 +234,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private final RemoteCallbackList<IAccessibilityManagerClient> mGlobalClients =
new RemoteCallbackList<>();
- private final SparseArray<AccessibilityConnectionWrapper> mGlobalInteractionConnections =
+ private final SparseArray<RemoteAccessibilityConnection> mGlobalInteractionConnections =
new SparseArray<>();
- private AccessibilityConnectionWrapper mPictureInPictureActionReplacingConnection;
+ private RemoteAccessibilityConnection mPictureInPictureActionReplacingConnection;
private final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<>();
@@ -501,6 +506,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
// performs the current profile parent resolution..
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
+
+ // Make sure the reported package is one the caller has access to.
+ event.setPackageName(mSecurityPolicy.resolveValidReportedPackageLocked(
+ event.getPackageName(), UserHandle.getCallingAppId(), resolvedUserId));
+
// This method does nothing for a background user.
if (resolvedUserId == mCurrentUserId) {
if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
@@ -627,30 +637,38 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
@Override
public int addAccessibilityInteractionConnection(IWindow windowToken,
- IAccessibilityInteractionConnection connection, int userId) throws RemoteException {
+ IAccessibilityInteractionConnection connection, String packageName,
+ int userId) throws RemoteException {
synchronized (mLock) {
// We treat calls from a profile as if made by its parent as profiles
// share the accessibility state of the parent. The call below
// performs the current profile parent resolution.
final int resolvedUserId = mSecurityPolicy
.resolveCallingUserIdEnforcingPermissionsLocked(userId);
+ final int resolvedUid = UserHandle.getUid(resolvedUserId, UserHandle.getCallingAppId());
+
+ // Make sure the reported package is one the caller has access to.
+ packageName = mSecurityPolicy.resolveValidReportedPackageLocked(
+ packageName, UserHandle.getCallingAppId(), resolvedUserId);
+
final int windowId = sNextWindowId++;
// If the window is from a process that runs across users such as
// the system UI or the system we add it to the global state that
// is shared across users.
if (mSecurityPolicy.isCallerInteractingAcrossUsers(userId)) {
- AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
- windowId, connection, UserHandle.USER_ALL);
+ RemoteAccessibilityConnection wrapper = new RemoteAccessibilityConnection(
+ windowId, connection, packageName, resolvedUid, UserHandle.USER_ALL);
wrapper.linkToDeath();
mGlobalInteractionConnections.put(windowId, wrapper);
mGlobalWindowTokens.put(windowId, windowToken.asBinder());
if (DEBUG) {
Slog.i(LOG_TAG, "Added global connection for pid:" + Binder.getCallingPid()
- + " with windowId: " + windowId + " and token: " + windowToken.asBinder());
+ + " with windowId: " + windowId + " and token: "
+ + windowToken.asBinder());
}
} else {
- AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
- windowId, connection, resolvedUserId);
+ RemoteAccessibilityConnection wrapper = new RemoteAccessibilityConnection(
+ windowId, connection, packageName, resolvedUid, resolvedUserId);
wrapper.linkToDeath();
UserState userState = getUserStateLocked(resolvedUserId);
userState.mInteractionConnections.put(windowId, wrapper);
@@ -679,7 +697,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if (removedWindowId >= 0) {
if (DEBUG) {
Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
- + " with windowId: " + removedWindowId + " and token: " + window.asBinder());
+ + " with windowId: " + removedWindowId + " and token: "
+ + window.asBinder());
}
return;
}
@@ -703,13 +722,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
private int removeAccessibilityInteractionConnectionInternalLocked(IBinder windowToken,
SparseArray<IBinder> windowTokens,
- SparseArray<AccessibilityConnectionWrapper> interactionConnections) {
+ SparseArray<RemoteAccessibilityConnection> interactionConnections) {
final int count = windowTokens.size();
for (int i = 0; i < count; i++) {
if (windowTokens.valueAt(i) == windowToken) {
final int windowId = windowTokens.keyAt(i);
windowTokens.removeAt(i);
- AccessibilityConnectionWrapper wrapper = interactionConnections.get(windowId);
+ RemoteAccessibilityConnection wrapper = interactionConnections.get(windowId);
wrapper.unlinkToDeath();
interactionConnections.remove(windowId);
return windowId;
@@ -729,9 +748,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
mPictureInPictureActionReplacingConnection = null;
}
if (connection != null) {
- AccessibilityConnectionWrapper wrapper = new AccessibilityConnectionWrapper(
+ RemoteAccessibilityConnection wrapper = new RemoteAccessibilityConnection(
AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID,
- connection, UserHandle.USER_ALL);
+ connection, "foo.bar.baz", Process.SYSTEM_UID, UserHandle.USER_ALL);
mPictureInPictureActionReplacingConnection = wrapper;
wrapper.linkToDeath();
}
@@ -2023,7 +2042,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final long identity = Binder.clearCallingIdentity();
try {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null, userState.mUserId);
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, null,
+ userState.mUserId);
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0, userState.mUserId);
@@ -2354,18 +2374,35 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
- private class AccessibilityConnectionWrapper implements DeathRecipient {
+ class RemoteAccessibilityConnection implements DeathRecipient {
+ private final int mUid;
+ private final String mPackageName;
private final int mWindowId;
private final int mUserId;
private final IAccessibilityInteractionConnection mConnection;
- public AccessibilityConnectionWrapper(int windowId,
- IAccessibilityInteractionConnection connection, int userId) {
+ RemoteAccessibilityConnection(int windowId,
+ IAccessibilityInteractionConnection connection,
+ String packageName, int uid, int userId) {
mWindowId = windowId;
+ mPackageName = packageName;
+ mUid = uid;
mUserId = userId;
mConnection = connection;
}
+ public int getUid() {
+ return mUid;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public IAccessibilityInteractionConnection getRemote() {
+ return mConnection;
+ }
+
public void linkToDeath() throws RemoteException {
mConnection.asBinder().linkToDeath(this, 0);
}
@@ -3041,28 +3078,28 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
@Override
- public boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
+ public String[] findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
long accessibilityNodeId, String viewIdResName, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
+ RemoteAccessibilityConnection connection = null;
Region partialInteractiveRegion = Region.obtain();
MagnificationSpec spec;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!isCalledForCurrentUserLocked()) {
- return false;
+ return null;
}
resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
if (!permissionGranted) {
- return false;
+ return null;
} else {
connection = getConnectionLocked(resolvedWindowId);
if (connection == null) {
- return false;
+ return null;
}
}
if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
@@ -3075,12 +3112,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final int interrogatingPid = Binder.getCallingPid();
callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
interrogatingPid, interrogatingTid);
+ final int callingUid = Binder.getCallingUid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.findAccessibilityNodeInfosByViewId(accessibilityNodeId, viewIdResName,
- partialInteractiveRegion, interactionId, callback, mFetchFlags,
- interrogatingPid, interrogatingTid, spec);
- return true;
+ connection.getRemote().findAccessibilityNodeInfosByViewId(accessibilityNodeId,
+ viewIdResName, partialInteractiveRegion, interactionId, callback,
+ mFetchFlags, interrogatingPid, interrogatingTid, spec);
+ return mSecurityPolicy.computeValidReportedPackages(callingUid,
+ connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error findAccessibilityNodeInfoByViewId().");
@@ -3088,36 +3127,36 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} finally {
Binder.restoreCallingIdentity(identityToken);
// Recycle if passed to another process.
- if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
+ if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) {
partialInteractiveRegion.recycle();
}
}
- return false;
+ return null;
}
@Override
- public boolean findAccessibilityNodeInfosByText(int accessibilityWindowId,
+ public String[] findAccessibilityNodeInfosByText(int accessibilityWindowId,
long accessibilityNodeId, String text, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
+ RemoteAccessibilityConnection connection = null;
Region partialInteractiveRegion = Region.obtain();
MagnificationSpec spec;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!isCalledForCurrentUserLocked()) {
- return false;
+ return null;
}
resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
if (!permissionGranted) {
- return false;
+ return null;
} else {
connection = getConnectionLocked(resolvedWindowId);
if (connection == null) {
- return false;
+ return null;
}
}
if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
@@ -3130,12 +3169,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final int interrogatingPid = Binder.getCallingPid();
callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
interrogatingPid, interrogatingTid);
+ final int callingUid = Binder.getCallingUid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.findAccessibilityNodeInfosByText(accessibilityNodeId, text,
+ connection.getRemote().findAccessibilityNodeInfosByText(accessibilityNodeId, text,
partialInteractiveRegion, interactionId, callback, mFetchFlags,
interrogatingPid, interrogatingTid, spec);
- return true;
+ return mSecurityPolicy.computeValidReportedPackages(callingUid,
+ connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfosByText()");
@@ -3143,36 +3184,36 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} finally {
Binder.restoreCallingIdentity(identityToken);
// Recycle if passed to another process.
- if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
+ if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) {
partialInteractiveRegion.recycle();
}
}
- return false;
+ return null;
}
@Override
- public boolean findAccessibilityNodeInfoByAccessibilityId(
+ public String[] findAccessibilityNodeInfoByAccessibilityId(
int accessibilityWindowId, long accessibilityNodeId, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int flags,
long interrogatingTid, Bundle arguments) throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
+ RemoteAccessibilityConnection connection = null;
Region partialInteractiveRegion = Region.obtain();
MagnificationSpec spec;
synchronized (mLock) {
mUsesAccessibilityCache = true;
if (!isCalledForCurrentUserLocked()) {
- return false;
+ return null;
}
resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
if (!permissionGranted) {
- return false;
+ return null;
} else {
connection = getConnectionLocked(resolvedWindowId);
if (connection == null) {
- return false;
+ return null;
}
}
if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
@@ -3185,12 +3226,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final int interrogatingPid = Binder.getCallingPid();
callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
interrogatingPid, interrogatingTid);
+ final int callingUid = Binder.getCallingUid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
- partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
- interrogatingPid, interrogatingTid, spec, arguments);
- return true;
+ connection.getRemote().findAccessibilityNodeInfoByAccessibilityId(
+ accessibilityNodeId, partialInteractiveRegion, interactionId, callback,
+ mFetchFlags | flags, interrogatingPid, interrogatingTid, spec, arguments);
+ return mSecurityPolicy.computeValidReportedPackages(callingUid,
+ connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
@@ -3198,36 +3241,36 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} finally {
Binder.restoreCallingIdentity(identityToken);
// Recycle if passed to another process.
- if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
+ if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) {
partialInteractiveRegion.recycle();
}
}
- return false;
+ return null;
}
@Override
- public boolean findFocus(int accessibilityWindowId, long accessibilityNodeId,
+ public String[] findFocus(int accessibilityWindowId, long accessibilityNodeId,
int focusType, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
+ RemoteAccessibilityConnection connection = null;
Region partialInteractiveRegion = Region.obtain();
MagnificationSpec spec;
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
- return false;
+ return null;
}
resolvedWindowId = resolveAccessibilityWindowIdForFindFocusLocked(
accessibilityWindowId, focusType);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
if (!permissionGranted) {
- return false;
+ return null;
} else {
connection = getConnectionLocked(resolvedWindowId);
if (connection == null) {
- return false;
+ return null;
}
}
if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
@@ -3240,12 +3283,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final int interrogatingPid = Binder.getCallingPid();
callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
interrogatingPid, interrogatingTid);
+ final int callingUid = Binder.getCallingUid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.findFocus(accessibilityNodeId, focusType, partialInteractiveRegion,
- interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
- spec);
- return true;
+ connection.getRemote().findFocus(accessibilityNodeId, focusType,
+ partialInteractiveRegion, interactionId, callback, mFetchFlags,
+ interrogatingPid, interrogatingTid, spec);
+ return mSecurityPolicy.computeValidReportedPackages(callingUid,
+ connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findFocus()");
@@ -3253,35 +3298,35 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} finally {
Binder.restoreCallingIdentity(identityToken);
// Recycle if passed to another process.
- if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
+ if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) {
partialInteractiveRegion.recycle();
}
}
- return false;
+ return null;
}
@Override
- public boolean focusSearch(int accessibilityWindowId, long accessibilityNodeId,
+ public String[] focusSearch(int accessibilityWindowId, long accessibilityNodeId,
int direction, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
+ RemoteAccessibilityConnection connection = null;
Region partialInteractiveRegion = Region.obtain();
MagnificationSpec spec;
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
- return false;
+ return null;
}
resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
final boolean permissionGranted =
mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
if (!permissionGranted) {
- return false;
+ return null;
} else {
connection = getConnectionLocked(resolvedWindowId);
if (connection == null) {
- return false;
+ return null;
}
}
if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked(
@@ -3294,12 +3339,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
final int interrogatingPid = Binder.getCallingPid();
callback = replaceCallbackIfNeeded(callback, resolvedWindowId, interactionId,
interrogatingPid, interrogatingTid);
+ final int callingUid = Binder.getCallingUid();
final long identityToken = Binder.clearCallingIdentity();
try {
- connection.focusSearch(accessibilityNodeId, direction, partialInteractiveRegion,
- interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid,
- spec);
- return true;
+ connection.getRemote().focusSearch(accessibilityNodeId, direction,
+ partialInteractiveRegion, interactionId, callback, mFetchFlags,
+ interrogatingPid, interrogatingTid, spec);
+ return mSecurityPolicy.computeValidReportedPackages(callingUid,
+ connection.getPackageName(), connection.getUid());
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling accessibilityFocusSearch()");
@@ -3307,11 +3354,11 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
} finally {
Binder.restoreCallingIdentity(identityToken);
// Recycle if passed to another process.
- if (partialInteractiveRegion != null && Binder.isProxy(connection)) {
+ if (partialInteractiveRegion != null && Binder.isProxy(connection.getRemote())) {
partialInteractiveRegion.recycle();
}
}
- return false;
+ return null;
}
@Override
@@ -3351,8 +3398,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
throws RemoteException {
final int resolvedWindowId;
- IAccessibilityInteractionConnection connection = null;
IBinder activityToken = null;
+ RemoteAccessibilityConnection connection;
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
return false;
@@ -3375,7 +3422,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
if ((a11yWindowInfo != null) && a11yWindowInfo.inPictureInPicture()) {
if ((mPictureInPictureActionReplacingConnection != null)
&& !isA11yFocusAction) {
- connection = mPictureInPictureActionReplacingConnection.mConnection;
+ connection = mPictureInPictureActionReplacingConnection;
}
}
}
@@ -3391,8 +3438,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
LocalServices.getService(ActivityManagerInternal.class)
.setFocusedActivity(activityToken);
}
- connection.performAccessibilityAction(accessibilityNodeId, action, arguments,
- interactionId, callback, mFetchFlags, interrogatingPid, interrogatingTid);
+ connection.mConnection.performAccessibilityAction(accessibilityNodeId, action,
+ arguments, interactionId, callback, mFetchFlags, interrogatingPid,
+ interrogatingTid);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling performAccessibilityAction()");
@@ -4072,16 +4120,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
LocalServices.getService(StatusBarManagerInternal.class).toggleSplitScreen();
}
- private IAccessibilityInteractionConnection getConnectionLocked(int windowId) {
+ private RemoteAccessibilityConnection getConnectionLocked(int windowId) {
if (DEBUG) {
Slog.i(LOG_TAG, "Trying to get interaction connection to windowId: " + windowId);
}
- AccessibilityConnectionWrapper wrapper = mGlobalInteractionConnections.get(windowId);
+ RemoteAccessibilityConnection wrapper = mGlobalInteractionConnections.get(windowId);
if (wrapper == null) {
wrapper = getCurrentUserStateLocked().mInteractionConnections.get(windowId);
}
if (wrapper != null && wrapper.mConnection != null) {
- return wrapper.mConnection;
+ return wrapper;
}
if (DEBUG) {
Slog.e(LOG_TAG, "No interaction connection to window: " + windowId);
@@ -4230,6 +4278,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ private AppWidgetManagerInternal getAppWidgetManager() {
+ synchronized (mLock) {
+ if (mAppWidgetService == null
+ && mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)) {
+ mAppWidgetService = LocalServices.getService(AppWidgetManagerInternal.class);
+ }
+ return mAppWidgetService;
+ }
+ }
+
final class WindowsForAccessibilityCallback implements
WindowManagerInternal.WindowsForAccessibilityCallback {
@@ -4507,6 +4565,81 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
}
}
+ private boolean isValidPackageForUid(String packageName, int uid) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return uid == mPackageManager.getPackageUid(
+ packageName, UserHandle.getUserId(uid));
+ } catch (PackageManager.NameNotFoundException e) {
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ String resolveValidReportedPackageLocked(CharSequence packageName, int appId, int userId) {
+ // Okay to pass no package
+ if (packageName == null) {
+ return null;
+ }
+ // The system gets to pass any package
+ if (appId == Process.SYSTEM_UID) {
+ return packageName.toString();
+ }
+ // Passing a package in your UID is fine
+ final String packageNameStr = packageName.toString();
+ final int resolvedUid = UserHandle.getUid(userId, appId);
+ if (isValidPackageForUid(packageNameStr, resolvedUid)) {
+ return packageName.toString();
+ }
+ // Appwidget hosts get to pass packages for widgets they host
+ final AppWidgetManagerInternal appWidgetManager = getAppWidgetManager();
+ if (appWidgetManager != null && ArrayUtils.contains(appWidgetManager
+ .getHostedWidgetPackages(resolvedUid), packageNameStr)) {
+ return packageName.toString();
+ }
+ // Otherwise, set the package to the first one in the UID
+ final String[] packageNames = mPackageManager.getPackagesForUid(resolvedUid);
+ if (ArrayUtils.isEmpty(packageNames)) {
+ return null;
+ }
+ // Okay, the caller reported a package it does not have access to.
+ // Instead of crashing the caller for better backwards compatibility
+ // we report the first package in the UID. Since most of the time apps
+ // don't use shared user id, this will yield correct results and for
+ // the edge case of using a shared user id we may report the wrong
+ // package but this is fine since first, this is a cheating app and
+ // second there is no way to get the correct package anyway.
+ return packageNames[0];
+ }
+
+ String[] computeValidReportedPackages(int callingUid,
+ String targetPackage, int targetUid) {
+ if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+ // Empty array means any package is Okay
+ return EmptyArray.STRING;
+ }
+ // IMPORTANT: The target package is already vetted to be in the target UID
+ String[] uidPackages = new String[]{targetPackage};
+ // Appwidget hosts get to pass packages for widgets they host
+ final AppWidgetManagerInternal appWidgetManager = getAppWidgetManager();
+ if (appWidgetManager != null) {
+ final ArraySet<String> widgetPackages = appWidgetManager
+ .getHostedWidgetPackages(targetUid);
+ if (widgetPackages != null && !widgetPackages.isEmpty()) {
+ final String[] validPackages = new String[uidPackages.length
+ + widgetPackages.size()];
+ System.arraycopy(uidPackages, 0, validPackages, 0, uidPackages.length);
+ final int widgetPackageCount = widgetPackages.size();
+ for (int i = 0; i < widgetPackageCount; i++) {
+ validPackages[uidPackages.length + i] = widgetPackages.valueAt(i);
+ }
+ return validPackages;
+ }
+ }
+ return uidPackages;
+ }
+
public void clearWindowsLocked() {
List<WindowInfo> windows = Collections.emptyList();
final int activeWindowId = mActiveWindowId;
@@ -4932,7 +5065,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
new RemoteCallbackList<>();
- public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
+ public final SparseArray<RemoteAccessibilityConnection> mInteractionConnections =
new SparseArray<>();
public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 80b54770e4b7..a57010b27037 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -29,6 +29,7 @@ import android.app.PendingIntent;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DevicePolicyManagerInternal.OnCrossProfileWidgetProvidersChangeListener;
import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetManagerInternal;
import android.appwidget.AppWidgetProviderInfo;
import android.appwidget.PendingHostUpdate;
import android.content.BroadcastReceiver;
@@ -99,6 +100,7 @@ import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.DumpUtils;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
@@ -107,6 +109,7 @@ import com.android.server.WidgetBackupProvider;
import com.android.server.policy.IconUtilities;
import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -256,6 +259,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
computeMaximumWidgetBitmapMemory();
registerBroadcastReceiver();
registerOnCrossProfileProvidersChangedListener();
+
+ LocalServices.addService(AppWidgetManagerInternal.class, new AppWidgetManagerLocal());
}
private void computeMaximumWidgetBitmapMemory() {
@@ -4709,4 +4714,24 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
}
}
}
+
+ private class AppWidgetManagerLocal extends AppWidgetManagerInternal {
+ @Override
+ public ArraySet<String> getHostedWidgetPackages(int uid) {
+ synchronized (mLock) {
+ ArraySet<String> widgetPackages = null;
+ final int widgetCount = mWidgets.size();
+ for (int i = 0; i < widgetCount; i++) {
+ final Widget widget = mWidgets.get(i);
+ if (widget.host.id.uid == uid) {
+ if (widgetPackages == null) {
+ widgetPackages = new ArraySet<>();
+ }
+ widgetPackages.add(widget.provider.id.componentName.getPackageName());
+ }
+ }
+ return widgetPackages;
+ }
+ }
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index a17c3ca92e5d..6d3398ea2648 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -26,6 +26,7 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.content.ComponentName;
@@ -69,6 +70,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.HandlerCaller;
+import com.android.server.LocalServices;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.PrintWriter;
@@ -417,16 +419,17 @@ final class AutofillManagerServiceImpl {
* Asserts the component is owned by the caller.
*/
private void assertCallerLocked(@NonNull ComponentName componentName) {
+ final String packageName = componentName.getPackageName();
final PackageManager pm = mContext.getPackageManager();
final int callingUid = Binder.getCallingUid();
final int packageUid;
try {
- packageUid = pm.getPackageUidAsUser(componentName.getPackageName(),
- UserHandle.getCallingUserId());
+ packageUid = pm.getPackageUidAsUser(packageName, UserHandle.getCallingUserId());
} catch (NameNotFoundException e) {
throw new SecurityException("Could not verify UID for " + componentName);
}
- if (callingUid != packageUid) {
+ if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class)
+ .hasRunningActivity(callingUid, packageName)) {
final String[] packages = pm.getPackagesForUid(callingUid);
final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1520b96a4afd..4a2d9c9ca5a4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -24248,6 +24248,26 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
}
+
+ @Override
+ public boolean hasRunningActivity(int uid, @Nullable String packageName) {
+ if (packageName == null) return false;
+
+ synchronized (ActivityManagerService.this) {
+ for (int i = 0; i < mLruProcesses.size(); i++) {
+ final ProcessRecord processRecord = mLruProcesses.get(i);
+ if (processRecord.uid == uid) {
+ for (int j = 0; j < processRecord.activities.size(); j++) {
+ final ActivityRecord activityRecord = processRecord.activities.get(j);
+ if (packageName.equals(activityRecord.packageName)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 06600bf75ffa..d6b572835950 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -184,6 +184,7 @@ import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -5850,6 +5851,83 @@ public class PackageManagerService extends IPackageManager.Stub
}
/**
+ * We might auto-grant permissions if any permission of the group is already granted. Hence if
+ * the group of a granted permission changes we need to revoke it to avoid having permissions of
+ * the new group auto-granted.
+ *
+ * @param newPackage The new package that was installed
+ * @param oldPackage The old package that was updated
+ * @param allPackageNames All package names
+ */
+ private void revokeRuntimePermissionsIfGroupChanged(
+ PackageParser.Package newPackage,
+ PackageParser.Package oldPackage,
+ ArrayList<String> allPackageNames) {
+ final int numOldPackagePermissions = oldPackage.permissions.size();
+ final ArrayMap<String, String> oldPermissionNameToGroupName
+ = new ArrayMap<>(numOldPackagePermissions);
+
+ for (int i = 0; i < numOldPackagePermissions; i++) {
+ final PackageParser.Permission permission = oldPackage.permissions.get(i);
+
+ if (permission.group != null) {
+ oldPermissionNameToGroupName.put(permission.info.name,
+ permission.group.info.name);
+ }
+ }
+
+ final int numNewPackagePermissions = newPackage.permissions.size();
+ for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
+ newPermissionNum++) {
+ final PackageParser.Permission newPermission =
+ newPackage.permissions.get(newPermissionNum);
+ final int newProtection = newPermission.info.protectionLevel;
+
+ if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
+ final String permissionName = newPermission.info.name;
+ final String newPermissionGroupName =
+ newPermission.group == null ? null : newPermission.group.info.name;
+ final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
+ permissionName);
+
+ if (newPermissionGroupName != null
+ && !newPermissionGroupName.equals(oldPermissionGroupName)) {
+ final List<UserInfo> users = mContext.getSystemService(UserManager.class)
+ .getUsers();
+
+ final int numUsers = users.size();
+ for (int userNum = 0; userNum < numUsers; userNum++) {
+ final int userId = users.get(userNum).id;
+ final int numPackages = allPackageNames.size();
+
+ for (int packageNum = 0; packageNum < numPackages; packageNum++) {
+ final String packageName = allPackageNames.get(packageNum);
+
+ if (checkPermission(permissionName, packageName, userId)
+ == PackageManager.PERMISSION_GRANTED) {
+ EventLog.writeEvent(0x534e4554, "72710897",
+ newPackage.applicationInfo.uid,
+ "Revoking permission", permissionName, "from package",
+ packageName, "as the group changed from",
+ oldPermissionGroupName, "to", newPermissionGroupName);
+
+ try {
+ revokeRuntimePermission(packageName, permissionName, userId,
+ false);
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Could not revoke " + permissionName + " from "
+ + packageName, e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
* Get the first event id for the permission.
*
* <p>There are four events for each permission: <ul>
@@ -10743,6 +10821,8 @@ public class PackageManagerService extends IPackageManager.Stub
String primaryCpuAbiFromSettings = null;
String secondaryCpuAbiFromSettings = null;
+ final PackageParser.Package oldPkg;
+
// writer
synchronized (mPackages) {
if (pkg.mSharedUserId != null) {
@@ -10843,6 +10923,12 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageSetting disabledPkgSetting =
mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ if (oldPkgSetting == null) {
+ oldPkg = null;
+ } else {
+ oldPkg = oldPkgSetting.pkg;
+ }
+
String[] usesStaticLibraries = null;
if (pkg.usesStaticLibraries != null) {
usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
@@ -11175,6 +11261,25 @@ public class PackageManagerService extends IPackageManager.Stub
mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
}
}
+
+ if (oldPkg != null) {
+ // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
+ // revokation from this method might need to kill apps which need the
+ // mPackages lock on a different thread. This would dead lock.
+ //
+ // Hence create a copy of all package names and pass it into
+ // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
+ // revoked. If a new package is added before the async code runs the permission
+ // won't be granted yet, hence new packages are no problem.
+ final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
+
+ AsyncTask.execute(new Runnable() {
+ public void run() {
+ revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
+ }
+ });
+ }
+
return pkg;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c9afb9f9ea31..d4a806621362 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -4605,7 +4605,7 @@ public class TelephonyManager {
ITelephony telephony = getITelephony();
if (telephony == null)
return null;
- return telephony.getForbiddenPlmns(subId, appType);
+ return telephony.getForbiddenPlmns(subId, appType, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9262ec5ed53b..235b5eecb986 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1352,12 +1352,12 @@ interface ITelephony {
* Returns null if the query fails.
*
*
- * <p>Requires that the calling app has READ_PRIVILEGED_PHONE_STATE
+ * <p>Requires that the calling app has READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE
*
* @param subId subscription ID used for authentication
* @param appType the icc application type, like {@link #APPTYPE_USIM}
*/
- String[] getForbiddenPlmns(int subId, int appType);
+ String[] getForbiddenPlmns(int subId, int appType, String callingPackage);
/**
* Check if phone is in emergency callback mode