[automerger] RESTRICT AUTOMERGE: Prevent reporting fake package name - framework (backport to mnc-dev) am: de71ee469a am: d672eef559
Change-Id: Ib50692050fd4e62ad80f24531818a378c75dfe25
This commit is contained in:
@@ -32,22 +32,22 @@ 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);
|
||||
|
||||
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,
|
||||
|
||||
39
core/java/android/appwidget/AppWidgetManagerInternal.java
Normal file
39
core/java/android/appwidget/AppWidgetManagerInternal.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -129,6 +129,11 @@ public final class UserHandle implements Parcelable {
|
||||
return getUserId(Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final int getCallingAppId() {
|
||||
return getAppId(Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final UserHandle getCallingUserHandle() {
|
||||
int userId = getUserId(Binder.getCallingUid());
|
||||
|
||||
@@ -6981,6 +6981,7 @@ public final class ViewRootImpl implements ViewParent,
|
||||
if (!registered) {
|
||||
mAttachInfo.mAccessibilityWindowId =
|
||||
mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
|
||||
mContext.getPackageName(),
|
||||
new AccessibilityInteractionConnection(ViewRootImpl.this));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -287,16 +289,23 @@ 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());
|
||||
Binder.restoreCallingIdentity(identityToken);
|
||||
// If the scale is zero the call has failed.
|
||||
if (success) {
|
||||
final String[] packageNames;
|
||||
try {
|
||||
packageNames = connection.findAccessibilityNodeInfoByAccessibilityId(
|
||||
accessibilityWindowId, accessibilityNodeId, interactionId, this,
|
||||
prefetchFlags, Thread.currentThread().getId());
|
||||
} 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();
|
||||
}
|
||||
return infos.get(0);
|
||||
}
|
||||
}
|
||||
@@ -335,15 +344,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;
|
||||
}
|
||||
}
|
||||
@@ -383,15 +398,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;
|
||||
}
|
||||
}
|
||||
@@ -430,14 +451,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 {
|
||||
@@ -474,14 +500,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 {
|
||||
@@ -582,7 +613,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 {
|
||||
@@ -698,13 +729,25 @@ 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)
|
||||
&& !ArrayUtils.contains(packageNames, info.getPackageName().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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,14 +756,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,7 +571,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) {
|
||||
@@ -582,7 +582,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);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ interface IAccessibilityManager {
|
||||
void interrupt(int userId);
|
||||
|
||||
int addAccessibilityInteractionConnection(IWindow windowToken,
|
||||
in IAccessibilityInteractionConnection connection, int userId);
|
||||
in IAccessibilityInteractionConnection connection, String packageName, int userId);
|
||||
|
||||
void removeAccessibilityInteractionConnection(IWindow windowToken);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.accessibilityservice.IAccessibilityServiceConnection;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.StatusBarManager;
|
||||
import android.appwidget.AppWidgetManagerInternal;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
@@ -63,6 +64,7 @@ import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextUtils.SimpleStringSplitter;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Pools.Pool;
|
||||
import android.util.Pools.SimplePool;
|
||||
import android.util.Slog;
|
||||
@@ -91,9 +93,11 @@ import android.view.accessibility.IAccessibilityManagerClient;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -176,6 +180,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
|
||||
private final WindowManagerInternal mWindowManagerService;
|
||||
|
||||
private AppWidgetManagerInternal mAppWidgetService;
|
||||
|
||||
private final SecurityPolicy mSecurityPolicy;
|
||||
|
||||
private final MainHandler mMainHandler;
|
||||
@@ -196,7 +202,7 @@ 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 final SparseArray<IBinder> mGlobalWindowTokens = new SparseArray<>();
|
||||
@@ -422,6 +428,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) {
|
||||
return true; // yes, recycle the event
|
||||
@@ -529,30 +540,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);
|
||||
@@ -581,7 +600,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;
|
||||
}
|
||||
@@ -605,13 +625,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;
|
||||
@@ -1714,18 +1734,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);
|
||||
}
|
||||
@@ -2233,12 +2270,12 @@ 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();
|
||||
synchronized (mLock) {
|
||||
// We treat calls from a profile as if made by its parent as profiles
|
||||
@@ -2248,17 +2285,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
.resolveCallingUserIdEnforcingPermissionsLocked(
|
||||
UserHandle.USER_CURRENT);
|
||||
if (resolvedUserId != mCurrentUserId) {
|
||||
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(
|
||||
@@ -2268,13 +2305,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
|
||||
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().");
|
||||
@@ -2282,20 +2321,20 @@ 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();
|
||||
synchronized (mLock) {
|
||||
// We treat calls from a profile as if made by its parent as profiles
|
||||
@@ -2305,17 +2344,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
.resolveCallingUserIdEnforcingPermissionsLocked(
|
||||
UserHandle.USER_CURRENT);
|
||||
if (resolvedUserId != mCurrentUserId) {
|
||||
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(
|
||||
@@ -2325,13 +2364,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
|
||||
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()");
|
||||
@@ -2339,20 +2380,20 @@ 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) throws RemoteException {
|
||||
final int resolvedWindowId;
|
||||
IAccessibilityInteractionConnection connection = null;
|
||||
RemoteAccessibilityConnection connection = null;
|
||||
Region partialInteractiveRegion = Region.obtain();
|
||||
synchronized (mLock) {
|
||||
// We treat calls from a profile as if made by its parent as profiles
|
||||
@@ -2362,17 +2403,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
.resolveCallingUserIdEnforcingPermissionsLocked(
|
||||
UserHandle.USER_CURRENT);
|
||||
if (resolvedUserId != mCurrentUserId) {
|
||||
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(
|
||||
@@ -2382,13 +2423,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
|
||||
try {
|
||||
connection.findAccessibilityNodeInfoByAccessibilityId(accessibilityNodeId,
|
||||
partialInteractiveRegion, interactionId, callback, mFetchFlags | flags,
|
||||
interrogatingPid, interrogatingTid, spec);
|
||||
return true;
|
||||
connection.getRemote().findAccessibilityNodeInfoByAccessibilityId(
|
||||
accessibilityNodeId, partialInteractiveRegion, interactionId, callback,
|
||||
mFetchFlags | flags, interrogatingPid, interrogatingTid, spec);
|
||||
return mSecurityPolicy.computeValidReportedPackages(callingUid,
|
||||
connection.getPackageName(), connection.getUid());
|
||||
} catch (RemoteException re) {
|
||||
if (DEBUG) {
|
||||
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
|
||||
@@ -2396,20 +2439,20 @@ 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();
|
||||
synchronized (mLock) {
|
||||
// We treat calls from a profile as if made by its parent as profiles
|
||||
@@ -2419,18 +2462,18 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
.resolveCallingUserIdEnforcingPermissionsLocked(
|
||||
UserHandle.USER_CURRENT);
|
||||
if (resolvedUserId != mCurrentUserId) {
|
||||
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(
|
||||
@@ -2440,13 +2483,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
|
||||
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()");
|
||||
@@ -2454,20 +2499,20 @@ 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();
|
||||
synchronized (mLock) {
|
||||
// We treat calls from a profile as if made by its parent as profiles
|
||||
@@ -2477,17 +2522,17 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
.resolveCallingUserIdEnforcingPermissionsLocked(
|
||||
UserHandle.USER_CURRENT);
|
||||
if (resolvedUserId != mCurrentUserId) {
|
||||
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(
|
||||
@@ -2497,13 +2542,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
MagnificationSpec spec = getCompatibleMagnificationSpecLocked(resolvedWindowId);
|
||||
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()");
|
||||
@@ -2511,11 +2558,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
|
||||
@@ -2524,7 +2571,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
|
||||
throws RemoteException {
|
||||
final int resolvedWindowId;
|
||||
IAccessibilityInteractionConnection connection = null;
|
||||
RemoteAccessibilityConnection connection;
|
||||
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
|
||||
@@ -2550,8 +2597,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
final int interrogatingPid = Binder.getCallingPid();
|
||||
final long identityToken = Binder.clearCallingIdentity();
|
||||
try {
|
||||
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()");
|
||||
@@ -2894,16 +2942,16 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
mWindowManagerService.showGlobalActions();
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -3109,6 +3157,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 {
|
||||
|
||||
@@ -3367,6 +3425,78 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidPackageForUid(String packageName, int uid) {
|
||||
try {
|
||||
return uid == mPackageManager.getPackageUid(
|
||||
packageName, UserHandle.getUserId(uid));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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<AccessibilityWindowInfo> windows = Collections.emptyList();
|
||||
final int activeWindowId = mActiveWindowId;
|
||||
@@ -3751,7 +3881,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
public final RemoteCallbackList<IAccessibilityManagerClient> mClients =
|
||||
new RemoteCallbackList<>();
|
||||
|
||||
public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
|
||||
public final SparseArray<RemoteAccessibilityConnection> mInteractionConnections =
|
||||
new SparseArray<>();
|
||||
|
||||
public final SparseArray<IBinder> mWindowTokens = new SparseArray<>();
|
||||
|
||||
@@ -23,6 +23,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.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -76,6 +77,7 @@ import com.android.internal.appwidget.IAppWidgetHost;
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.internal.util.FastXmlSerializer;
|
||||
import com.android.internal.widget.IRemoteViewsAdapterConnection;
|
||||
import com.android.internal.widget.IRemoteViewsFactory;
|
||||
@@ -83,6 +85,7 @@ import com.android.internal.widget.IRemoteViewsFactory;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.WidgetBackupProvider;
|
||||
import libcore.io.IoUtils;
|
||||
import libcore.util.EmptyArray;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
@@ -210,6 +213,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
computeMaximumWidgetBitmapMemory();
|
||||
registerBroadcastReceiver();
|
||||
registerOnCrossProfileProvidersChangedListener();
|
||||
|
||||
LocalServices.addService(AppWidgetManagerInternal.class, new AppWidgetManagerLocal());
|
||||
}
|
||||
|
||||
private void computeMaximumWidgetBitmapMemory() {
|
||||
@@ -4175,4 +4180,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user