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