diff options
4 files changed, 86 insertions, 14 deletions
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java index 8ffe8f547eac..4f90019d32b6 100644 --- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java +++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java @@ -61,6 +61,8 @@ public final class AutoFillUI { private final MetricsLogger mMetricsLogger = new MetricsLogger(); + private final @NonNull OverlayControl mOverlayControl; + public interface AutoFillUiCallback { void authenticate(int requestId, int datasetIndex, @NonNull IntentSender intent, @Nullable Bundle extras); @@ -75,6 +77,7 @@ public final class AutoFillUI { public AutoFillUI(@NonNull Context context) { mContext = context; + mOverlayControl = new OverlayControl(context); } public void setCallback(@NonNull AutoFillUiCallback callback) { @@ -174,7 +177,7 @@ public final class AutoFillUI { } hideAllUiThread(callback); mFillUi = new FillUi(mContext, response, focusedId, - filterText, new FillUi.Callback() { + filterText, mOverlayControl, new FillUi.Callback() { @Override public void onResponsePicked(FillResponse response) { log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL); @@ -255,7 +258,7 @@ public final class AutoFillUI { } hideAllUiThread(callback); mSaveUi = new SaveUi(mContext, providerLabel, info, - new SaveUi.OnSaveListener() { + mOverlayControl, new SaveUi.OnSaveListener() { @Override public void onSave() { log.setType(MetricsProto.MetricsEvent.TYPE_ACTION); diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java index e9c98e94c860..51a239f62be5 100644 --- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java @@ -100,7 +100,7 @@ final class FillUi { FillUi(@NonNull Context context, @NonNull FillResponse response, @NonNull AutofillId focusedViewId, @NonNull @Nullable String filterText, - @NonNull Callback callback) { + @NonNull OverlayControl overlayControl, @NonNull Callback callback) { mContext = context; mCallback = callback; @@ -146,7 +146,7 @@ final class FillUi { mContentWidth = content.getMeasuredWidth(); mContentHeight = content.getMeasuredHeight(); - mWindow = new AnchoredWindow(decor); + mWindow = new AnchoredWindow(decor, overlayControl); mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter); } else { final int datasetCount = response.getDatasets().size(); @@ -193,7 +193,7 @@ final class FillUi { } applyNewFilterText(); - mWindow = new AnchoredWindow(decor); + mWindow = new AnchoredWindow(decor, overlayControl); } } @@ -366,6 +366,7 @@ final class FillUi { } final class AnchoredWindow implements View.OnTouchListener { + private final @NonNull OverlayControl mOverlayControl; private final WindowManager mWm; private final View mContentView; private boolean mShowing; @@ -375,9 +376,10 @@ final class FillUi { * * @param contentView content of the window */ - AnchoredWindow(View contentView) { + AnchoredWindow(View contentView, @NonNull OverlayControl overlayControl) { mWm = contentView.getContext().getSystemService(WindowManager.class); mContentView = contentView; + mOverlayControl = overlayControl; } /** @@ -391,6 +393,7 @@ final class FillUi { .getString(R.string.autofill_picker_accessibility_title); mWm.addView(mContentView, params); mContentView.setOnTouchListener(this); + mOverlayControl.hideOverlays(); mShowing = true; } else { mWm.updateViewLayout(mContentView, params); @@ -423,6 +426,8 @@ final class FillUi { // does, it should not crash the system. Slog.e(TAG, "Exception hiding window ", e); mCallback.onDestroy(); + } finally { + mOverlayControl.showOverlays(); } } diff --git a/services/autofill/java/com/android/server/autofill/ui/OverlayControl.java b/services/autofill/java/com/android/server/autofill/ui/OverlayControl.java new file mode 100644 index 000000000000..fe0611eef0a2 --- /dev/null +++ b/services/autofill/java/com/android/server/autofill/ui/OverlayControl.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2017 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 com.android.server.autofill.ui; + +import android.annotation.NonNull; +import android.app.AppOpsManager; +import android.content.Context; +import android.os.Binder; +import android.os.IBinder; + +/** + * This class controls showing/hiding overlays. We don't + * hide all overlays (toast/system alerts) while sensitive + * autofill UI is up. + */ +class OverlayControl { + + private final IBinder mToken = new Binder(); + + private final @NonNull AppOpsManager mAppOpsManager; + + OverlayControl(@NonNull Context context) { + mAppOpsManager = context.getSystemService(AppOpsManager.class); + } + + void hideOverlays() { + setOverlayAllowed(false); + } + + void showOverlays() { + setOverlayAllowed(true); + } + + private void setOverlayAllowed(boolean allowed) { + if (mAppOpsManager != null) { + mAppOpsManager.setUserRestriction( + AppOpsManager.OP_SYSTEM_ALERT_WINDOW, !allowed, mToken); + mAppOpsManager.setUserRestriction( + AppOpsManager.OP_TOAST_WINDOW, !allowed, mToken); + } + } +} diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index 491af91cbc36..d1fbbf9ceda1 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -99,14 +99,17 @@ final class SaveUi { private final @NonNull OneTimeListener mListener; + private final @NonNull OverlayControl mOverlayControl; + private final CharSequence mTitle; private final CharSequence mSubTitle; private boolean mDestroyed; SaveUi(@NonNull Context context, @NonNull CharSequence providerLabel, @NonNull SaveInfo info, - @NonNull OnSaveListener listener) { + @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener) { mListener = new OneTimeListener(listener); + mOverlayControl = overlayControl; final LayoutInflater inflater = LayoutInflater.from(context); final View view = inflater.inflate(R.layout.autofill_save, null); @@ -197,16 +200,21 @@ final class SaveUi { Slog.i(TAG, "Showing save dialog: " + mTitle); mDialog.show(); + mOverlayControl.hideOverlays(); } void destroy() { - if (sDebug) Slog.d(TAG, "destroy()"); - throwIfDestroyed(); - mListener.onDestroy(); - mHandler.removeCallbacksAndMessages(mListener); - if (sVerbose) Slog.v(TAG, "destroy(): dismissing dialog"); - mDialog.dismiss(); - mDestroyed = true; + try { + if (sDebug) Slog.d(TAG, "destroy()"); + throwIfDestroyed(); + mListener.onDestroy(); + mHandler.removeCallbacksAndMessages(mListener); + if (sVerbose) Slog.v(TAG, "destroy(): dismissing dialog"); + mDialog.dismiss(); + mDestroyed = true; + } finally { + mOverlayControl.showOverlays(); + } } private void throwIfDestroyed() { |