summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/TEST_MAPPING9
-rw-r--r--core/java/android/inputmethodservice/InlineSuggestionSessionController.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java44
-rw-r--r--core/java/com/android/internal/app/ChooserListAdapter.java38
-rw-r--r--core/java/com/android/internal/app/ResolverListAdapter.java93
-rw-r--r--services/core/java/com/android/server/appop/TEST_MAPPING10
6 files changed, 132 insertions, 64 deletions
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 8ad33dbf9f4a..b65ae7a0a7b9 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -29,6 +29,15 @@
},
{
"file_patterns": ["(/|^)AppOpsManager.java"],
+ "name": "CtsStatsdHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.cts.statsd.atom.UidAtomTests#testAppOps"
+ }
+ ]
+ },
+ {
+ "file_patterns": ["(/|^)AppOpsManager.java"],
"name": "CtsPermission2TestCases",
"options": [
{
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSessionController.java b/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
index 8c0dd2a9bf59..071c096ee2f0 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSessionController.java
@@ -134,6 +134,7 @@ class InlineSuggestionSessionController {
mImeClientFieldId = imeFieldId;
if (mSession != null) {
+ mSession.consumeInlineSuggestionsResponse(InlineSuggestionSession.EMPTY_RESPONSE);
// Initiates the callback to Autofill if there is a pending matching session.
// Otherwise updates the session with the Ime status.
if (!mSession.isCallbackInvoked() && match(mSession.getRequestInfo())) {
@@ -213,7 +214,6 @@ class InlineSuggestionSessionController {
mImeInputViewStarted = false;
mImeInputStarted = false;
if (mSession != null && mSession.shouldSendImeStatus()) {
- mSession.consumeInlineSuggestionsResponse(InlineSuggestionSession.EMPTY_RESPONSE);
try {
mSession.getRequestCallback().onInputMethodFinishInput();
} catch (RemoteException e) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b860bac0d001..896a2de8b135 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1726,8 +1726,10 @@ public final class ViewRootImpl implements ViewParent,
destroySurface();
}
}
+ scheduleConsumeBatchedInputImmediately();
}
+
/** Register callbacks to be notified when the ViewRootImpl surface changes. */
interface SurfaceChangedCallback {
void surfaceCreated(Transaction t);
@@ -8107,7 +8109,9 @@ public final class ViewRootImpl implements ViewParent,
}
void scheduleConsumeBatchedInput() {
- if (!mConsumeBatchedInputScheduled) {
+ // If anything is currently scheduled to consume batched input then there's no point in
+ // scheduling it again.
+ if (!mConsumeBatchedInputScheduled && !mConsumeBatchedInputImmediatelyScheduled) {
mConsumeBatchedInputScheduled = true;
mChoreographer.postCallback(Choreographer.CALLBACK_INPUT,
mConsumedBatchedInputRunnable, null);
@@ -8130,22 +8134,15 @@ public final class ViewRootImpl implements ViewParent,
}
}
- void doConsumeBatchedInput(long frameTimeNanos) {
- if (mConsumeBatchedInputScheduled) {
- mConsumeBatchedInputScheduled = false;
- if (mInputEventReceiver != null) {
- if (mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos)
- && frameTimeNanos != -1) {
- // If we consumed a batch here, we want to go ahead and schedule the
- // consumption of batched input events on the next frame. Otherwise, we would
- // wait until we have more input events pending and might get starved by other
- // things occurring in the process. If the frame time is -1, however, then
- // we're in a non-batching mode, so there's no need to schedule this.
- scheduleConsumeBatchedInput();
- }
- }
- doProcessInputEvents();
+ boolean doConsumeBatchedInput(long frameTimeNanos) {
+ final boolean consumedBatches;
+ if (mInputEventReceiver != null) {
+ consumedBatches = mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos);
+ } else {
+ consumedBatches = false;
}
+ doProcessInputEvents();
+ return consumedBatches;
}
final class TraversalRunnable implements Runnable {
@@ -8189,8 +8186,11 @@ public final class ViewRootImpl implements ViewParent,
@Override
public void onBatchedInputEventPending(int source) {
+ // mStopped: There will be no more choreographer callbacks if we are stopped,
+ // so we must consume all input immediately to prevent ANR
final boolean unbuffered = mUnbufferedInputDispatch
- || (source & mUnbufferedInputSource) != SOURCE_CLASS_NONE;
+ || (source & mUnbufferedInputSource) != SOURCE_CLASS_NONE
+ || mStopped;
if (unbuffered) {
if (mConsumeBatchedInputScheduled) {
unscheduleConsumeBatchedInput();
@@ -8218,7 +8218,14 @@ public final class ViewRootImpl implements ViewParent,
final class ConsumeBatchedInputRunnable implements Runnable {
@Override
public void run() {
- doConsumeBatchedInput(mChoreographer.getFrameTimeNanos());
+ mConsumeBatchedInputScheduled = false;
+ if (doConsumeBatchedInput(mChoreographer.getFrameTimeNanos())) {
+ // If we consumed a batch here, we want to go ahead and schedule the
+ // consumption of batched input events on the next frame. Otherwise, we would
+ // wait until we have more input events pending and might get starved by other
+ // things occurring in the process.
+ scheduleConsumeBatchedInput();
+ }
}
}
final ConsumeBatchedInputRunnable mConsumedBatchedInputRunnable =
@@ -8228,6 +8235,7 @@ public final class ViewRootImpl implements ViewParent,
final class ConsumeBatchedInputImmediatelyRunnable implements Runnable {
@Override
public void run() {
+ mConsumeBatchedInputImmediatelyScheduled = false;
doConsumeBatchedInput(-1);
}
}
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index de5ab6f1c90d..31e6cb9b5591 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -95,6 +95,7 @@ public class ChooserListAdapter extends ResolverListAdapter {
mSelectableTargetInfoCommunicator;
private int mNumShortcutResults = 0;
+ private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
// Reserve spots for incoming direct share targets by adding placeholders
private ChooserTargetInfo
@@ -239,11 +240,42 @@ public class ChooserListAdapter extends ResolverListAdapter {
@Override
protected void onBindView(View view, TargetInfo info, int position) {
- super.onBindView(view, info, position);
- if (info == null) return;
+ final ViewHolder holder = (ViewHolder) view.getTag();
+ if (info == null) {
+ holder.icon.setImageDrawable(
+ mContext.getDrawable(R.drawable.resolver_icon_placeholder));
+ return;
+ }
+
+ if (!(info instanceof DisplayResolveInfo)) {
+ holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
+ holder.bindIcon(info);
+
+ if (info instanceof SelectableTargetInfo) {
+ // direct share targets should append the application name for a better readout
+ DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
+ CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
+ CharSequence extendedInfo = info.getExtendedInfo();
+ String contentDescription = String.join(" ", info.getDisplayLabel(),
+ extendedInfo != null ? extendedInfo : "", appName);
+ holder.updateContentDescription(contentDescription);
+ }
+ } else {
+ DisplayResolveInfo dri = (DisplayResolveInfo) info;
+ holder.bindLabel(dri.getDisplayLabel(), dri.getExtendedInfo(), alwaysShowSubLabel());
+ LoadIconTask task = mIconLoaders.get(dri);
+ if (task == null) {
+ task = new LoadIconTask(dri, holder);
+ mIconLoaders.put(dri, task);
+ task.execute();
+ } else {
+ // The holder was potentially changed as the underlying items were
+ // reshuffled, so reset the target holder
+ task.setViewHolder(holder);
+ }
+ }
// If target is loading, show a special placeholder shape in the label, make unclickable
- final ViewHolder holder = (ViewHolder) view.getTag();
if (info instanceof ChooserActivity.PlaceHolderTargetInfo) {
final int maxWidth = mContext.getResources().getDimensionPixelSize(
R.dimen.chooser_direct_share_label_placeholder_max_width);
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 094fb1e2f23c..eef722e32bdc 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -54,7 +54,6 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
import com.android.internal.app.chooser.DisplayResolveInfo;
-import com.android.internal.app.chooser.SelectableTargetInfo;
import com.android.internal.app.chooser.TargetInfo;
import java.util.ArrayList;
@@ -68,7 +67,7 @@ public class ResolverListAdapter extends BaseAdapter {
private final List<ResolveInfo> mBaseResolveList;
private final PackageManager mPm;
protected final Context mContext;
- private final ColorMatrixColorFilter mSuspendedMatrixColorFilter;
+ private static ColorMatrixColorFilter sSuspendedMatrixColorFilter;
private final int mIconDpi;
protected ResolveInfo mLastChosen;
private DisplayResolveInfo mOtherProfile;
@@ -103,7 +102,6 @@ public class ResolverListAdapter extends BaseAdapter {
mDisplayList = new ArrayList<>();
mFilterLastUsed = filterLastUsed;
mResolverListController = resolverListController;
- mSuspendedMatrixColorFilter = createSuspendedColorMatrix();
mResolverListCommunicator = resolverListCommunicator;
mIsAudioCaptureDevice = isAudioCaptureDevice;
final ActivityManager am = (ActivityManager) mContext.getSystemService(ACTIVITY_SERVICE);
@@ -541,28 +539,13 @@ public class ResolverListAdapter extends BaseAdapter {
getLoadLabelTask((DisplayResolveInfo) info, holder).execute();
} else {
holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
- if (info instanceof SelectableTargetInfo) {
- // direct share targets should append the application name for a better readout
- DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
- CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
- CharSequence extendedInfo = info.getExtendedInfo();
- String contentDescription = String.join(" ", info.getDisplayLabel(),
- extendedInfo != null ? extendedInfo : "", appName);
- holder.updateContentDescription(contentDescription);
- }
- }
-
- if (info.isSuspended()) {
- holder.icon.setColorFilter(mSuspendedMatrixColorFilter);
- } else {
- holder.icon.setColorFilter(null);
}
if (info instanceof DisplayResolveInfo
&& !((DisplayResolveInfo) info).hasDisplayIcon()) {
- new ResolverListAdapter.LoadIconTask((DisplayResolveInfo) info, holder.icon).execute();
+ new LoadIconTask((DisplayResolveInfo) info, holder).execute();
} else {
- holder.icon.setImageDrawable(info.getDisplayIcon(mContext));
+ holder.bindIcon(info);
}
}
@@ -580,23 +563,27 @@ public class ResolverListAdapter extends BaseAdapter {
}
}
- private ColorMatrixColorFilter createSuspendedColorMatrix() {
- int grayValue = 127;
- float scale = 0.5f; // half bright
+ private static ColorMatrixColorFilter getSuspendedColorMatrix() {
+ if (sSuspendedMatrixColorFilter == null) {
+
+ int grayValue = 127;
+ float scale = 0.5f; // half bright
- ColorMatrix tempBrightnessMatrix = new ColorMatrix();
- float[] mat = tempBrightnessMatrix.getArray();
- mat[0] = scale;
- mat[6] = scale;
- mat[12] = scale;
- mat[4] = grayValue;
- mat[9] = grayValue;
- mat[14] = grayValue;
+ ColorMatrix tempBrightnessMatrix = new ColorMatrix();
+ float[] mat = tempBrightnessMatrix.getArray();
+ mat[0] = scale;
+ mat[6] = scale;
+ mat[12] = scale;
+ mat[4] = grayValue;
+ mat[9] = grayValue;
+ mat[14] = grayValue;
- ColorMatrix matrix = new ColorMatrix();
- matrix.setSaturation(0.0f);
- matrix.preConcat(tempBrightnessMatrix);
- return new ColorMatrixColorFilter(matrix);
+ ColorMatrix matrix = new ColorMatrix();
+ matrix.setSaturation(0.0f);
+ matrix.preConcat(tempBrightnessMatrix);
+ sSuspendedMatrixColorFilter = new ColorMatrixColorFilter(matrix);
+ }
+ return sSuspendedMatrixColorFilter;
}
ActivityInfoPresentationGetter makePresentationGetter(ActivityInfo ai) {
@@ -615,7 +602,17 @@ public class ResolverListAdapter extends BaseAdapter {
void loadFilteredItemIconTaskAsync(@NonNull ImageView iconView) {
final DisplayResolveInfo iconInfo = getFilteredItem();
if (iconView != null && iconInfo != null) {
- new LoadIconTask(iconInfo, iconView).execute();
+ new AsyncTask<Void, Void, Drawable>() {
+ @Override
+ protected Drawable doInBackground(Void... params) {
+ return loadIconForResolveInfo(iconInfo.getResolveInfo());
+ }
+
+ @Override
+ protected void onPostExecute(Drawable d) {
+ iconView.setImageDrawable(d);
+ }
+ }.execute();
}
}
@@ -708,6 +705,15 @@ public class ResolverListAdapter extends BaseAdapter {
public void updateContentDescription(String description) {
itemView.setContentDescription(description);
}
+
+ public void bindIcon(TargetInfo info) {
+ icon.setImageDrawable(info.getDisplayIcon(itemView.getContext()));
+ if (info.isSuspended()) {
+ icon.setColorFilter(getSuspendedColorMatrix());
+ } else {
+ icon.setColorFilter(null);
+ }
+ }
}
protected class LoadLabelTask extends AsyncTask<Void, Void, CharSequence[]> {
@@ -761,14 +767,14 @@ public class ResolverListAdapter extends BaseAdapter {
}
class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
- protected final com.android.internal.app.chooser.DisplayResolveInfo mDisplayResolveInfo;
+ protected final DisplayResolveInfo mDisplayResolveInfo;
private final ResolveInfo mResolveInfo;
- private final ImageView mTargetView;
+ private ViewHolder mHolder;
- LoadIconTask(DisplayResolveInfo dri, ImageView target) {
+ LoadIconTask(DisplayResolveInfo dri, ViewHolder holder) {
mDisplayResolveInfo = dri;
mResolveInfo = dri.getResolveInfo();
- mTargetView = target;
+ mHolder = holder;
}
@Override
@@ -782,9 +788,14 @@ public class ResolverListAdapter extends BaseAdapter {
mResolverListCommunicator.updateProfileViewButton();
} else {
mDisplayResolveInfo.setDisplayIcon(d);
- mTargetView.setImageDrawable(d);
+ mHolder.bindIcon(mDisplayResolveInfo);
}
}
+
+ public void setViewHolder(ViewHolder holder) {
+ mHolder = holder;
+ mHolder.bindIcon(mDisplayResolveInfo);
+ }
}
/**
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index a3baa7e8bdea..00bbacc089a2 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -43,6 +43,14 @@
"include-filter": "android.app.cts.ActivityManagerApi29Test"
}
]
- }
+ },
+ {
+ "name": "CtsStatsdHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.cts.statsd.atom.UidAtomTests#testAppOps"
+ }
+ ]
+ }
]
}