Merge "Notify WifiManager of interface state changes" into oc-dev
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 0ad790b..3353530 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -64,6 +64,7 @@
ComponentName mActivityComponent;
private boolean mIsHomeActivity;
+ private int mFlags;
final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
@@ -186,6 +187,7 @@
mSanitizeOnWrite = as.mSanitizeOnWrite;
mWriteStructure = as.waitForReady();
ComponentName.writeToParcel(as.mActivityComponent, out);
+ out.writeInt(as.mFlags);
out.writeLong(as.mAcquisitionStartTime);
out.writeLong(as.mAcquisitionEndTime);
mNumWindows = as.mWindowNodes.size();
@@ -340,6 +342,7 @@
void go() {
fetchData();
mActivityComponent = ComponentName.readFromParcel(mCurParcel);
+ mFlags = mCurParcel.readInt();
mAcquisitionStartTime = mCurParcel.readLong();
mAcquisitionEndTime = mCurParcel.readLong();
final int N = mCurParcel.readInt();
@@ -1876,6 +1879,7 @@
public AssistStructure(Activity activity, boolean forAutoFill, int flags) {
mHaveData = true;
mActivityComponent = activity.getComponentName();
+ mFlags = flags;
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
activity.getActivityToken());
for (int i=0; i<views.size(); i++) {
@@ -1887,6 +1891,7 @@
public AssistStructure() {
mHaveData = true;
mActivityComponent = null;
+ mFlags = 0;
}
/** @hide */
@@ -1913,6 +1918,7 @@
}
Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
Log.i(TAG, "Sanitize on write: " + mSanitizeOnWrite);
+ Log.i(TAG, "Flags: " + mFlags);
final int N = getWindowNodeCount();
for (int i=0; i<N; i++) {
WindowNode node = getWindowNodeAt(i);
@@ -2025,6 +2031,11 @@
return mActivityComponent;
}
+ /** @hide */
+ public int getFlags() {
+ return mFlags;
+ }
+
/**
* Returns whether the activity associated with this AssistStructure was the home activity
* (Launcher) at the time the assist data was acquired.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e4db0f0..a05f11b 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -547,6 +547,8 @@
*/
public interface Callback {
boolean hasFeature(String feature);
+ String[] getOverlayPaths(String targetPackageName, String targetPath);
+ String[] getOverlayApks(String targetPackageName);
}
/**
@@ -563,6 +565,14 @@
@Override public boolean hasFeature(String feature) {
return mPm.hasSystemFeature(feature);
}
+
+ @Override public String[] getOverlayPaths(String targetPackageName, String targetPath) {
+ return null;
+ }
+
+ @Override public String[] getOverlayApks(String targetPackageName) {
+ return null;
+ }
}
/**
@@ -1054,7 +1064,19 @@
try {
final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath());
- return fromCacheEntry(bytes);
+ Package p = fromCacheEntry(bytes);
+ if (mCallback != null) {
+ String[] overlayApks = mCallback.getOverlayApks(p.packageName);
+ if (overlayApks != null && overlayApks.length > 0) {
+ for (String overlayApk : overlayApks) {
+ // If a static RRO is updated, return null.
+ if (!isCacheUpToDate(new File(overlayApk), cacheFile)) {
+ return null;
+ }
+ }
+ }
+ }
+ return p;
} catch (Exception e) {
Slog.w(TAG, "Error reading package cache: ", e);
@@ -1238,7 +1260,7 @@
parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);
final String[] outError = new String[1];
- final Package pkg = parseBaseApk(res, parser, flags, outError);
+ final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError);
if (pkg == null) {
throw new PackageParserException(mParseError,
apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
@@ -1938,6 +1960,7 @@
* need to consider whether they should be supported by split APKs and child
* packages.
*
+ * @param apkPath The package apk file path
* @param res The resources from which to resolve values
* @param parser The manifest parser
* @param flags Flags how to parse
@@ -1947,7 +1970,7 @@
* @throws XmlPullParserException
* @throws IOException
*/
- private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags,
+ private Package parseBaseApk(String apkPath, Resources res, XmlResourceParser parser, int flags,
String[] outError) throws XmlPullParserException, IOException {
final String splitName;
final String pkgName;
@@ -1967,6 +1990,15 @@
return null;
}
+ if (mCallback != null) {
+ String[] overlayPaths = mCallback.getOverlayPaths(pkgName, apkPath);
+ if (overlayPaths != null && overlayPaths.length > 0) {
+ for (String overlayPath : overlayPaths) {
+ res.getAssets().addOverlayPath(overlayPath);
+ }
+ }
+ }
+
final Package pkg = new Package(pkgName);
TypedArray sa = res.obtainAttributes(parser,
diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java
index 8a28c45..e482c78 100644
--- a/core/java/android/service/autofill/FillContext.java
+++ b/core/java/android/service/autofill/FillContext.java
@@ -74,11 +74,9 @@
@Override
public String toString() {
- if (!DEBUG) {
- return super.toString();
- } else {
- return "FillContext [mRequestId=" + mRequestId + "]";
- }
+ if (!DEBUG) return super.toString();
+
+ return "FillContext [reqId=" + mRequestId + "]";
}
@Override
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 2c8e43e..b1c9d69 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -107,11 +107,10 @@
@Deprecated
public static final int FLAG_MANUAL_REQUEST = 0x1;
- // TODO(b/37563972): start from 0x1 once FLAG_MANUAL_REQUEST is gone
- /** @hide */ public static final int FLAG_START_SESSION = 0x80000000;
- /** @hide */ public static final int FLAG_VIEW_ENTERED = 0x40000000;
- /** @hide */ public static final int FLAG_VIEW_EXITED = 0x20000000;
- /** @hide */ public static final int FLAG_VALUE_CHANGED = 0x10000000;
+ /** @hide */ public static final int ACTION_START_SESSION = 1;
+ /** @hide */ public static final int ACTION_VIEW_ENTERED = 2;
+ /** @hide */ public static final int ACTION_VIEW_EXITED = 3;
+ /** @hide */ public static final int ACTION_VALUE_CHANGED = 4;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
@@ -404,7 +403,7 @@
startSessionLocked(id, view.getWindowToken(), null, value, flags);
} else {
// Update focus on existing session.
- updateSessionLocked(id, null, value, FLAG_VIEW_ENTERED);
+ updateSessionLocked(id, null, value, ACTION_VIEW_ENTERED, flags);
}
}
}
@@ -430,7 +429,7 @@
final AutofillId id = getAutofillId(view);
// Update focus on existing session.
- updateSessionLocked(id, null, null, FLAG_VIEW_EXITED);
+ updateSessionLocked(id, null, null, ACTION_VIEW_EXITED, 0);
}
}
}
@@ -482,7 +481,7 @@
startSessionLocked(id, view.getWindowToken(), bounds, null, flags);
} else {
// Update focus on existing session.
- updateSessionLocked(id, bounds, null, FLAG_VIEW_ENTERED);
+ updateSessionLocked(id, bounds, null, ACTION_VIEW_ENTERED, flags);
}
}
}
@@ -510,7 +509,7 @@
final AutofillId id = getAutofillId(view, childId);
// Update focus on existing session.
- updateSessionLocked(id, null, null, FLAG_VIEW_EXITED);
+ updateSessionLocked(id, null, null, ACTION_VIEW_EXITED, 0);
}
}
}
@@ -562,7 +561,7 @@
value = view.getAutofillValue();
}
- updateSessionLocked(id, null, value, FLAG_VALUE_CHANGED);
+ updateSessionLocked(id, null, value, ACTION_VALUE_CHANGED, 0);
}
}
@@ -583,7 +582,7 @@
}
final AutofillId id = getAutofillId(view, childId);
- updateSessionLocked(id, null, value, FLAG_VALUE_CHANGED);
+ updateSessionLocked(id, null, value, ACTION_VALUE_CHANGED, 0);
}
}
@@ -726,7 +725,7 @@
mSessionId = mService.startSession(mContext.getActivityToken(), windowToken,
mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
mCallback != null, flags, mContext.getOpPackageName());
- AutofillClient client = getClientLocked();
+ final AutofillClient client = getClientLocked();
if (client != null) {
client.autofillCallbackResetableStateAvailable();
}
@@ -769,16 +768,18 @@
mTrackedViews = null;
}
- private void updateSessionLocked(AutofillId id, Rect bounds, AutofillValue value, int flags) {
+ private void updateSessionLocked(AutofillId id, Rect bounds, AutofillValue value, int action,
+ int flags) {
if (DEBUG) {
- if (VERBOSE || (flags & FLAG_VIEW_EXITED) != 0) {
+ if (VERBOSE || action != ACTION_VIEW_EXITED) {
Log.d(TAG, "updateSessionLocked(): id=" + id + ", bounds=" + bounds
- + ", value=" + value + ", flags=" + flags);
+ + ", value=" + value + ", action=" + action + ", flags=" + flags);
}
}
try {
- mService.updateSession(mSessionId, id, bounds, value, flags, mContext.getUserId());
+ mService.updateSession(mSessionId, id, bounds, value, action, flags,
+ mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 9417bd0..6e121ac 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -38,7 +38,7 @@
boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback);
void setWindow(int sessionId, in IBinder windowToken);
void updateSession(int sessionId, in AutofillId id, in Rect bounds,
- in AutofillValue value, int flags, int userId);
+ in AutofillValue value, int action, int flags, int userId);
void finishSession(int sessionId, int userId);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int userId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 8a20c85..8d65ded 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -509,12 +509,12 @@
@Override
public void updateSession(int sessionId, AutofillId id, Rect bounds,
- AutofillValue value, int flags, int userId) {
+ AutofillValue value, int action, int flags, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
service.updateSessionLocked(sessionId, getCallingUid(), id, bounds, value,
- flags);
+ action, flags);
}
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 44a296e..500ddb2 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -16,7 +16,7 @@
package com.android.server.autofill;
-import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
+import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
import static android.view.autofill.AutofillManager.NO_SESSION;
import static com.android.server.autofill.Helper.DEBUG;
@@ -271,14 +271,14 @@
}
final String historyItem =
- "id=" + newSession.getId() + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
+ "id=" + newSession.id + " uid=" + uid + " s=" + mInfo.getServiceInfo().packageName
+ " u=" + mUserId + " i=" + autofillId + " b=" + virtualBounds + " hc=" +
hasCallback + " f=" + flags;
mRequestsHistory.log(historyItem);
- newSession.updateLocked(autofillId, virtualBounds, value, FLAG_START_SESSION);
+ newSession.updateLocked(autofillId, virtualBounds, value, ACTION_START_SESSION, flags);
- return newSession.getId();
+ return newSession.id;
}
void finishSessionLocked(int sessionId, int uid) {
@@ -350,9 +350,9 @@
} while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
- sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback, flags,
+ sessionId, uid, activityToken, windowToken, appCallbackToken, hasCallback,
mInfo.getServiceInfo().getComponentName(), packageName);
- mSessions.put(newSession.getId(), newSession);
+ mSessions.put(newSession.id, newSession);
return newSession;
}
@@ -396,7 +396,7 @@
}
void updateSessionLocked(int sessionId, int uid, AutofillId autofillId, Rect virtualBounds,
- AutofillValue value, int flags) {
+ AutofillValue value, int action, int flags) {
final Session session = mSessions.get(sessionId);
if (session == null || session.uid != uid) {
if (VERBOSE) {
@@ -406,7 +406,7 @@
return;
}
- session.updateLocked(autofillId, virtualBounds, value, flags);
+ session.updateLocked(autofillId, virtualBounds, value, action, flags);
}
void removeSessionLocked(int sessionId) {
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 2aeb07e..f6831b2 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -89,7 +89,7 @@
private PendingRequest mPendingRequest;
public interface FillServiceCallbacks {
- void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
+ void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response, int serviceUid,
@NonNull String servicePackageName);
void onFillRequestFailure(@Nullable CharSequence message,
@NonNull String servicePackageName);
@@ -281,10 +281,10 @@
}
private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
- int callingUid, FillResponse response) {
+ int callingUid, int requestFlags, FillResponse response) {
mHandler.getHandler().post(() -> {
if (handleResponseCallbackCommon(pendingRequest)) {
- mCallbacks.onFillRequestSuccess(response, callingUid,
+ mCallbacks.onFillRequestSuccess(requestFlags, response, callingUid,
mComponentName.getPackageName());
}
});
@@ -452,8 +452,8 @@
public void onSuccess(FillResponse response) {
RemoteFillService remoteService = mWeakService.get();
if (remoteService != null) {
- remoteService.dispatchOnFillRequestSuccess(
- PendingFillRequest.this, getCallingUid(), response);
+ remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this,
+ getCallingUid(), request.getFlags(), response);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 5a32274..eb95684 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -20,10 +20,10 @@
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
import static android.service.voice.VoiceInteractionSession.KEY_RECEIVER_EXTRAS;
import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
-import static android.view.autofill.AutofillManager.FLAG_START_SESSION;
-import static android.view.autofill.AutofillManager.FLAG_VALUE_CHANGED;
-import static android.view.autofill.AutofillManager.FLAG_VIEW_ENTERED;
-import static android.view.autofill.AutofillManager.FLAG_VIEW_EXITED;
+import static android.view.autofill.AutofillManager.ACTION_START_SESSION;
+import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
+import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
+import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
import static com.android.server.autofill.Helper.DEBUG;
import static com.android.server.autofill.Helper.VERBOSE;
@@ -108,7 +108,7 @@
private static AtomicInteger sIdCounter = new AtomicInteger();
/** Id of the session */
- private final int mId;
+ public final int id;
/** uid the session is for */
public final int uid;
@@ -174,23 +174,14 @@
private boolean mDestroyed;
/**
- * Flags used to start the session.
- */
- private final int mFlags;
-
- /**
* Receiver of assist data from the app's {@link Activity}.
*/
private final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
@Override
public void send(int resultCode, Bundle resultData) throws RemoteException {
- if (VERBOSE) {
- Slog.v(TAG, "resultCode on mAssistReceiver: " + resultCode);
- }
-
final AssistStructure structure = resultData.getParcelable(KEY_STRUCTURE);
if (structure == null) {
- Slog.wtf(TAG, "no assist structure for id " + resultCode);
+ Slog.wtf(TAG, "no assist structure");
return;
}
@@ -218,6 +209,9 @@
// Sanitize structure before it's sent to service.
structure.sanitizeForParceling(true);
+ // Flags used to start the session.
+ final int flags = structure.getFlags();
+
if (mContexts == null) {
mContexts = new ArrayList<>(1);
}
@@ -230,7 +224,7 @@
fillStructureWithAllowedValues(mContexts.get(i).getStructure());
}
- request = new FillRequest(requestId, mContexts, mClientState, mFlags);
+ request = new FillRequest(requestId, mContexts, mClientState, flags);
}
mRemoteFillService.onFillRequest(request);
@@ -295,7 +289,7 @@
/**
* Reads a new structure and then request a new fill response from the fill service.
*/
- private void requestNewFillResponseLocked() {
+ private void requestNewFillResponseLocked(int flags) {
int requestId;
do {
@@ -303,7 +297,7 @@
} while (requestId == INVALID_REQUEST_ID);
if (DEBUG) {
- Slog.d(TAG, "Requesting structure for requestId " + requestId);
+ Slog.d(TAG, "Requesting structure for requestId=" + requestId + ", flags=" + flags);
}
// If the focus changes very quickly before the first request is returned each focus change
@@ -319,7 +313,7 @@
final long identity = Binder.clearCallingIdentity();
try {
if (!ActivityManager.getService().requestAutofillData(mAssistReceiver,
- receiverExtras, mActivityToken, mFlags)) {
+ receiverExtras, mActivityToken, flags)) {
Slog.w(TAG, "failed to request autofill data for " + mActivityToken);
}
} finally {
@@ -334,8 +328,8 @@
@NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
@NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
@Nullable IBinder windowToken, @NonNull IBinder client, boolean hasCallback,
- int flags, @NonNull ComponentName componentName, @NonNull String packageName) {
- mId = sessionId;
+ @NonNull ComponentName componentName, @NonNull String packageName) {
+ id = sessionId;
this.uid = uid;
mService = service;
mLock = lock;
@@ -346,7 +340,6 @@
mWindowToken = windowToken;
mHasCallback = hasCallback;
mPackageName = packageName;
- mFlags = flags;
mClient = IAutoFillManagerClient.Stub.asInterface(client);
mMetricsLogger.action(MetricsEvent.AUTOFILL_SESSION_STARTED, mPackageName);
@@ -371,7 +364,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#switchWindow() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
mWindowToken = newWindow;
@@ -388,7 +381,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#switchActivity() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
mActivityToken = newActivity;
@@ -401,17 +394,17 @@
// FillServiceCallbacks
@Override
- public void onFillRequestSuccess(@Nullable FillResponse response, int serviceUid,
- @NonNull String servicePackageName) {
+ public void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response,
+ int serviceUid, @NonNull String servicePackageName) {
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
if (response == null) {
- if ((mFlags & FLAG_MANUAL_REQUEST) != 0) {
+ if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
getUiForShowing().showError(R.string.autofill_error_cannot_autofill);
}
// Nothing to be done, but need to notify client.
@@ -452,7 +445,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onFillRequestFailure() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -472,7 +465,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onSaveRequestSuccess() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -494,7 +487,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onSaveRequestFailure() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -541,7 +534,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#authenticate() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -566,7 +559,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#fill() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -579,12 +572,12 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#save() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
mHandlerCaller.getHandler()
- .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, mId, 0)
+ .obtainMessage(AutofillManagerServiceImpl.MSG_SERVICE_SAVE, id, 0)
.sendToTarget();
}
@@ -594,7 +587,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#cancelSave() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -608,13 +601,13 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#requestShowFillUi() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
if (id.equals(mCurrentViewId)) {
try {
final ViewState view = mViewStates.get(id);
- mClient.requestShowFillUi(mId, mWindowToken, id, width, height,
+ mClient.requestShowFillUi(this.id, mWindowToken, id, width, height,
view.getVirtualBounds(), presenter);
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to show fill UI", e);
@@ -635,7 +628,7 @@
// NOTE: We allow this call in a destroyed state as the UI is
// asked to go away after we get destroyed, so let it do that.
try {
- mClient.requestHideFillUi(mId, mWindowToken, id);
+ mClient.requestHideFillUi(this.id, mWindowToken, id);
} catch (RemoteException e) {
Slog.e(TAG, "Error requesting to hide fill UI", e);
}
@@ -648,7 +641,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#startIntentSender() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
removeSelfLocked();
@@ -667,7 +660,7 @@
void setAuthenticationResultLocked(Bundle data) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#setAuthenticationResultLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
@@ -707,7 +700,7 @@
void setHasCallbackLocked(boolean hasIt) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#setHasCallbackLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
mHasCallback = hasIt;
@@ -721,7 +714,7 @@
public boolean showSaveLocked() {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#showSaveLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return false;
}
if (mContexts == null) {
@@ -845,7 +838,7 @@
void callSaveLocked() {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#callSaveLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
@@ -932,7 +925,7 @@
final int numDatasets = datasets.size();
for (int dataSetNum = 0; dataSetNum < numDatasets; dataSetNum++) {
- final ArrayList fields = datasets.get(dataSetNum).getFieldIds();
+ final ArrayList<AutofillId> fields = datasets.get(dataSetNum).getFieldIds();
if (fields != null && fields.contains(id)) {
return false;
@@ -944,96 +937,92 @@
return true;
}
- void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
+ void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int action,
+ int flags) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#updateLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
ViewState viewState = mViewStates.get(id);
if (viewState == null) {
- if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED | FLAG_VIEW_ENTERED)) != 0) {
+ if (action == ACTION_START_SESSION || action == ACTION_VALUE_CHANGED
+ || action == ACTION_VIEW_ENTERED) {
if (DEBUG) {
- Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
+ Slog.d(TAG,
+ "Creating viewState for " + id + " on " + getActionAsString(action));
}
viewState = new ViewState(this, id, value, this, ViewState.STATE_INITIAL);
mViewStates.put(id, viewState);
} else {
- if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
+ if (VERBOSE) Slog.v(TAG, "Ignored " + getActionAsString(action) + " for " + id);
return;
}
}
- if ((flags & FLAG_START_SESSION) != 0) {
- // View is triggering autofill.
- mCurrentViewId = viewState.id;
- viewState.update(value, virtualBounds);
- viewState.setState(ViewState.STATE_STARTED_SESSION);
- requestNewFillResponseLocked();
- return;
- }
-
- if ((flags & FLAG_VALUE_CHANGED) != 0) {
- if (value != null && !value.equals(viewState.getCurrentValue())) {
- // Always update the internal state.
- viewState.setCurrentValue(value);
-
- // Must check if this update was caused by autofilling the view, in which
- // case we just update the value, but not the UI.
- final AutofillValue filledValue = viewState.getAutofilledValue();
- if (value.equals(filledValue)) {
- return;
- }
- // Update the internal state...
- viewState.setState(ViewState.STATE_CHANGED);
-
- //..and the UI
- if (value.isText()) {
- getUiForShowing().filterFillUi(value.getTextValue().toString());
- } else {
- getUiForShowing().filterFillUi(null);
- }
- }
-
- return;
- }
-
- if ((flags & FLAG_VIEW_ENTERED) != 0) {
- if (shouldStartNewPartitionLocked(id)) {
- // TODO(b/37424539): proper implementation
- if (mResponseWaitingAuth != null && ((flags & FLAG_START_SESSION) == 0)) {
- viewState.setState(ViewState.STATE_WAITING_RESPONSE_AUTH);
- } else if ((flags & FLAG_START_SESSION) == 0){
- if (DEBUG) {
- Slog.d(TAG, "Starting partition for view id " + viewState.id);
- }
- viewState.setState(ViewState.STATE_STARTED_PARTITION);
- requestNewFillResponseLocked();
- }
- }
-
- // Remove the UI if the ViewState has changed.
- if (mCurrentViewId != viewState.id) {
- mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
+ switch(action) {
+ case ACTION_START_SESSION:
+ // View is triggering autofill.
mCurrentViewId = viewState.id;
- }
+ viewState.update(value, virtualBounds);
+ viewState.setState(ViewState.STATE_STARTED_SESSION);
+ requestNewFillResponseLocked(flags);
+ break;
+ case ACTION_VALUE_CHANGED:
+ if (value != null && !value.equals(viewState.getCurrentValue())) {
+ // Always update the internal state.
+ viewState.setCurrentValue(value);
- // If the ViewState is ready to be displayed, onReady() will be called.
- viewState.update(value, virtualBounds);
+ // Must check if this update was caused by autofilling the view, in which
+ // case we just update the value, but not the UI.
+ final AutofillValue filledValue = viewState.getAutofilledValue();
+ if (value.equals(filledValue)) {
+ return;
+ }
+ // Update the internal state...
+ viewState.setState(ViewState.STATE_CHANGED);
- return;
+ //..and the UI
+ if (value.isText()) {
+ getUiForShowing().filterFillUi(value.getTextValue().toString());
+ } else {
+ getUiForShowing().filterFillUi(null);
+ }
+ }
+ break;
+ case ACTION_VIEW_ENTERED:
+ if (shouldStartNewPartitionLocked(id)) {
+ // TODO(b/37424539): proper implementation
+ if (mResponseWaitingAuth != null) {
+ viewState.setState(ViewState.STATE_WAITING_RESPONSE_AUTH);
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "Starting partition for view id " + viewState.id);
+ }
+ viewState.setState(ViewState.STATE_STARTED_PARTITION);
+ requestNewFillResponseLocked(flags);
+ }
+ }
+
+ // Remove the UI if the ViewState has changed.
+ if (mCurrentViewId != viewState.id) {
+ mUi.hideFillUi(mCurrentViewId != null ? mCurrentViewId : null);
+ mCurrentViewId = viewState.id;
+ }
+
+ // If the ViewState is ready to be displayed, onReady() will be called.
+ viewState.update(value, virtualBounds);
+ break;
+ case ACTION_VIEW_EXITED:
+ if (mCurrentViewId == viewState.id) {
+ mUi.hideFillUi(viewState.id);
+ mCurrentViewId = null;
+ }
+ break;
+ default:
+ Slog.w(TAG, "updateLocked(): unknown action: " + action);
}
-
- if ((flags & FLAG_VIEW_EXITED) != 0) {
- if (mCurrentViewId == viewState.id) {
- mUi.hideFillUi(viewState.id);
- mCurrentViewId = null;
- }
- return;
- }
-
- Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
}
@Override
@@ -1042,7 +1031,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onFillReady() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
}
@@ -1055,12 +1044,8 @@
getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
}
- static String getFlagAsString(int flag) {
- return DebugUtils.flagsToString(AutofillManager.class, "FLAG_", flag);
- }
-
- int getId() {
- return mId;
+ String getActionAsString(int flag) {
+ return DebugUtils.flagsToString(AutofillManager.class, "ACTION_", flag);
}
boolean isDestroyed() {
@@ -1079,7 +1064,7 @@
synchronized (mLock) {
if (!mHasCallback) return;
try {
- mClient.notifyNoFillUi(mId, mWindowToken, mCurrentViewId);
+ mClient.notifyNoFillUi(id, mWindowToken, mCurrentViewId);
} catch (RemoteException e) {
Slog.e(TAG, "Error notifying client no fill UI: windowToken=" + mWindowToken
+ " id=" + mCurrentViewId, e);
@@ -1114,7 +1099,7 @@
}
try {
- mClient.setTrackedViews(mId, trackedViews, saveOnAllViewsInvisible);
+ mClient.setTrackedViews(id, trackedViews, saveOnAllViewsInvisible);
} catch (RemoteException e) {
Slog.w(TAG, "Cannot set tracked ids", e);
}
@@ -1128,7 +1113,8 @@
if (mResponses == null) {
mResponses = new SparseArray<>(4);
}
- mResponses.put(response.getRequestId(), response);
+ final int requestId = response.getRequestId();
+ mResponses.put(requestId, response);
mClientState = response.getClientState();
setViewStatesLocked(response, ViewState.STATE_FILLABLE);
@@ -1138,13 +1124,18 @@
return;
}
- if ((mFlags & FLAG_MANUAL_REQUEST) != 0 && response.getDatasets() != null
- && response.getDatasets().size() == 1) {
- Slog.d(TAG, "autofilling manual request directly");
- autoFill(response.getRequestId(), response.getDatasets().get(0));
- return;
- }
+ final ArrayList<Dataset> datasets = response.getDatasets();
+ if (datasets != null && datasets.size() == 1) {
+ // Check if it its a single response for a manual request, in which case it should
+ // be automatically filled
+ final FillContext context = getFillContextByRequestIdLocked(requestId);
+ if (context != null && (context.getStructure().getFlags() & FLAG_MANUAL_REQUEST) != 0) {
+ Slog.d(TAG, "autofilling manual request directly");
+ autoFill(requestId, datasets.get(0));
+ return;
+ }
+ }
// Updates the UI, if necessary.
final ViewState currentView = mViewStates.get(mCurrentViewId);
currentView.maybeCallOnFillReady();
@@ -1199,7 +1190,7 @@
}
}
- private ViewState createOrUpdateViewStateLocked(AutofillId id, int state,AutofillValue value) {
+ private ViewState createOrUpdateViewStateLocked(AutofillId id, int state, AutofillValue value) {
ViewState viewState = mViewStates.get(id);
if (viewState != null) {
viewState.setState(state);
@@ -1234,7 +1225,7 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#autoFill() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
// Autofill it directly...
@@ -1280,7 +1271,7 @@
private void startAuthentication(IntentSender intent, Intent fillInIntent) {
try {
synchronized (mLock) {
- mClient.authenticate(mId, intent, fillInIntent);
+ mClient.authenticate(id, intent, fillInIntent);
}
} catch (RemoteException e) {
Slog.e(TAG, "Error launching auth intent", e);
@@ -1288,10 +1279,9 @@
}
void dumpLocked(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("id: "); pw.println(mId);
+ pw.print(prefix); pw.print("id: "); pw.println(id);
pw.print(prefix); pw.print("uid: "); pw.println(uid);
pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
- pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
pw.print(prefix); pw.print("mResponses: "); pw.println(mResponses);
pw.print(prefix); pw.print("mResponseWaitingAuth: "); pw.println(mResponseWaitingAuth);
pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
@@ -1332,14 +1322,14 @@
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#autoFillApp() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
try {
if (DEBUG) {
Slog.d(TAG, "autoFillApp(): the buck is on the app: " + dataset);
}
- mClient.autofill(mId, mWindowToken, dataset.getFieldIds(),
+ mClient.autofill(id, mWindowToken, dataset.getFieldIds(),
dataset.getFieldValues());
setViewStatesLocked(null, dataset, ViewState.STATE_AUTOFILLED);
} catch (RemoteException e) {
@@ -1378,11 +1368,11 @@
}
if (mDestroyed) {
Slog.w(TAG, "Call to Session#removeSelfLocked() rejected - session: "
- + mId + " destroyed");
+ + id + " destroyed");
return;
}
destroyLocked();
- mService.removeSessionLocked(mId);
+ mService.removeSessionLocked(id);
}
private int getLastResponseIndex() {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 3967f59..d98ee9d 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -65,15 +65,15 @@
public static final int STATE_WAITING_RESPONSE_AUTH = 0x80;
public final AutofillId id;
+
private final Listener mListener;
private final Session mSession;
- private FillResponse mResponse;
+ private FillResponse mResponse;
private AutofillValue mInitialValue;
private AutofillValue mCurrentValue;
private AutofillValue mAutofilledValue;
private Rect mVirtualBounds;
-
private int mState;
ViewState(Session session, AutofillId id, AutofillValue value, Listener listener, int state) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 772cdcd..cabaebd4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12912,11 +12912,6 @@
@Override
public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
IBinder activityToken, int flags) {
- // NOTE: we could always use ActivityManager.ASSIST_CONTEXT_FULL and let ActivityThread
- // rely on the flags to decide whether the handleRequestAssistContextExtras() is for
- // autofill, but it's safer to explicitly use new AutoFill types, in case the Assist
- // requests use flags in the future as well (since their flags value might collide with the
- // autofill flag values).
return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index ba72dcf..d6bfb35 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -751,6 +751,26 @@
mAppsNotReportingCrashes.add(proc.info.packageName);
}
+ static boolean isInterestingForBackgroundTraces(ProcessRecord app) {
+ // The system_server is always considered interesting.
+ if (app.pid == MY_PID) {
+ return true;
+ }
+
+ // A package is considered interesting if any of the following is true :
+ //
+ // - It's displaying an activity.
+ // - It's the SystemUI.
+ // - It has an overlay or a top UI visible.
+ //
+ // NOTE: The check whether a given ProcessRecord belongs to the systemui
+ // process is a bit of a kludge, but the same pattern seems repeated at
+ // several places in the system server.
+ return app.isInterestingToUserLocked() ||
+ (app.info != null && "com.android.systemui".equals(app.info.packageName)) ||
+ (app.hasTopUi || app.hasOverlayUi);
+ }
+
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
ActivityRecord parent, boolean aboveSystem, final String annotation) {
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
@@ -812,7 +832,7 @@
firstPids.add(app.pid);
// Don't dump other PIDs if it's a background ANR
- isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID;
+ isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
if (!isSilentANR) {
int parentPid = app.pid;
if (parent != null && parent.app != null && parent.app.pid > 0) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 3c5c5fd..b025385 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -520,6 +520,14 @@
return true;
}
}
+
+ final int servicesSize = services.size();
+ for (int i = 0; i < servicesSize; i++) {
+ ServiceRecord r = services.valueAt(i);
+ if (r.isForeground) {
+ return true;
+ }
+ }
return false;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a14c273..15df545 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -739,12 +739,123 @@
@GuardedBy("mPackages")
final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
- final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
- @Override public boolean hasFeature(String feature) {
+ class PackageParserCallback implements PackageParser.Callback {
+ @Override public final boolean hasFeature(String feature) {
return PackageManagerService.this.hasSystemFeature(feature, 0);
}
+
+ final List<PackageParser.Package> getStaticOverlayPackagesLocked(
+ Collection<PackageParser.Package> allPackages, String targetPackageName) {
+ List<PackageParser.Package> overlayPackages = null;
+ for (PackageParser.Package p : allPackages) {
+ if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
+ if (overlayPackages == null) {
+ overlayPackages = new ArrayList<PackageParser.Package>();
+ }
+ overlayPackages.add(p);
+ }
+ }
+ if (overlayPackages != null) {
+ Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
+ public int compare(PackageParser.Package p1, PackageParser.Package p2) {
+ return p1.mOverlayPriority - p2.mOverlayPriority;
+ }
+ };
+ Collections.sort(overlayPackages, cmp);
+ }
+ return overlayPackages;
+ }
+
+ final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
+ String targetPackageName, String targetPath) {
+ if ("android".equals(targetPackageName)) {
+ // Static RROs targeting to "android", ie framework-res.apk, are already applied by
+ // native AssetManager.
+ return null;
+ }
+ List<PackageParser.Package> overlayPackages =
+ getStaticOverlayPackagesLocked(allPackages, targetPackageName);
+ if (overlayPackages == null || overlayPackages.isEmpty()) {
+ return null;
+ }
+ List<String> overlayPathList = null;
+ for (PackageParser.Package overlayPackage : overlayPackages) {
+ if (targetPath == null) {
+ if (overlayPathList == null) {
+ overlayPathList = new ArrayList<String>();
+ }
+ overlayPathList.add(overlayPackage.baseCodePath);
+ continue;
+ }
+
+ try {
+ // Creates idmaps for system to parse correctly the Android manifest of the
+ // target package.
+ //
+ // OverlayManagerService will update each of them with a correct gid from its
+ // target package app id.
+ mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
+ UserHandle.getSharedAppGid(
+ UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
+ if (overlayPathList == null) {
+ overlayPathList = new ArrayList<String>();
+ }
+ overlayPathList.add(overlayPackage.baseCodePath);
+ } catch (InstallerException e) {
+ Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
+ overlayPackage.baseCodePath);
+ }
+ }
+ return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
+ }
+
+ String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
+ synchronized (mPackages) {
+ return getStaticOverlayPathsLocked(
+ mPackages.values(), targetPackageName, targetPath);
+ }
+ }
+
+ @Override public final String[] getOverlayApks(String targetPackageName) {
+ return getStaticOverlayPaths(targetPackageName, null);
+ }
+
+ @Override public final String[] getOverlayPaths(String targetPackageName,
+ String targetPath) {
+ return getStaticOverlayPaths(targetPackageName, targetPath);
+ }
};
+ class ParallelPackageParserCallback extends PackageParserCallback {
+ List<PackageParser.Package> mOverlayPackages = null;
+
+ void findStaticOverlayPackages() {
+ synchronized (mPackages) {
+ for (PackageParser.Package p : mPackages.values()) {
+ if (p.mIsStaticOverlay) {
+ if (mOverlayPackages == null) {
+ mOverlayPackages = new ArrayList<PackageParser.Package>();
+ }
+ mOverlayPackages.add(p);
+ }
+ }
+ }
+ }
+
+ @Override
+ synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
+ // We can trust mOverlayPackages without holding mPackages because package uninstall
+ // can't happen while running parallel parsing.
+ // Moreover holding mPackages on each parsing thread causes dead-lock.
+ return mOverlayPackages == null ? null :
+ getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
+ }
+ }
+
+ final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
+ final ParallelPackageParserCallback mParallelPackageParserCallback =
+ new ParallelPackageParserCallback();
+
public static final class SharedLibraryEntry {
public final String path;
public final String apk;
@@ -2453,6 +2564,8 @@
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
+ mParallelPackageParserCallback.findStaticOverlayPackages();
+
// Find base frameworks (resource packages without code).
scanDirTracedLI(frameworkDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
@@ -7856,7 +7969,8 @@
+ " flags=0x" + Integer.toHexString(parseFlags));
}
ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
- mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
+ mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
+ mParallelPackageParserCallback);
// Submit files for parsing in parallel
int fileCount = 0;