Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.systemui.statusbar.phone;
     18 
     19 import android.annotation.ColorInt;
     20 import android.annotation.DrawableRes;
     21 import android.annotation.LayoutRes;
     22 import android.app.StatusBarManager;
     23 import android.content.Context;
     24 import android.content.res.Configuration;
     25 import android.content.res.TypedArray;
     26 import android.graphics.Canvas;
     27 import android.graphics.Paint;
     28 import android.graphics.PorterDuff;
     29 import android.graphics.PorterDuffXfermode;
     30 import android.graphics.Rect;
     31 import android.graphics.drawable.Drawable;
     32 import android.media.AudioManager;
     33 import android.media.session.MediaSessionLegacyHelper;
     34 import android.net.Uri;
     35 import android.os.Bundle;
     36 import android.os.IBinder;
     37 import android.os.SystemClock;
     38 import android.util.AttributeSet;
     39 import android.view.ActionMode;
     40 import android.view.InputDevice;
     41 import android.view.InputQueue;
     42 import android.view.KeyEvent;
     43 import android.view.LayoutInflater;
     44 import android.view.Menu;
     45 import android.view.MenuItem;
     46 import android.view.MotionEvent;
     47 import android.view.SurfaceHolder;
     48 import android.view.View;
     49 import android.view.ViewGroup;
     50 import android.view.ViewTreeObserver;
     51 import android.view.Window;
     52 import android.view.WindowManager;
     53 import android.view.WindowManagerGlobal;
     54 import android.widget.FrameLayout;
     55 
     56 import com.android.internal.annotations.VisibleForTesting;
     57 import com.android.internal.view.FloatingActionMode;
     58 import com.android.internal.widget.FloatingToolbar;
     59 import com.android.systemui.R;
     60 import com.android.systemui.classifier.FalsingManager;
     61 import com.android.systemui.statusbar.DragDownHelper;
     62 import com.android.systemui.statusbar.StatusBarState;
     63 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
     64 
     65 import java.io.FileDescriptor;
     66 import java.io.PrintWriter;
     67 
     68 
     69 public class StatusBarWindowView extends FrameLayout {
     70     public static final String TAG = "StatusBarWindowView";
     71     public static final boolean DEBUG = StatusBar.DEBUG;
     72 
     73     private DragDownHelper mDragDownHelper;
     74     private DoubleTapHelper mDoubleTapHelper;
     75     private NotificationStackScrollLayout mStackScrollLayout;
     76     private NotificationPanelView mNotificationPanel;
     77     private View mBrightnessMirror;
     78 
     79     private int mRightInset = 0;
     80     private int mLeftInset = 0;
     81 
     82     private StatusBar mService;
     83     private final Paint mTransparentSrcPaint = new Paint();
     84     private FalsingManager mFalsingManager;
     85 
     86     // Implements the floating action mode for TextView's Cut/Copy/Past menu. Normally provided by
     87     // DecorView, but since this is a special window we have to roll our own.
     88     private View mFloatingActionModeOriginatingView;
     89     private ActionMode mFloatingActionMode;
     90     private FloatingToolbar mFloatingToolbar;
     91     private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
     92     private boolean mTouchCancelled;
     93     private boolean mTouchActive;
     94     private boolean mExpandAnimationRunning;
     95     private boolean mExpandAnimationPending;
     96 
     97     public StatusBarWindowView(Context context, AttributeSet attrs) {
     98         super(context, attrs);
     99         setMotionEventSplittingEnabled(false);
    100         mTransparentSrcPaint.setColor(0);
    101         mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
    102         mFalsingManager = FalsingManager.getInstance(context);
    103         mDoubleTapHelper = new DoubleTapHelper(this, active -> {}, () -> {
    104             mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this);
    105             return true;
    106         }, null, null);
    107     }
    108 
    109     @Override
    110     protected boolean fitSystemWindows(Rect insets) {
    111         if (getFitsSystemWindows()) {
    112             boolean paddingChanged = insets.top != getPaddingTop()
    113                     || insets.bottom != getPaddingBottom();
    114 
    115             // Super-special right inset handling, because scrims and backdrop need to ignore it.
    116             if (insets.right != mRightInset || insets.left != mLeftInset) {
    117                 mRightInset = insets.right;
    118                 mLeftInset = insets.left;
    119                 applyMargins();
    120             }
    121             // Drop top inset, and pass through bottom inset.
    122             if (paddingChanged) {
    123                 setPadding(0, 0, 0, 0);
    124             }
    125             insets.left = 0;
    126             insets.top = 0;
    127             insets.right = 0;
    128         } else {
    129             if (mRightInset != 0 || mLeftInset != 0) {
    130                 mRightInset = 0;
    131                 mLeftInset = 0;
    132                 applyMargins();
    133             }
    134             boolean changed = getPaddingLeft() != 0
    135                     || getPaddingRight() != 0
    136                     || getPaddingTop() != 0
    137                     || getPaddingBottom() != 0;
    138             if (changed) {
    139                 setPadding(0, 0, 0, 0);
    140             }
    141             insets.top = 0;
    142         }
    143         return false;
    144     }
    145 
    146     private void applyMargins() {
    147         final int N = getChildCount();
    148         for (int i = 0; i < N; i++) {
    149             View child = getChildAt(i);
    150             if (child.getLayoutParams() instanceof LayoutParams) {
    151                 LayoutParams lp = (LayoutParams) child.getLayoutParams();
    152                 if (!lp.ignoreRightInset
    153                         && (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {
    154                     lp.rightMargin = mRightInset;
    155                     lp.leftMargin = mLeftInset;
    156                     child.requestLayout();
    157                 }
    158             }
    159         }
    160     }
    161 
    162     @Override
    163     public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
    164         return new LayoutParams(getContext(), attrs);
    165     }
    166 
    167     @Override
    168     protected FrameLayout.LayoutParams generateDefaultLayoutParams() {
    169         return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    170     }
    171 
    172     @Override
    173     protected void onFinishInflate() {
    174         super.onFinishInflate();
    175         mStackScrollLayout = (NotificationStackScrollLayout) findViewById(
    176                 R.id.notification_stack_scroller);
    177         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
    178         mBrightnessMirror = findViewById(R.id.brightness_mirror);
    179     }
    180 
    181     @Override
    182     public void onViewAdded(View child) {
    183         super.onViewAdded(child);
    184         if (child.getId() == R.id.brightness_mirror) {
    185             mBrightnessMirror = child;
    186         }
    187     }
    188 
    189     public void setService(StatusBar service) {
    190         mService = service;
    191         setDragDownHelper(new DragDownHelper(getContext(), this, mStackScrollLayout, mService));
    192     }
    193 
    194     @VisibleForTesting
    195     void setDragDownHelper(DragDownHelper dragDownHelper) {
    196         mDragDownHelper = dragDownHelper;
    197     }
    198 
    199     @Override
    200     protected void onAttachedToWindow () {
    201         super.onAttachedToWindow();
    202 
    203         // We need to ensure that our window doesn't suffer from overdraw which would normally
    204         // occur if our window is translucent. Since we are drawing the whole window anyway with
    205         // the scrim, we don't need the window to be cleared in the beginning.
    206         if (mService.isScrimSrcModeEnabled()) {
    207             IBinder windowToken = getWindowToken();
    208             WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
    209             lp.token = windowToken;
    210             setLayoutParams(lp);
    211             WindowManagerGlobal.getInstance().changeCanvasOpacity(windowToken, true);
    212             setWillNotDraw(false);
    213         } else {
    214             setWillNotDraw(!DEBUG);
    215         }
    216     }
    217 
    218     @Override
    219     public boolean dispatchKeyEvent(KeyEvent event) {
    220         if (mService.interceptMediaKey(event)) {
    221             return true;
    222         }
    223         if (super.dispatchKeyEvent(event)) {
    224             return true;
    225         }
    226         boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
    227         switch (event.getKeyCode()) {
    228             case KeyEvent.KEYCODE_BACK:
    229                 if (!down) {
    230                     mService.onBackPressed();
    231                 }
    232                 return true;
    233             case KeyEvent.KEYCODE_MENU:
    234                 if (!down) {
    235                     return mService.onMenuPressed();
    236                 }
    237             case KeyEvent.KEYCODE_SPACE:
    238                 if (!down) {
    239                     return mService.onSpacePressed();
    240                 }
    241                 break;
    242             case KeyEvent.KEYCODE_VOLUME_DOWN:
    243             case KeyEvent.KEYCODE_VOLUME_UP:
    244                 if (mService.isDozing()) {
    245                     MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(
    246                             event, AudioManager.USE_DEFAULT_STREAM_TYPE, true);
    247                     return true;
    248                 }
    249                 break;
    250         }
    251         return false;
    252     }
    253 
    254     public void setTouchActive(boolean touchActive) {
    255         mTouchActive = touchActive;
    256     }
    257 
    258     @Override
    259     public boolean dispatchTouchEvent(MotionEvent ev) {
    260         boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN;
    261         boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL;
    262         if (!isCancel && mService.shouldIgnoreTouch()) {
    263             return false;
    264         }
    265         if (isDown && mNotificationPanel.isFullyCollapsed()) {
    266             mNotificationPanel.startExpandLatencyTracking();
    267         }
    268         if (isDown) {
    269             setTouchActive(true);
    270             mTouchCancelled = false;
    271         } else if (ev.getActionMasked() == MotionEvent.ACTION_UP
    272                 || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) {
    273             setTouchActive(false);
    274         }
    275         if (mTouchCancelled || mExpandAnimationRunning || mExpandAnimationPending) {
    276             return false;
    277         }
    278         mFalsingManager.onTouchEvent(ev, getWidth(), getHeight());
    279         if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
    280             // Disallow new pointers while the brightness mirror is visible. This is so that you
    281             // can't touch anything other than the brightness slider while the mirror is showing
    282             // and the rest of the panel is transparent.
    283             if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
    284                 return false;
    285             }
    286         }
    287         if (isDown) {
    288             mStackScrollLayout.closeControlsIfOutsideTouch(ev);
    289         }
    290         if (mService.isDozing()) {
    291             mService.mDozeScrimController.extendPulse();
    292         }
    293 
    294         return super.dispatchTouchEvent(ev);
    295     }
    296 
    297     @Override
    298     public boolean onInterceptTouchEvent(MotionEvent ev) {
    299         if (mService.isDozing() && !mStackScrollLayout.hasPulsingNotifications()) {
    300             // Capture all touch events in always-on.
    301             return true;
    302         }
    303         boolean intercept = false;
    304         if (mNotificationPanel.isFullyExpanded()
    305                 && mStackScrollLayout.getVisibility() == View.VISIBLE
    306                 && mService.getBarState() == StatusBarState.KEYGUARD
    307                 && !mService.isBouncerShowing()
    308                 && !mService.isDozing()) {
    309             intercept = mDragDownHelper.onInterceptTouchEvent(ev);
    310         }
    311         if (!intercept) {
    312             super.onInterceptTouchEvent(ev);
    313         }
    314         if (intercept) {
    315             MotionEvent cancellation = MotionEvent.obtain(ev);
    316             cancellation.setAction(MotionEvent.ACTION_CANCEL);
    317             mStackScrollLayout.onInterceptTouchEvent(cancellation);
    318             mNotificationPanel.onInterceptTouchEvent(cancellation);
    319             cancellation.recycle();
    320         }
    321         return intercept;
    322     }
    323 
    324     @Override
    325     public boolean onTouchEvent(MotionEvent ev) {
    326         boolean handled = false;
    327         if (mService.isDozing()) {
    328             mDoubleTapHelper.onTouchEvent(ev);
    329             handled = true;
    330         }
    331         if ((mService.getBarState() == StatusBarState.KEYGUARD && !handled)
    332                 || mDragDownHelper.isDraggingDown()) {
    333             // we still want to finish our drag down gesture when locking the screen
    334             handled = mDragDownHelper.onTouchEvent(ev);
    335         }
    336         if (!handled) {
    337             handled = super.onTouchEvent(ev);
    338         }
    339         final int action = ev.getAction();
    340         if (!handled && (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL)) {
    341             mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
    342         }
    343         return handled;
    344     }
    345 
    346     @Override
    347     public void onDraw(Canvas canvas) {
    348         super.onDraw(canvas);
    349         if (mService.isScrimSrcModeEnabled()) {
    350             // We need to ensure that our window is always drawn fully even when we have paddings,
    351             // since we simulate it to be opaque.
    352             int paddedBottom = getHeight() - getPaddingBottom();
    353             int paddedRight = getWidth() - getPaddingRight();
    354             if (getPaddingTop() != 0) {
    355                 canvas.drawRect(0, 0, getWidth(), getPaddingTop(), mTransparentSrcPaint);
    356             }
    357             if (getPaddingBottom() != 0) {
    358                 canvas.drawRect(0, paddedBottom, getWidth(), getHeight(), mTransparentSrcPaint);
    359             }
    360             if (getPaddingLeft() != 0) {
    361                 canvas.drawRect(0, getPaddingTop(), getPaddingLeft(), paddedBottom,
    362                         mTransparentSrcPaint);
    363             }
    364             if (getPaddingRight() != 0) {
    365                 canvas.drawRect(paddedRight, getPaddingTop(), getWidth(), paddedBottom,
    366                         mTransparentSrcPaint);
    367             }
    368         }
    369         if (DEBUG) {
    370             Paint pt = new Paint();
    371             pt.setColor(0x80FFFF00);
    372             pt.setStrokeWidth(12.0f);
    373             pt.setStyle(Paint.Style.STROKE);
    374             canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), pt);
    375         }
    376     }
    377 
    378     public void cancelExpandHelper() {
    379         if (mStackScrollLayout != null) {
    380             mStackScrollLayout.cancelExpandHelper();
    381         }
    382     }
    383 
    384     public void cancelCurrentTouch() {
    385         if (mTouchActive) {
    386             final long now = SystemClock.uptimeMillis();
    387             MotionEvent event = MotionEvent.obtain(now, now,
    388                     MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
    389             event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
    390             dispatchTouchEvent(event);
    391             event.recycle();
    392             mTouchCancelled = true;
    393         }
    394     }
    395 
    396     public void setExpandAnimationRunning(boolean expandAnimationRunning) {
    397         mExpandAnimationRunning = expandAnimationRunning;
    398     }
    399 
    400     public void setExpandAnimationPending(boolean pending) {
    401         mExpandAnimationPending = pending;
    402     }
    403 
    404     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    405         pw.print("  mExpandAnimationPending="); pw.println(mExpandAnimationPending);
    406         pw.print("  mExpandAnimationRunning="); pw.println(mExpandAnimationRunning);
    407         pw.print("  mTouchCancelled="); pw.println(mTouchCancelled);
    408         pw.print("  mTouchActive="); pw.println(mTouchActive);
    409     }
    410 
    411     public class LayoutParams extends FrameLayout.LayoutParams {
    412 
    413         public boolean ignoreRightInset;
    414 
    415         public LayoutParams(int width, int height) {
    416             super(width, height);
    417         }
    418 
    419         public LayoutParams(Context c, AttributeSet attrs) {
    420             super(c, attrs);
    421 
    422             TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.StatusBarWindowView_Layout);
    423             ignoreRightInset = a.getBoolean(
    424                     R.styleable.StatusBarWindowView_Layout_ignoreRightInset, false);
    425             a.recycle();
    426         }
    427     }
    428 
    429     @Override
    430     public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback,
    431             int type) {
    432         if (type == ActionMode.TYPE_FLOATING) {
    433             return startActionMode(originalView, callback, type);
    434         }
    435         return super.startActionModeForChild(originalView, callback, type);
    436     }
    437 
    438     private ActionMode createFloatingActionMode(
    439             View originatingView, ActionMode.Callback2 callback) {
    440         if (mFloatingActionMode != null) {
    441             mFloatingActionMode.finish();
    442         }
    443         cleanupFloatingActionModeViews();
    444         mFloatingToolbar = new FloatingToolbar(mFakeWindow);
    445         final FloatingActionMode mode =
    446                 new FloatingActionMode(mContext, callback, originatingView, mFloatingToolbar);
    447         mFloatingActionModeOriginatingView = originatingView;
    448         mFloatingToolbarPreDrawListener =
    449                 new ViewTreeObserver.OnPreDrawListener() {
    450                     @Override
    451                     public boolean onPreDraw() {
    452                         mode.updateViewLocationInWindow();
    453                         return true;
    454                     }
    455                 };
    456         return mode;
    457     }
    458 
    459     private void setHandledFloatingActionMode(ActionMode mode) {
    460         mFloatingActionMode = mode;
    461         mFloatingActionMode.invalidate();  // Will show the floating toolbar if necessary.
    462         mFloatingActionModeOriginatingView.getViewTreeObserver()
    463                 .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
    464     }
    465 
    466     private void cleanupFloatingActionModeViews() {
    467         if (mFloatingToolbar != null) {
    468             mFloatingToolbar.dismiss();
    469             mFloatingToolbar = null;
    470         }
    471         if (mFloatingActionModeOriginatingView != null) {
    472             if (mFloatingToolbarPreDrawListener != null) {
    473                 mFloatingActionModeOriginatingView.getViewTreeObserver()
    474                         .removeOnPreDrawListener(mFloatingToolbarPreDrawListener);
    475                 mFloatingToolbarPreDrawListener = null;
    476             }
    477             mFloatingActionModeOriginatingView = null;
    478         }
    479     }
    480 
    481     private ActionMode startActionMode(
    482             View originatingView, ActionMode.Callback callback, int type) {
    483         ActionMode.Callback2 wrappedCallback = new ActionModeCallback2Wrapper(callback);
    484         ActionMode mode = createFloatingActionMode(originatingView, wrappedCallback);
    485         if (mode != null && wrappedCallback.onCreateActionMode(mode, mode.getMenu())) {
    486             setHandledFloatingActionMode(mode);
    487         } else {
    488             mode = null;
    489         }
    490         return mode;
    491     }
    492 
    493     private class ActionModeCallback2Wrapper extends ActionMode.Callback2 {
    494         private final ActionMode.Callback mWrapped;
    495 
    496         public ActionModeCallback2Wrapper(ActionMode.Callback wrapped) {
    497             mWrapped = wrapped;
    498         }
    499 
    500         public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    501             return mWrapped.onCreateActionMode(mode, menu);
    502         }
    503 
    504         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    505             requestFitSystemWindows();
    506             return mWrapped.onPrepareActionMode(mode, menu);
    507         }
    508 
    509         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    510             return mWrapped.onActionItemClicked(mode, item);
    511         }
    512 
    513         public void onDestroyActionMode(ActionMode mode) {
    514             mWrapped.onDestroyActionMode(mode);
    515             if (mode == mFloatingActionMode) {
    516                 cleanupFloatingActionModeViews();
    517                 mFloatingActionMode = null;
    518             }
    519             requestFitSystemWindows();
    520         }
    521 
    522         @Override
    523         public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
    524             if (mWrapped instanceof ActionMode.Callback2) {
    525                 ((ActionMode.Callback2) mWrapped).onGetContentRect(mode, view, outRect);
    526             } else {
    527                 super.onGetContentRect(mode, view, outRect);
    528             }
    529         }
    530     }
    531 
    532     /**
    533      * Minimal window to satisfy FloatingToolbar.
    534      */
    535     private Window mFakeWindow = new Window(mContext) {
    536         @Override
    537         public void takeSurface(SurfaceHolder.Callback2 callback) {
    538         }
    539 
    540         @Override
    541         public void takeInputQueue(InputQueue.Callback callback) {
    542         }
    543 
    544         @Override
    545         public boolean isFloating() {
    546             return false;
    547         }
    548 
    549         @Override
    550         public void alwaysReadCloseOnTouchAttr() {
    551         }
    552 
    553         @Override
    554         public void setContentView(@LayoutRes int layoutResID) {
    555         }
    556 
    557         @Override
    558         public void setContentView(View view) {
    559         }
    560 
    561         @Override
    562         public void setContentView(View view, ViewGroup.LayoutParams params) {
    563         }
    564 
    565         @Override
    566         public void addContentView(View view, ViewGroup.LayoutParams params) {
    567         }
    568 
    569         @Override
    570         public void clearContentView() {
    571         }
    572 
    573         @Override
    574         public View getCurrentFocus() {
    575             return null;
    576         }
    577 
    578         @Override
    579         public LayoutInflater getLayoutInflater() {
    580             return null;
    581         }
    582 
    583         @Override
    584         public void setTitle(CharSequence title) {
    585         }
    586 
    587         @Override
    588         public void setTitleColor(@ColorInt int textColor) {
    589         }
    590 
    591         @Override
    592         public void openPanel(int featureId, KeyEvent event) {
    593         }
    594 
    595         @Override
    596         public void closePanel(int featureId) {
    597         }
    598 
    599         @Override
    600         public void togglePanel(int featureId, KeyEvent event) {
    601         }
    602 
    603         @Override
    604         public void invalidatePanelMenu(int featureId) {
    605         }
    606 
    607         @Override
    608         public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
    609             return false;
    610         }
    611 
    612         @Override
    613         public boolean performPanelIdentifierAction(int featureId, int id, int flags) {
    614             return false;
    615         }
    616 
    617         @Override
    618         public void closeAllPanels() {
    619         }
    620 
    621         @Override
    622         public boolean performContextMenuIdentifierAction(int id, int flags) {
    623             return false;
    624         }
    625 
    626         @Override
    627         public void onConfigurationChanged(Configuration newConfig) {
    628         }
    629 
    630         @Override
    631         public void setBackgroundDrawable(Drawable drawable) {
    632         }
    633 
    634         @Override
    635         public void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
    636         }
    637 
    638         @Override
    639         public void setFeatureDrawableUri(int featureId, Uri uri) {
    640         }
    641 
    642         @Override
    643         public void setFeatureDrawable(int featureId, Drawable drawable) {
    644         }
    645 
    646         @Override
    647         public void setFeatureDrawableAlpha(int featureId, int alpha) {
    648         }
    649 
    650         @Override
    651         public void setFeatureInt(int featureId, int value) {
    652         }
    653 
    654         @Override
    655         public void takeKeyEvents(boolean get) {
    656         }
    657 
    658         @Override
    659         public boolean superDispatchKeyEvent(KeyEvent event) {
    660             return false;
    661         }
    662 
    663         @Override
    664         public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
    665             return false;
    666         }
    667 
    668         @Override
    669         public boolean superDispatchTouchEvent(MotionEvent event) {
    670             return false;
    671         }
    672 
    673         @Override
    674         public boolean superDispatchTrackballEvent(MotionEvent event) {
    675             return false;
    676         }
    677 
    678         @Override
    679         public boolean superDispatchGenericMotionEvent(MotionEvent event) {
    680             return false;
    681         }
    682 
    683         @Override
    684         public View getDecorView() {
    685             return StatusBarWindowView.this;
    686         }
    687 
    688         @Override
    689         public View peekDecorView() {
    690             return null;
    691         }
    692 
    693         @Override
    694         public Bundle saveHierarchyState() {
    695             return null;
    696         }
    697 
    698         @Override
    699         public void restoreHierarchyState(Bundle savedInstanceState) {
    700         }
    701 
    702         @Override
    703         protected void onActive() {
    704         }
    705 
    706         @Override
    707         public void setChildDrawable(int featureId, Drawable drawable) {
    708         }
    709 
    710         @Override
    711         public void setChildInt(int featureId, int value) {
    712         }
    713 
    714         @Override
    715         public boolean isShortcutKey(int keyCode, KeyEvent event) {
    716             return false;
    717         }
    718 
    719         @Override
    720         public void setVolumeControlStream(int streamType) {
    721         }
    722 
    723         @Override
    724         public int getVolumeControlStream() {
    725             return 0;
    726         }
    727 
    728         @Override
    729         public int getStatusBarColor() {
    730             return 0;
    731         }
    732 
    733         @Override
    734         public void setStatusBarColor(@ColorInt int color) {
    735         }
    736 
    737         @Override
    738         public int getNavigationBarColor() {
    739             return 0;
    740         }
    741 
    742         @Override
    743         public void setNavigationBarColor(@ColorInt int color) {
    744         }
    745 
    746         @Override
    747         public void setDecorCaptionShade(int decorCaptionShade) {
    748         }
    749 
    750         @Override
    751         public void setResizingCaptionDrawable(Drawable drawable) {
    752         }
    753 
    754         @Override
    755         public void onMultiWindowModeChanged() {
    756         }
    757 
    758         @Override
    759         public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
    760         }
    761 
    762         @Override
    763         public void reportActivityRelaunched() {
    764         }
    765     };
    766 
    767 }
    768 
    769