/* * Copyright (C) 2019-2021 crDroid Android Project * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ package com.android.systemui.aicp; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.os.UserHandle; import android.provider.Settings; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.FrameLayout; import android.widget.RelativeLayout; import androidx.palette.graphics.Palette; import com.android.settingslib.Utils; import com.android.systemui.R; public class NotificationLightsView extends RelativeLayout { private static final boolean DEBUG = false; private static final String TAG = "NotificationLightsView"; private View mNotificationAnimView; private ValueAnimator mLightAnimator; private boolean mPulsing; private WallpaperManager mWallManager; private int color; public NotificationLightsView(Context context) { this(context, null); } public NotificationLightsView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public NotificationLightsView(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public NotificationLightsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); if (DEBUG) Log.d(TAG, "new"); } private Runnable mLightUpdate = new Runnable() { @Override public void run() { if (DEBUG) Log.d(TAG, "run"); animateNotification(); } }; public void setPulsing(boolean pulsing) { if (mPulsing == pulsing) { return; } mPulsing = pulsing; } @Override public void draw(Canvas canvas) { super.draw(canvas); if (DEBUG) Log.d(TAG, "draw"); } public void animateNotification() { int customColor = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR, 0xFF3980FF, UserHandle.USER_CURRENT); int duration = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_DURATION, 2, UserHandle.USER_CURRENT) * 1000; int repeat = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_REPEAT_COUNT, 0, UserHandle.USER_CURRENT); boolean directionIsRestart = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_REPEAT_DIRECTION, 0, UserHandle.USER_CURRENT) != 1; int colorMode = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_COLOR_MODE, 1, UserHandle.USER_CURRENT); int width = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.PULSE_AMBIENT_LIGHT_WIDTH, 125, UserHandle.USER_CURRENT); if (colorMode == 0) { try { WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext); Drawable wallpaperDrawable = wallpaperManager.getDrawable(); Bitmap bitmap = ((BitmapDrawable)wallpaperDrawable).getBitmap(); if (bitmap != null) { Palette p = Palette.from(bitmap).generate(); int wallColor = p.getDominantColor(color); if (color != wallColor) color = wallColor; } } catch (Exception e) { // Nothing to do } } else if (colorMode == 1) { color = Utils.getColorAccentDefaultColor(getContext()); } else if (colorMode == 3) { color = randomColor(); } else { color = customColor; } StringBuilder sb = new StringBuilder(); sb.append("animateNotification color "); sb.append(Integer.toHexString(color)); Log.e("NotificationLightsView", sb.toString()); ImageView leftView = (ImageView) findViewById(R.id.notification_animation_left); ImageView rightView = (ImageView) findViewById(R.id.notification_animation_right); leftView.setColorFilter(color); rightView.setColorFilter(color); leftView.getLayoutParams().width = width; rightView.getLayoutParams().width = width; mLightAnimator = ValueAnimator.ofFloat(new float[]{0.0f, 2.0f}); mLightAnimator.setDuration(duration); mLightAnimator.setRepeatCount(repeat); mLightAnimator.setRepeatMode(directionIsRestart ? ValueAnimator.RESTART : ValueAnimator.REVERSE); mLightAnimator.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { if (DEBUG) Log.d(TAG, "onAnimationUpdate"); float progress = ((Float) animation.getAnimatedValue()).floatValue(); leftView.setScaleY(progress); rightView.setScaleY(progress); float alpha = 1.0f; if (progress <= 0.3f) { alpha = progress / 0.3f; } else if (progress >= 1.0f) { alpha = 2.0f - progress; } leftView.setAlpha(alpha); rightView.setAlpha(alpha); } }); if (DEBUG) Log.d(TAG, "start"); mLightAnimator.start(); } private int randomColor() { int red = (int)(Math.random() * 128); int green = (int)(Math.random() * 128); int blue = (int)(Math.random() * 128); int generatedColor = 0xFF000000 | (red << 16) | (green << 8) | blue; if (DEBUG) Log.d(TAG, Integer.toHexString(generatedColor)); return generatedColor; } }