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