Home | History | Annotate | Download | only in notification
      1 /*
      2  * Copyright (C) 2014 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.notification;
     18 
     19 import android.content.Context;
     20 import android.graphics.Color;
     21 import android.graphics.drawable.ColorDrawable;
     22 import android.graphics.drawable.Drawable;
     23 import android.support.v4.graphics.ColorUtils;
     24 import android.view.NotificationHeaderView;
     25 import android.view.View;
     26 
     27 import com.android.systemui.statusbar.CrossFadeHelper;
     28 import com.android.systemui.statusbar.ExpandableNotificationRow;
     29 import com.android.systemui.statusbar.TransformableView;
     30 
     31 /**
     32  * Wraps the actual notification content view; used to implement behaviors which are different for
     33  * the individual templates and custom views.
     34  */
     35 public abstract class NotificationViewWrapper implements TransformableView {
     36 
     37     protected final View mView;
     38     protected final ExpandableNotificationRow mRow;
     39     private final NotificationDozeHelper mDozer;
     40 
     41     protected boolean mDark;
     42     private int mBackgroundColor = 0;
     43     protected boolean mShouldInvertDark;
     44     protected boolean mDarkInitialized = false;
     45 
     46     public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
     47         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
     48             if ("bigPicture".equals(v.getTag())) {
     49                 return new NotificationBigPictureTemplateViewWrapper(ctx, v, row);
     50             } else if ("bigText".equals(v.getTag())) {
     51                 return new NotificationBigTextTemplateViewWrapper(ctx, v, row);
     52             } else if ("media".equals(v.getTag()) || "bigMediaNarrow".equals(v.getTag())) {
     53                 return new NotificationMediaTemplateViewWrapper(ctx, v, row);
     54             } else if ("messaging".equals(v.getTag())) {
     55                 return new NotificationMessagingTemplateViewWrapper(ctx, v, row);
     56             }
     57             return new NotificationTemplateViewWrapper(ctx, v, row);
     58         } else if (v instanceof NotificationHeaderView) {
     59             return new NotificationHeaderViewWrapper(ctx, v, row);
     60         } else {
     61             return new NotificationCustomViewWrapper(ctx, v, row);
     62         }
     63     }
     64 
     65     protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
     66         mView = view;
     67         mRow = row;
     68         mDozer = createDozer(ctx);
     69         onReinflated();
     70     }
     71 
     72     protected NotificationDozeHelper createDozer(Context ctx) {
     73         return new NotificationDozeHelper();
     74     }
     75 
     76     protected NotificationDozeHelper getDozer() {
     77         return mDozer;
     78     }
     79 
     80     /**
     81      * In dark mode, we draw as little as possible, assuming a black background.
     82      *
     83      * @param dark whether we should display ourselves in dark mode
     84      * @param fade whether to animate the transition if the mode changes
     85      * @param delay if fading, the delay of the animation
     86      */
     87     public void setDark(boolean dark, boolean fade, long delay) {
     88         mDark = dark;
     89         mDarkInitialized = true;
     90     }
     91 
     92     /**
     93      * Notifies this wrapper that the content of the view might have changed.
     94      * @param row the row this wrapper is attached to
     95      */
     96     public void onContentUpdated(ExpandableNotificationRow row) {
     97         mDarkInitialized = false;
     98     }
     99 
    100     public void onReinflated() {
    101         if (shouldClearBackgroundOnReapply()) {
    102             mBackgroundColor = 0;
    103         }
    104         Drawable background = mView.getBackground();
    105         if (background instanceof ColorDrawable) {
    106             mBackgroundColor = ((ColorDrawable) background).getColor();
    107             mView.setBackground(null);
    108         }
    109         mShouldInvertDark = mBackgroundColor == 0 || isColorLight(mBackgroundColor);
    110     }
    111 
    112     protected boolean shouldClearBackgroundOnReapply() {
    113         return true;
    114     }
    115 
    116     private boolean isColorLight(int backgroundColor) {
    117         return Color.alpha(backgroundColor) == 0
    118                 || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
    119     }
    120 
    121     /**
    122      * Update the appearance of the expand button.
    123      *
    124      * @param expandable should this view be expandable
    125      * @param onClickListener the listener to invoke when the expand affordance is clicked on
    126      */
    127     public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {}
    128 
    129     /**
    130      * @return the notification header if it exists
    131      */
    132     public NotificationHeaderView getNotificationHeader() {
    133         return null;
    134     }
    135 
    136     @Override
    137     public TransformState getCurrentState(int fadingView) {
    138         return null;
    139     }
    140 
    141     @Override
    142     public void transformTo(TransformableView notification, Runnable endRunnable) {
    143         // By default we are fading out completely
    144         CrossFadeHelper.fadeOut(mView, endRunnable);
    145     }
    146 
    147     @Override
    148     public void transformTo(TransformableView notification, float transformationAmount) {
    149         CrossFadeHelper.fadeOut(mView, transformationAmount);
    150     }
    151 
    152     @Override
    153     public void transformFrom(TransformableView notification) {
    154         // By default we are fading in completely
    155         CrossFadeHelper.fadeIn(mView);
    156     }
    157 
    158     @Override
    159     public void transformFrom(TransformableView notification, float transformationAmount) {
    160         CrossFadeHelper.fadeIn(mView, transformationAmount);
    161     }
    162 
    163     @Override
    164     public void setVisible(boolean visible) {
    165         mView.animate().cancel();
    166         mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
    167     }
    168 
    169     public int getCustomBackgroundColor() {
    170         // Parent notifications should always use the normal background color
    171         return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor;
    172     }
    173 
    174     public void setLegacy(boolean legacy) {
    175     }
    176 
    177     public void setContentHeight(int contentHeight, int minHeightHint) {
    178     }
    179 
    180     public void setRemoteInputVisible(boolean visible) {
    181     }
    182 
    183     public void setIsChildInGroup(boolean isChildInGroup) {
    184     }
    185 
    186     public boolean isDimmable() {
    187         return true;
    188     }
    189 }
    190