summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-05-25 18:43:02 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-05-25 18:43:02 +0000
commitadeda596272c167ef6cca29853dee692becd2f78 (patch)
tree05d306c1a05921d9608495bd7aad03dc4a739ccd
parent1477a4f6677eeaa1993d58f296029f2df4ec7273 (diff)
parent45b074fab45cbb9888d1250abcc36b1b0af0150a (diff)
downloadbase-oreo-m6-s2-release.tar.gz
Merge cherrypicks of [4195294, 4195296, 4195440, 4195441, 4186165, 4186166, 4186580, 4195442, 4195443, 4186193, 4186194, 4186195, 4186196, 4186607, 4195444, 4195297, 4186608, 4186609, 4186610, 4186611, 4186612, 4186613, 4186614, 4186649, 4186650, 4186651, 4186652, 4186653, 4186654, 4186655, 4186656, 4186657, 4195518, 4195519, 4195520, 4195521, 4195522, 4186406, 4186407, 4186408, 4195523, 4195558, 4195559, 4186197, 4195524, 4186615, 4195445, 4195446, 4186829, 4186830, 4186831, 4186832, 4186833, 4186834, 4186835, 4186836, 4186837, 4195578, 4195579, 4195580, 4195581, 4195447, 4186581, 4195448, 4195560] into sparse-4749909-L06000000176800346android-8.1.0_r41oreo-m6-s2-release
Change-Id: I0c1d22050d3841fb9c8e11abf44e608f7c132326
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl10
-rw-r--r--core/java/android/app/Activity.java10
-rw-r--r--core/java/android/app/ActivityManagerInternal.java5
-rw-r--r--core/java/android/app/assist/AssistStructure.java10
-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--core/java/android/view/autofill/AutofillManager.java33
-rw-r--r--core/java/android/view/autofill/IAutoFillManager.aidl6
-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--proto/src/metrics_constants.proto13
-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/AutofillManagerService.java14
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java43
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java32
-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
30 files changed, 735 insertions, 228 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/Activity.java b/core/java/android/app/Activity.java
index 2c04f8ff9548..8dc558ccf755 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5872,6 +5872,16 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Temporary method on O-MR1 only.
+ *
+ * @hide
+ */
+ @Override
+ public ComponentName getComponentNameForAutofill() {
+ return mComponent;
+ }
+
+ /**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
* {@link #getSharedPreferences(String, int)} method by passing in this activity's
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/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 9383626360dc..bf715c35d9b7 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2058,6 +2058,16 @@ public class AssistStructure implements Parcelable {
return mActivityComponent;
}
+ /**
+ * Called by Autofill server when app forged a different value.
+ *
+ * @hide
+ */
+ public void setActivityComponent(ComponentName componentName) {
+ ensureData();
+ mActivityComponent = componentName;
+ }
+
/** @hide */
public int getFlags() {
return mFlags;
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/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 4fb2a99af575..fb9534b2e52e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -24,6 +24,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemService;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -44,6 +45,7 @@ import android.view.View;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -384,13 +386,20 @@ public final class AutofillManager {
* Runs the specified action on the UI thread.
*/
void runOnUiThread(Runnable action);
+
+ /**
+ * Gets the complete component name of this client.
+ *
+ * <p>Temporary method on O-MR1 only.
+ */
+ ComponentName getComponentNameForAutofill();
}
/**
* @hide
*/
public AutofillManager(Context context, IAutoFillManager service) {
- mContext = context;
+ mContext = Preconditions.checkNotNull(context, "context cannot be null");
mService = service;
}
@@ -940,6 +949,10 @@ public final class AutofillManager {
return mContext.getAutofillClient();
}
+ private ComponentName getComponentNameFromContext(AutofillClient client) {
+ return client == null ? null : client.getComponentNameForAutofill();
+ }
+
/** @hide */
public void onAuthenticationResult(int authenticationId, Intent data) {
if (!hasAutofillFeature()) {
@@ -990,13 +1003,18 @@ public final class AutofillManager {
return;
}
try {
+ final AutofillClient client = getClientLocked();
+ final ComponentName componentName = getComponentNameFromContext(client);
+ if (componentName == null) {
+ Log.w(TAG, "startSessionLocked(): context is not activity: " + mContext);
+ return;
+ }
mSessionId = mService.startSession(mContext.getActivityToken(),
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
- mCallback != null, flags, mContext.getOpPackageName());
+ mCallback != null, flags, componentName);
if (mSessionId != NO_SESSION) {
mState = STATE_ACTIVE;
}
- final AutofillClient client = getClientLocked();
if (client != null) {
client.autofillCallbackResetableStateAvailable();
}
@@ -1050,14 +1068,19 @@ public final class AutofillManager {
try {
if (restartIfNecessary) {
+ final AutofillClient client = getClientLocked();
+ final ComponentName componentName = getComponentNameFromContext(client);
+ if (componentName == null) {
+ Log.w(TAG, "startSessionLocked(): context is not activity: " + mContext);
+ return;
+ }
final int newId = mService.updateOrRestartSession(mContext.getActivityToken(),
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
- mCallback != null, flags, mContext.getOpPackageName(), mSessionId, action);
+ mCallback != null, flags, componentName, mSessionId, action);
if (newId != mSessionId) {
if (sDebug) Log.d(TAG, "Session restarted: " + mSessionId + "=>" + newId);
mSessionId = newId;
mState = (mSessionId == NO_SESSION) ? STATE_UNKNOWN : STATE_ACTIVE;
- final AutofillClient client = getClientLocked();
if (client != null) {
client.autofillCallbackResetableStateAvailable();
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 6bd9bec368c8..9329c4dcff6a 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -16,6 +16,7 @@
package android.view.autofill;
+import android.content.ComponentName;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.IBinder;
@@ -34,14 +35,15 @@ interface IAutoFillManager {
int addClient(in IAutoFillManagerClient client, int userId);
int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId,
in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags,
- String packageName);
+ in ComponentName componentName);
FillEventHistory getFillEventHistory();
boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
void updateSession(int sessionId, in AutofillId id, in Rect bounds,
in AutofillValue value, int action, int flags, int userId);
int updateOrRestartSession(IBinder activityToken, in IBinder appCallback,
in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
- boolean hasCallback, int flags, String packageName, int sessionId, int action);
+ boolean hasCallback, int flags, in ComponentName componentName, int sessionId,
+ int action);
void finishSession(int sessionId, int userId);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);
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/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index a27515c0266d..3cadff242e03 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4006,6 +4006,19 @@ message MetricsEvent {
// OS: O
FIELD_NOTIFICATION_GROUP_SUMMARY = 947;
+ // An app attempted to forge a different component name in the AssisStructure that would be
+ // passed to the autofill service.
+ // OS: O (security patch)
+ // Package: Real package of the app being autofilled
+ // Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request
+ // TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged
+ AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948;
+
+ // FIELD - The component that an app tried tro forged.
+ // Type: string
+ // OS: O (security patch)
+ FIELD_AUTOFILL_FORGED_COMPONENT_NAME = 949;
+
// ---- End O Constants, all O constants go above this line ----
// OPEN: Settings > System > Languages & input > Advanced > Lift to open camera
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/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 1f4161ac54d4..ffc778a8ee40 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -533,25 +533,26 @@ public final class AutofillManagerService extends SystemService {
@Override
public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId,
Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags,
- String packageName) {
+ ComponentName componentName) {
activityToken = Preconditions.checkNotNull(activityToken, "activityToken");
appCallback = Preconditions.checkNotNull(appCallback, "appCallback");
autofillId = Preconditions.checkNotNull(autofillId, "autoFillId");
- packageName = Preconditions.checkNotNull(packageName, "packageName");
+ componentName = Preconditions.checkNotNull(componentName, "componentName");
+ final String packageName = Preconditions.checkNotNull(componentName.getPackageName());
Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId");
try {
mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, userId);
} catch (PackageManager.NameNotFoundException e) {
- throw new IllegalArgumentException(packageName + " is not a valid package", e);
+ throw new IllegalArgumentException(componentName + " is not a valid package", e);
}
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
return service.startSessionLocked(activityToken, getCallingUid(), appCallback,
- autofillId, bounds, value, hasCallback, flags, packageName);
+ autofillId, bounds, value, hasCallback, flags, componentName);
}
}
@@ -603,7 +604,8 @@ public final class AutofillManagerService extends SystemService {
@Override
public int updateOrRestartSession(IBinder activityToken, IBinder appCallback,
AutofillId autoFillId, Rect bounds, AutofillValue value, int userId,
- boolean hasCallback, int flags, String packageName, int sessionId, int action) {
+ boolean hasCallback, int flags, ComponentName componentName, int sessionId,
+ int action) {
boolean restart = false;
synchronized (mLock) {
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
@@ -614,7 +616,7 @@ public final class AutofillManagerService extends SystemService {
}
if (restart) {
return startSession(activityToken, appCallback, autoFillId, bounds, value, userId,
- hasCallback, flags, packageName);
+ hasCallback, flags, componentName);
}
// Nothing changed...
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3a3b5707fc6f..6d3398ea2648 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -26,12 +26,14 @@ 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;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -43,6 +45,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.autofill.AutofillService;
@@ -67,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;
@@ -279,7 +283,7 @@ final class AutofillManagerServiceImpl {
int startSessionLocked(@NonNull IBinder activityToken, int uid,
@NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
@NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
- int flags, @NonNull String packageName) {
+ int flags, @NonNull ComponentName componentName) {
if (!isEnabled()) {
return 0;
}
@@ -289,7 +293,7 @@ final class AutofillManagerServiceImpl {
pruneAbandonedSessionsLocked();
final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
- hasCallback, packageName);
+ hasCallback, componentName);
if (newSession == null) {
return NO_SESSION;
}
@@ -386,7 +390,8 @@ final class AutofillManagerServiceImpl {
}
private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
- @NonNull IBinder appCallbackToken, boolean hasCallback, @NonNull String packageName) {
+ @NonNull IBinder appCallbackToken, boolean hasCallback,
+ @NonNull ComponentName componentName) {
// use random ids so that one app cannot know that another app creates sessions
int sessionId;
int tries = 0;
@@ -400,15 +405,45 @@ final class AutofillManagerServiceImpl {
sessionId = sRandom.nextInt();
} while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
+ assertCallerLocked(componentName);
+
final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
sessionId, uid, activityToken, appCallbackToken, hasCallback,
- mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), packageName);
+ mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), componentName);
mSessions.put(newSession.id, newSession);
return newSession;
}
/**
+ * 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(packageName, UserHandle.getCallingUserId());
+ } catch (NameNotFoundException e) {
+ throw new SecurityException("Could not verify UID for " + componentName);
+ }
+ 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
+ + ") passed component (" + componentName + ") owned by UID " + packageUid);
+ mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT)
+ .setPackageName(callingPackage)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
+ componentName == null ? "null" : componentName.flattenToShortString()));
+ throw new SecurityException("Invalid component: " + componentName);
+ }
+ }
+
+ /**
* Restores a session after an activity was temporarily destroyed.
*
* @param sessionId The id of the session to restore
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index de2950dd5985..1f0e51c694aa 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -126,8 +126,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@GuardedBy("mLock")
@NonNull private IBinder mActivityToken;
- /** Package name of the app that is auto-filled */
- @NonNull private final String mPackageName;
+ /** Component that's being auto-filled */
+ @NonNull private final ComponentName mComponentName;
@GuardedBy("mLock")
private final ArrayMap<AutofillId, ViewState> mViewStates = new ArrayMap<>();
@@ -227,6 +227,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
structure.ensureData();
// Sanitize structure before it's sent to service.
+ final ComponentName componentNameFromApp = structure.getActivityComponent();
+ if (!mComponentName.equals(componentNameFromApp)) {
+ Slog.w(TAG, "Activity " + mComponentName + " forged different component on "
+ + "AssistStructure: " + componentNameFromApp);
+ structure.setActivityComponent(mComponentName);
+ mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
+ componentNameFromApp == null ? "null"
+ : componentNameFromApp.flattenToShortString()));
+ }
structure.sanitizeForParceling(true);
// Flags used to start the session.
@@ -415,7 +425,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
@NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
@NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
- @NonNull ComponentName componentName, @NonNull String packageName) {
+ @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName) {
id = sessionId;
this.uid = uid;
mStartTime = SystemClock.elapsedRealtime();
@@ -423,11 +433,11 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
mLock = lock;
mUi = ui;
mHandlerCaller = handlerCaller;
- mRemoteFillService = new RemoteFillService(context, componentName, userId, this);
+ mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this);
mActivityToken = activityToken;
mHasCallback = hasCallback;
mUiLatencyHistory = uiLatencyHistory;
- mPackageName = packageName;
+ mComponentName = appComponentName;
mClient = IAutoFillManagerClient.Stub.asInterface(client);
writeLog(MetricsEvent.AUTOFILL_SESSION_STARTED);
@@ -1008,8 +1018,8 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
final IAutoFillManagerClient client = getClient();
mPendingSaveUi = new PendingUi(mActivityToken, id, client);
getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(),
- mService.getServicePackageName(), saveInfo, valueFinder, mPackageName, this,
- mPendingSaveUi);
+ mService.getServicePackageName(), saveInfo, valueFinder,
+ mComponentName.getPackageName(), this, mPendingSaveUi);
if (client != null) {
try {
client.setSaveUiState(id, true);
@@ -1365,7 +1375,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
getUiForShowing().showFillUi(filledId, response, filterText,
- mService.getServicePackageName(), mPackageName, this);
+ mService.getServicePackageName(), mComponentName.getPackageName(), this);
synchronized (mLock) {
if (mUiShownTime == 0) {
@@ -1690,14 +1700,14 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
@Override
public String toString() {
- return "Session: [id=" + id + ", pkg=" + mPackageName + "]";
+ return "Session: [id=" + id + ", pkg=" + mComponentName.getPackageName() + "]";
}
void dumpLocked(String prefix, PrintWriter pw) {
final String prefix2 = prefix + " ";
pw.print(prefix); pw.print("id: "); pw.println(id);
pw.print(prefix); pw.print("uid: "); pw.println(uid);
- pw.print(prefix); pw.print("mPackagename: "); pw.println(mPackageName);
+ pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName);
pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
pw.print(prefix); pw.print("mStartTime: "); pw.println(mStartTime);
pw.print(prefix); pw.print("Time to show UI: ");
@@ -1920,7 +1930,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
private LogMaker newLogMaker(int category, String servicePackageName) {
- return Helper.newLogMaker(category, mPackageName, servicePackageName);
+ return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName);
}
private void writeLog(int category) {
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