14e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi/* 24e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Copyright (C) 2014 The Android Open Source Project 34e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * 44e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 54e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * you may not use this file except in compliance with the License. 64e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * You may obtain a copy of the License at 74e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * 84e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 94e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * 104e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Unless required by applicable law or agreed to in writing, software 114e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 124e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * See the License for the specific language governing permissions and 144e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * limitations under the License 154e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi */ 164e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 170ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinekpackage com.android.systemui.statusbar.notification; 184e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 19c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinekimport android.animation.Animator; 20c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinekimport android.animation.ValueAnimator; 214e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.content.Context; 22c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinekimport android.graphics.ColorMatrix; 234ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinekimport android.service.notification.StatusBarNotification; 24ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinekimport android.view.NotificationHeaderView; 254e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.view.View; 264e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 27c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinekimport com.android.systemui.Interpolators; 280ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinekimport com.android.systemui.statusbar.CrossFadeHelper; 297d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinekimport com.android.systemui.statusbar.ExpandableNotificationRow; 300ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinekimport com.android.systemui.statusbar.TransformableView; 31c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinekimport com.android.systemui.statusbar.phone.NotificationPanelView; 324ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek 334e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi/** 344e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Wraps the actual notification content view; used to implement behaviors which are different for 354e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * the individual templates and custom views. 364e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi */ 374ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinekpublic abstract class NotificationViewWrapper implements TransformableView { 384e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 39c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix(); 404e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi protected final View mView; 417d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek protected final ExpandableNotificationRow mRow; 4219ba7050c3aaf47f431d33341de7399df776f559Selim Cinek protected boolean mDark; 43b88b98477ae725092c27dfe52f7fca3d4f29913eSelim Cinek protected boolean mDarkInitialized = false; 444e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 457d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) { 46be4116a3471184748bf6545506b59d48c720ea58Jorim Jaggi if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) { 470ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinek if ("bigPicture".equals(v.getTag())) { 487d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationBigPictureTemplateViewWrapper(ctx, v, row); 49d634d069dd484698c6d109525ee0b6e882ca49dfSelim Cinek } else if ("bigText".equals(v.getTag())) { 507d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationBigTextTemplateViewWrapper(ctx, v, row); 51df5bf6147ca8105f4617a815d4c7b92f818de3e8Selim Cinek } else if ("media".equals(v.getTag()) || "bigMediaNarrow".equals(v.getTag())) { 527d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationMediaTemplateViewWrapper(ctx, v, row); 53feafa052f33d97b9bf73cae8aa4074462c399f73Adrian Roos } else if ("messaging".equals(v.getTag())) { 54feafa052f33d97b9bf73cae8aa4074462c399f73Adrian Roos return new NotificationMessagingTemplateViewWrapper(ctx, v, row); 550ffbda62e55ad390e05e6c3ff52e1378e420285cSelim Cinek } 567d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationTemplateViewWrapper(ctx, v, row); 579c7712d45ccec56a80873a83e56a83f810624b43Selim Cinek } else if (v instanceof NotificationHeaderView) { 587d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationHeaderViewWrapper(ctx, v, row); 594e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi } else { 607d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek return new NotificationCustomViewWrapper(v, row); 614e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi } 624e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi } 634e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 647d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek protected NotificationViewWrapper(View view, ExpandableNotificationRow row) { 654e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi mView = view; 667d1c63e66a2e19bf32249f52c56e563eae4c6819Selim Cinek mRow = row; 674e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi } 684e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi 694e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi /** 704e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * In dark mode, we draw as little as possible, assuming a black background. 714e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * 724e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * @param dark whether we should display ourselves in dark mode 734e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * @param fade whether to animate the transition if the mode changes 744e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * @param delay if fading, the delay of the animation 754e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi */ 7619ba7050c3aaf47f431d33341de7399df776f559Selim Cinek public void setDark(boolean dark, boolean fade, long delay) { 7719ba7050c3aaf47f431d33341de7399df776f559Selim Cinek mDark = dark; 78b88b98477ae725092c27dfe52f7fca3d4f29913eSelim Cinek mDarkInitialized = true; 7919ba7050c3aaf47f431d33341de7399df776f559Selim Cinek } 80dacc924a65d68e7888d8771baa14141329265ebfJorim Jaggi 81dacc924a65d68e7888d8771baa14141329265ebfJorim Jaggi /** 82dacc924a65d68e7888d8771baa14141329265ebfJorim Jaggi * Notifies this wrapper that the content of the view might have changed. 834ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek * @param notification 84dacc924a65d68e7888d8771baa14141329265ebfJorim Jaggi */ 8519ba7050c3aaf47f431d33341de7399df776f559Selim Cinek public void notifyContentUpdated(StatusBarNotification notification) { 86b88b98477ae725092c27dfe52f7fca3d4f29913eSelim Cinek mDarkInitialized = false; 8719ba7050c3aaf47f431d33341de7399df776f559Selim Cinek }; 88be4116a3471184748bf6545506b59d48c720ea58Jorim Jaggi 89c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek 90c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek protected void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener, 91c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek boolean dark, long delay, Animator.AnimatorListener listener) { 92c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek float startIntensity = dark ? 0f : 1f; 93c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek float endIntensity = dark ? 1f : 0f; 94c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); 95c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.addUpdateListener(updateListener); 96c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION); 97c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); 98c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.setStartDelay(delay); 99c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek if (listener != null) { 100c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.addListener(listener); 101c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek } 102c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek animator.start(); 103c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek } 104c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek 105c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek protected void updateGrayscaleMatrix(float intensity) { 106c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek mGrayscaleColorMatrix.setSaturation(1 - intensity); 107c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek } 108c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek 109be4116a3471184748bf6545506b59d48c720ea58Jorim Jaggi /** 11065b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek * Update the appearance of the expand button. 11165b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek * 11265b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek * @param expandable should this view be expandable 11365b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek * @param onClickListener the listener to invoke when the expand affordance is clicked on 11465b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek */ 11565b2e7c6cbcd41985ab007eec3a21aad75dfc983Selim Cinek public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {} 116ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek 117ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek /** 118ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek * @return the notification header if it exists 119ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek */ 120ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek public NotificationHeaderView getNotificationHeader() { 121ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek return null; 122ea4bef7386ca6c6260f292bf006d16a99b93f698Selim Cinek } 1234ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek 1244ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek @Override 1254ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek public TransformState getCurrentState(int fadingView) { 1264ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek return null; 1274ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek } 1284ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek 1294ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek @Override 1304ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek public void transformTo(TransformableView notification, Runnable endRunnable) { 1314ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek // By default we are fading out completely 1324ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek CrossFadeHelper.fadeOut(mView, endRunnable); 1334ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek } 1344ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek 1354ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek @Override 1368f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek public void transformTo(TransformableView notification, float transformationAmount) { 1378f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek CrossFadeHelper.fadeOut(mView, transformationAmount); 1388f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek } 1398f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek 1408f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek @Override 1414ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek public void transformFrom(TransformableView notification) { 1424ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek // By default we are fading in completely 1434ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek CrossFadeHelper.fadeIn(mView); 1444ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek } 1454ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek 1464ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek @Override 1478f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek public void transformFrom(TransformableView notification, float transformationAmount) { 1488f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek CrossFadeHelper.fadeIn(mView, transformationAmount); 1498f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek } 1508f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek 1518f2f6a67fad7aed720e33a6629cb65d368ebfb80Selim Cinek @Override 1524ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek public void setVisible(boolean visible) { 153f64044c6a4e1d34595c9a9bc26ca949b54a93288Selim Cinek mView.animate().cancel(); 1544ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 1554ffd63611a0d516c9988b37e9c06e6f8390c2a2fSelim Cinek } 156c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek 157c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek public int getCustomBackgroundColor() { 158c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek return 0; 159c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek } 160c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek 161c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek public void setShowingLegacyBackground(boolean showing) { 162c317933a91b1d33cc4af9b7c6218b9ce675d05eaSelim Cinek } 163181385ce33c83a249087a1cff65870dfe120aae8Adrian Roos 164181385ce33c83a249087a1cff65870dfe120aae8Adrian Roos public void setContentHeight(int contentHeight, int minHeightHint) { 165181385ce33c83a249087a1cff65870dfe120aae8Adrian Roos } 1664e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi} 167