diff options
| author | 2020-02-28 21:09:36 +0000 | |
|---|---|---|
| committer | 2020-02-28 21:09:36 +0000 | |
| commit | 9b256a210d3b90f7fdd236de2ca8aa9d5df604bb (patch) | |
| tree | 04e4dad5c01091133add0942c480bd64099cc117 | |
| parent | 228376091d055bd5a6671916941878aaa9913405 (diff) | |
| parent | dee28c91a323a3438191020af198d5cc2dcf1e7f (diff) | |
Merge "Unify toast presentation code" into rvc-dev
| -rw-r--r-- | core/java/android/widget/Toast.java | 83 | ||||
| -rw-r--r-- | core/java/android/widget/ToastPresenter.java | 117 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/toast/ToastUI.java | 64 |
3 files changed, 140 insertions, 124 deletions
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index 9e4ebfe44b58..436d6836d11e 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -31,9 +31,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.EnabledAfter; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; -import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.PixelFormat; import android.os.Binder; import android.os.Build; import android.os.Handler; @@ -43,11 +41,8 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; -import android.view.Gravity; -import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import com.android.internal.annotations.GuardedBy; @@ -122,6 +117,7 @@ public class Toast { private final Binder mToken; private final Context mContext; private final Handler mHandler; + private final ToastPresenter mPresenter; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) final TN mTN; @UnsupportedAppUsage @@ -172,7 +168,8 @@ public class Toast { looper = getLooper(looper); mHandler = new Handler(looper); mCallbacks = new ArrayList<>(); - mTN = new TN(context.getPackageName(), mToken, mCallbacks, looper); + mPresenter = new ToastPresenter(context, AccessibilityManager.getInstance(context)); + mTN = new TN(mPresenter, context.getPackageName(), mToken, mCallbacks, looper); mTN.mY = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.toast_y_offset); mTN.mGravity = context.getResources().getInteger( @@ -504,13 +501,7 @@ public class Toast { return result; } else { Toast result = new Toast(context, looper); - - LayoutInflater inflate = (LayoutInflater) - context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null); - TextView tv = (TextView) v.findViewById(com.android.internal.R.id.message); - tv.setText(text); - + View v = result.mPresenter.getTextToastView(text); result.mNextView = v; result.mDuration = duration; @@ -611,34 +602,20 @@ public class Toast { final String mPackageName; final Binder mToken; + private final ToastPresenter mPresenter; @GuardedBy("mCallbacks") private final List<Callback> mCallbacks; - static final long SHORT_DURATION_TIMEOUT = 4000; - static final long LONG_DURATION_TIMEOUT = 7000; - /** * Creates a {@link ITransientNotification} object. * * The parameter {@code callbacks} is not copied and is accessed with itself as its own * lock. */ - TN(String packageName, Binder token, List<Callback> callbacks, @Nullable Looper looper) { - // XXX This should be changed to use a Dialog, with a Theme.Toast - // defined that sets up the layout params appropriately. - final WindowManager.LayoutParams params = mParams; - params.height = WindowManager.LayoutParams.WRAP_CONTENT; - params.width = WindowManager.LayoutParams.WRAP_CONTENT; - params.format = PixelFormat.TRANSLUCENT; - params.windowAnimations = com.android.internal.R.style.Animation_Toast; - params.type = WindowManager.LayoutParams.TYPE_TOAST; - params.setFitInsetsIgnoringVisibility(true); - params.setTitle("Toast"); - params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; - + TN(ToastPresenter presenter, String packageName, Binder token, List<Callback> callbacks, + @Nullable Looper looper) { + mPresenter = presenter; mPackageName = packageName; mToken = token; mCallbacks = callbacks; @@ -673,6 +650,8 @@ public class Toast { } } }; + + presenter.startLayoutParams(mParams); } private List<Callback> getCallbacks() { @@ -718,30 +697,12 @@ public class Toast { handleHide(); mView = mNextView; Context context = mView.getContext().getApplicationContext(); - String packageName = mView.getContext().getOpPackageName(); if (context == null) { context = mView.getContext(); } - mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); - // We can resolve the Gravity here by using the Locale for getting - // the layout direction - final Configuration config = mView.getContext().getResources().getConfiguration(); - final int gravity = Gravity.getAbsoluteGravity(mGravity, config.getLayoutDirection()); - mParams.gravity = gravity; - if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { - mParams.horizontalWeight = 1.0f; - } - if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { - mParams.verticalWeight = 1.0f; - } - mParams.x = mX; - mParams.y = mY; - mParams.verticalMargin = mVerticalMargin; - mParams.horizontalMargin = mHorizontalMargin; - mParams.packageName = packageName; - mParams.hideTimeoutMilliseconds = mDuration == - Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT; - mParams.token = windowToken; + mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + mPresenter.adjustLayoutParams(mParams, windowToken, mDuration, mGravity, mX, mY, + mHorizontalMargin, mVerticalMargin); if (mView.getParent() != null) { if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this); mWM.removeView(mView); @@ -753,7 +714,7 @@ public class Toast { // invalidated. Let us hedge against that. try { mWM.addView(mView, mParams); - trySendAccessibilityEvent(); + mPresenter.trySendAccessibilityEvent(mView, mPackageName); for (Callback callback : getCallbacks()) { callback.onToastShown(); } @@ -763,22 +724,6 @@ public class Toast { } } - private void trySendAccessibilityEvent() { - AccessibilityManager accessibilityManager = - AccessibilityManager.getInstance(mView.getContext()); - if (!accessibilityManager.isEnabled()) { - return; - } - // treat toasts as notifications since they are used to - // announce a transient piece of information to the user - AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); - event.setClassName(getClass().getName()); - event.setPackageName(mView.getContext().getPackageName()); - mView.dispatchPopulateAccessibilityEvent(event); - accessibilityManager.sendAccessibilityEvent(event); - } - @UnsupportedAppUsage public void handleHide() { if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView); diff --git a/core/java/android/widget/ToastPresenter.java b/core/java/android/widget/ToastPresenter.java new file mode 100644 index 000000000000..654ab50a9ce5 --- /dev/null +++ b/core/java/android/widget/ToastPresenter.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 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.widget; + +import android.content.Context; +import android.content.res.Configuration; +import android.graphics.PixelFormat; +import android.os.IBinder; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.WindowManager; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; + +import com.android.internal.R; + +/** + * Class responsible for toast presentation inside app's process and in system UI. + * + * @hide + */ +public class ToastPresenter { + private static final long SHORT_DURATION_TIMEOUT = 4000; + private static final long LONG_DURATION_TIMEOUT = 7000; + + private final Context mContext; + private final AccessibilityManager mAccessibilityManager; + + public ToastPresenter(Context context, AccessibilityManager accessibilityManager) { + mContext = context; + mAccessibilityManager = accessibilityManager; + } + + /** + * Initializes {@code params} with default values for toasts. + */ + public void startLayoutParams(WindowManager.LayoutParams params) { + params.height = WindowManager.LayoutParams.WRAP_CONTENT; + params.width = WindowManager.LayoutParams.WRAP_CONTENT; + params.format = PixelFormat.TRANSLUCENT; + params.windowAnimations = R.style.Animation_Toast; + params.type = WindowManager.LayoutParams.TYPE_TOAST; + params.setFitInsetsIgnoringVisibility(true); + params.setTitle("Toast"); + params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; + } + + /** + * Customizes {@code params} according to other parameters, ready to be passed to {@link + * WindowManager#addView(View, ViewGroup.LayoutParams)}. + */ + public void adjustLayoutParams(WindowManager.LayoutParams params, IBinder windowToken, + int duration, int gravity, int xOffset, int yOffset, float horizontalMargin, + float verticalMargin) { + Configuration config = mContext.getResources().getConfiguration(); + int absGravity = Gravity.getAbsoluteGravity(gravity, config.getLayoutDirection()); + params.gravity = absGravity; + if ((absGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { + params.horizontalWeight = 1.0f; + } + if ((absGravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { + params.verticalWeight = 1.0f; + } + params.x = xOffset; + params.y = yOffset; + params.horizontalMargin = horizontalMargin; + params.verticalMargin = verticalMargin; + params.packageName = mContext.getPackageName(); + params.hideTimeoutMilliseconds = + (duration == Toast.LENGTH_LONG) ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT; + params.token = windowToken; + } + + /** + * Returns the default text toast view for message {@code text}. + */ + public View getTextToastView(CharSequence text) { + View view = LayoutInflater.from(mContext).inflate( + R.layout.transient_notification, null); + TextView textView = view.findViewById(com.android.internal.R.id.message); + textView.setText(text); + return view; + } + + /** + * Sends {@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED} event if accessibility is + * enabled. + */ + public void trySendAccessibilityEvent(View view, String packageName) { + if (!mAccessibilityManager.isEnabled()) { + return; + } + AccessibilityEvent event = AccessibilityEvent.obtain( + AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); + event.setClassName(Toast.class.getName()); + event.setPackageName(packageName); + view.dispatchPopulateAccessibilityEvent(event); + mAccessibilityManager.sendAccessibilityEvent(event); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java b/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java index edab4a72d8c8..34a252008500 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java +++ b/packages/SystemUI/src/com/android/systemui/toast/ToastUI.java @@ -21,21 +21,16 @@ import android.annotation.Nullable; import android.app.INotificationManager; import android.app.ITransientNotificationCallback; import android.content.Context; -import android.content.res.Configuration; -import android.graphics.PixelFormat; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; -import android.view.Gravity; -import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; -import android.widget.TextView; import android.widget.Toast; +import android.widget.ToastPresenter; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; @@ -64,6 +59,7 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { private final WindowManager mWindowManager; private final INotificationManager mNotificationManager; private final AccessibilityManager mAccessibilityManager; + private final ToastPresenter mPresenter; private ToastEntry mCurrentToast; @Inject @@ -83,6 +79,7 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { mWindowManager = windowManager; mNotificationManager = notificationManager; mAccessibilityManager = accessibilityManager; + mPresenter = new ToastPresenter(context, accessibilityManager); } @Override @@ -97,7 +94,7 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { if (mCurrentToast != null) { hideCurrentToast(); } - View view = getView(text); + View view = mPresenter.getTextToastView(text); LayoutParams params = getLayoutParams(windowToken, duration); mCurrentToast = new ToastEntry(packageName, token, view, windowToken, callback); try { @@ -106,7 +103,7 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { Log.w(TAG, "Error while attempting to show toast from " + packageName, e); return; } - trySendAccessibilityEvent(view, packageName); + mPresenter.trySendAccessibilityEvent(view, packageName); if (callback != null) { try { callback.onToastShown(); @@ -148,56 +145,13 @@ public class ToastUI extends SystemUI implements CommandQueue.Callbacks { mCurrentToast = null; } - private void trySendAccessibilityEvent(View view, String packageName) { - if (!mAccessibilityManager.isEnabled()) { - return; - } - AccessibilityEvent event = AccessibilityEvent.obtain( - AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED); - event.setClassName(Toast.class.getName()); - event.setPackageName(packageName); - view.dispatchPopulateAccessibilityEvent(event); - mAccessibilityManager.sendAccessibilityEvent(event); - } - - private View getView(CharSequence text) { - View view = LayoutInflater.from(mContext).inflate( - R.layout.transient_notification, null); - TextView textView = view.findViewById(com.android.internal.R.id.message); - textView.setText(text); - return view; - } - private LayoutParams getLayoutParams(IBinder windowToken, int duration) { WindowManager.LayoutParams params = new WindowManager.LayoutParams(); - params.height = WindowManager.LayoutParams.WRAP_CONTENT; - params.width = WindowManager.LayoutParams.WRAP_CONTENT; - params.format = PixelFormat.TRANSLUCENT; - params.windowAnimations = com.android.internal.R.style.Animation_Toast; - params.type = WindowManager.LayoutParams.TYPE_TOAST; - params.setTitle("Toast"); - params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; - Configuration config = mContext.getResources().getConfiguration(); - int specificGravity = mContext.getResources().getInteger( + mPresenter.startLayoutParams(params); + int gravity = mContext.getResources().getInteger( com.android.internal.R.integer.config_toastDefaultGravity); - int gravity = Gravity.getAbsoluteGravity(specificGravity, config.getLayoutDirection()); - params.gravity = gravity; - if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { - params.horizontalWeight = 1.0f; - } - if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { - params.verticalWeight = 1.0f; - } - params.x = 0; - params.y = mContext.getResources().getDimensionPixelSize(R.dimen.toast_y_offset); - params.verticalMargin = 0; - params.horizontalMargin = 0; - params.packageName = mContext.getPackageName(); - params.hideTimeoutMilliseconds = - (duration == Toast.LENGTH_LONG) ? DURATION_LONG : DURATION_SHORT; - params.token = windowToken; + int yOffset = mContext.getResources().getDimensionPixelSize(R.dimen.toast_y_offset); + mPresenter.adjustLayoutParams(params, windowToken, duration, gravity, 0, yOffset, 0, 0); return params; } |