RESTRICT AUTOMERGE: Prevent reporting fake package name - framework (backport to nyc-dev)
Test: added AccessibilityEndToEndTest#testPackageNameCannotBeFaked
cts-tradefed run cts -m CtsAccessibilityServiceTestCases
cts-tradefed run cts -m CtsAccessibilityTestCases
Bug: 69981755
Change-Id: I187e3e9839f654cea9e06e5de93e10e4d1de3109
This commit is contained in:
@@ -35,22 +35,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);
|
||||
}
|
||||
@@ -155,6 +155,11 @@ public final class UserHandle implements Parcelable {
|
||||
return getUserId(Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static @AppIdInt int getCallingAppId() {
|
||||
return getAppId(Binder.getCallingUid());
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@SystemApi
|
||||
public static UserHandle of(@UserIdInt int userId) {
|
||||
|
||||
@@ -7258,6 +7258,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;
|
||||
@@ -283,16 +285,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);
|
||||
}
|
||||
}
|
||||
@@ -331,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;
|
||||
}
|
||||
}
|
||||
@@ -379,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;
|
||||
}
|
||||
}
|
||||
@@ -426,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 {
|
||||
@@ -470,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 {
|
||||
@@ -578,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 {
|
||||
@@ -694,13 +725,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,14 +752,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -570,7 +570,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) {
|
||||
@@ -581,7 +581,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);
|
||||
|
||||
|
||||
@@ -29,6 +29,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;
|
||||
@@ -69,6 +70,7 @@ import android.text.TextUtils;
|
||||
import android.text.TextUtils.SimpleStringSplitter;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.util.ArraySet;
|
||||
import android.view.Display;
|
||||
import android.view.IWindow;
|
||||
import android.view.InputDevice;
|
||||
@@ -92,9 +94,11 @@ import android.view.accessibility.IAccessibilityManagerClient;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.content.PackageMonitor;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.server.LocalServices;
|
||||
|
||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||
import libcore.util.EmptyArray;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -181,6 +185,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
|
||||
private final WindowManagerInternal mWindowManagerService;
|
||||
|
||||
private AppWidgetManagerInternal mAppWidgetService;
|
||||
|
||||
private final SecurityPolicy mSecurityPolicy;
|
||||
|
||||
private final MainHandler mMainHandler;
|
||||
@@ -207,7 +213,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<>();
|
||||
@@ -433,6 +439,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
|
||||
@@ -539,30 +550,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);
|
||||
@@ -591,7 +610,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;
|
||||
}
|
||||
@@ -615,13 +635,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;
|
||||
@@ -1963,18 +1983,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);
|
||||
}
|
||||
@@ -2500,26 +2537,26 @@ 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) {
|
||||
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(
|
||||
@@ -2529,13 +2566,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().");
|
||||
@@ -2543,34 +2582,34 @@ 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) {
|
||||
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(
|
||||
@@ -2580,13 +2619,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()");
|
||||
@@ -2594,34 +2635,34 @@ 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) {
|
||||
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(
|
||||
@@ -2631,13 +2672,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()");
|
||||
@@ -2645,35 +2688,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 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) {
|
||||
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(
|
||||
@@ -2683,13 +2726,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()");
|
||||
@@ -2697,34 +2742,34 @@ 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) {
|
||||
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(
|
||||
@@ -2734,13 +2779,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()");
|
||||
@@ -2748,11 +2795,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
|
||||
@@ -2799,7 +2846,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
|
||||
throws RemoteException {
|
||||
final int resolvedWindowId;
|
||||
IAccessibilityInteractionConnection connection = null;
|
||||
RemoteAccessibilityConnection connection;
|
||||
synchronized (mLock) {
|
||||
if (!isCalledForCurrentUserLocked()) {
|
||||
return false;
|
||||
@@ -2824,8 +2871,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub {
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(),
|
||||
PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY, 0);
|
||||
|
||||
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()");
|
||||
@@ -3372,16 +3420,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);
|
||||
@@ -3493,6 +3541,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 {
|
||||
|
||||
@@ -3758,6 +3816,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;
|
||||
@@ -4156,7 +4286,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<>();
|
||||
|
||||
@@ -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.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -89,6 +90,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;
|
||||
@@ -97,6 +99,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;
|
||||
@@ -240,6 +243,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
|
||||
computeMaximumWidgetBitmapMemory();
|
||||
registerBroadcastReceiver();
|
||||
registerOnCrossProfileProvidersChangedListener();
|
||||
|
||||
LocalServices.addService(AppWidgetManagerInternal.class, new AppWidgetManagerLocal());
|
||||
}
|
||||
|
||||
private void computeMaximumWidgetBitmapMemory() {
|
||||
@@ -4551,4 +4556,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