You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
594 lines
20 KiB
Java
594 lines
20 KiB
Java
package name.mikanoshi.customiuizer.utils;
|
|
|
|
import android.animation.ObjectAnimator;
|
|
import android.animation.ValueAnimator;
|
|
import android.content.Context;
|
|
import android.content.res.Configuration;
|
|
import android.content.res.Resources;
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.BlurMaskFilter;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Color;
|
|
import android.graphics.CornerPathEffect;
|
|
import android.graphics.DashPathEffect;
|
|
import android.graphics.LinearGradient;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Path;
|
|
import android.graphics.Shader;
|
|
import android.media.audiofx.Visualizer;
|
|
import android.net.Uri;
|
|
import android.os.AsyncTask;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.util.AttributeSet;
|
|
import android.view.View;
|
|
import android.view.animation.AccelerateInterpolator;
|
|
import android.view.animation.DecelerateInterpolator;
|
|
|
|
import java.io.File;
|
|
|
|
import de.robv.android.xposed.XposedBridge;
|
|
import de.robv.android.xposed.XposedHelpers;
|
|
import name.mikanoshi.customiuizer.MainModule;
|
|
|
|
public class AudioVisualizer extends View {
|
|
|
|
private int mHeight;
|
|
private int mWidth;
|
|
private final float mDensity;
|
|
private final Paint mPaint;
|
|
private Paint mGlowPaint;
|
|
private Visualizer mVisualizer;
|
|
private ObjectAnimator mVisualizerColorAnimator;
|
|
private ObjectAnimator mVisualizerGlowColorAnimator;
|
|
|
|
private final ValueAnimator[] mValueAnimators;
|
|
private final float[] mFFTPoints;
|
|
private final float[] mBands = {50, 90, 130, 180, 220, 260, 320, 380, 430, 520, 610, 700, 770, 920, 1080, 1270, 1480, 1720, 2000, 2320, 2700, 3135, 3700, 4400, 5300, 6400, 7700, 9500, 10500, 12000, 16000};
|
|
private float maxDb = 50;
|
|
private final int maxDp = 280;
|
|
|
|
private boolean isMusicPlaying = false;
|
|
public boolean isScreenOn = false;
|
|
private boolean isOnKeyguard = false;
|
|
private boolean isExpandedPanel = false;
|
|
private boolean isOnCustomLockScreen = false;
|
|
private boolean mPlaying;
|
|
private boolean mDisplaying;
|
|
private int mOpaqueColor;
|
|
private int mColor;
|
|
private final Handler mHandler;
|
|
private Bitmap mArt;
|
|
private Bitmap mProcessedArt;
|
|
private final int mBandsNum = 31;
|
|
private final int[] mRainbow = new int[mBandsNum];
|
|
private final int[] mRainbowVertical = new int[mBandsNum];
|
|
private final float[] mPositions = new float[mBandsNum];
|
|
private final Path mLinePath = new Path();
|
|
public boolean showOnCustom;
|
|
private int animDur;
|
|
private int transparency;
|
|
public ColorMode colorMode;
|
|
public BarStyle barStyle;
|
|
public RenderType renderType;
|
|
public int glowLevel;
|
|
public int customColor;
|
|
private int randomizeInterval;
|
|
public boolean showInDrawer;
|
|
public boolean showWithControllerOnly;
|
|
|
|
private final AccelerateInterpolator accel = new AccelerateInterpolator();
|
|
private final DecelerateInterpolator decel = new DecelerateInterpolator();
|
|
private final Runnable randomizeColor = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (colorMode != ColorMode.DYNAMIC) return;
|
|
setColor(getRandomColor());
|
|
mHandler.removeCallbacks(randomizeColor);
|
|
mHandler.postDelayed(randomizeColor, randomizeInterval);
|
|
}
|
|
};
|
|
|
|
int getRandomColor() {
|
|
return Color.HSVToColor(new float[] {(float)(Math.random() * 360f), (float)(0.5f + Math.random() * 0.5f), (float)(0.75f + Math.random() * 0.25f) });
|
|
}
|
|
|
|
enum BarStyle {
|
|
DUMMY, SOLID, SOLID_ROUNDED, DASHED, CIRCLES, LINE
|
|
}
|
|
|
|
enum ColorMode {
|
|
DUMMY, MATCH, STATIC, RAINBOW_H, RAINBOW_V, DYNAMIC
|
|
}
|
|
|
|
enum RenderType {
|
|
AUTO, LINES, PATH
|
|
}
|
|
|
|
public static boolean allZeros(byte[] array) {
|
|
for (byte item: array) if (item != 0) return false;
|
|
return true;
|
|
}
|
|
|
|
private final Visualizer.OnDataCaptureListener mVisualizerListener = new Visualizer.OnDataCaptureListener() {
|
|
byte real, imaginary;
|
|
int dbValue;
|
|
float magnitude;
|
|
|
|
@Override
|
|
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) {}
|
|
|
|
@Override
|
|
public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
|
|
try {
|
|
float bandWidth = (float)samplingRate / (float)fft.length;
|
|
int band = 0;
|
|
int i = 1;
|
|
float maxHeight = Math.min(maxDp * mDensity, mHeight / 2.0f);
|
|
|
|
while (band < mBandsNum && i < fft.length / 2) {
|
|
//int n = 0;
|
|
magnitude = 0;
|
|
|
|
if (!allZeros(fft))
|
|
while (i < fft.length / 2 && (i * bandWidth <= mBands[band] * samplingRate / 44100f)) {
|
|
real = fft[i * 2];
|
|
imaginary = fft[i * 2 + 1];
|
|
magnitude = Math.max(magnitude, real * real + imaginary * imaginary);
|
|
//n++;
|
|
i++;
|
|
}
|
|
//magnitude /= n;
|
|
|
|
//float amp = 0.75f + 0.5f * band / 31f;
|
|
dbValue = magnitude > 0 ? (int)(10 * Math.log10(magnitude)) : 0;
|
|
maxDb = Math.max(maxDb, dbValue);
|
|
float oldVal = mFFTPoints[band * 4 + 3];
|
|
float newVal = mFFTPoints[band * 4 + 1] - maxHeight * dbValue / maxDb;
|
|
|
|
mValueAnimators[band].cancel();
|
|
mValueAnimators[band].setInterpolator(newVal < oldVal ? decel : accel);
|
|
mValueAnimators[band].setFloatValues(oldVal, newVal);
|
|
mValueAnimators[band].start();
|
|
|
|
band++;
|
|
}
|
|
} catch (Throwable t) {
|
|
XposedBridge.log(t);
|
|
}
|
|
}
|
|
};
|
|
|
|
private final Runnable mLinkVisualizer = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
mVisualizer = new Visualizer(0);
|
|
mVisualizer.setEnabled(false);
|
|
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
|
|
mVisualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
|
|
mVisualizer.setDataCaptureListener(mVisualizerListener, Visualizer.getMaxCaptureRate(), false, true);
|
|
mVisualizer.setEnabled(true);
|
|
} catch (Throwable t){
|
|
XposedBridge.log(t);
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
private final Runnable mUnlinkVisualizer = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (mVisualizer != null) try {
|
|
mVisualizer.setEnabled(false);
|
|
mVisualizer.release();
|
|
mVisualizer = null;
|
|
} catch (Throwable t){
|
|
XposedBridge.log(t);
|
|
}
|
|
}
|
|
};
|
|
|
|
private void updateGlowPaint() {
|
|
mGlowPaint = new Paint(mPaint);
|
|
if (glowLevel == 0) return;
|
|
float scale = glowLevel / 100f;
|
|
mGlowPaint.setPathEffect(null);
|
|
mGlowPaint.setMaskFilter(new BlurMaskFilter(15 * mDensity * (1.25f + 0.25f * scale), BlurMaskFilter.Blur.NORMAL));
|
|
mGlowPaint.setAlpha(Math.min(transparency, 180));
|
|
mGlowPaint.setStrokeWidth((0.5f + 1.25f * scale) * mPaint.getStrokeWidth() * (barStyle == BarStyle.LINE ? 4f : (colorMode == ColorMode.RAINBOW_H ? 1.15f : 1.3f)));
|
|
if (barStyle == BarStyle.SOLID || barStyle == BarStyle.DASHED || mGlowPaint.getStrokeCap() == Paint.Cap.ROUND)
|
|
mGlowPaint.setStrokeCap(Paint.Cap.SQUARE);
|
|
}
|
|
|
|
public AudioVisualizer(Context context, AttributeSet attrs, int defStyle) {
|
|
super(context, attrs, defStyle);
|
|
setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
|
|
|
Resources res = context.getResources();
|
|
mHeight = res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? res.getDisplayMetrics().heightPixels : res.getDisplayMetrics().widthPixels;
|
|
mWidth = res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? res.getDisplayMetrics().widthPixels : res.getDisplayMetrics().heightPixels;
|
|
mDensity = res.getDisplayMetrics().density;
|
|
mColor = Color.TRANSPARENT;
|
|
mOpaqueColor = Color.TRANSPARENT;
|
|
|
|
mPaint = new Paint();
|
|
mPaint.setAntiAlias(true);
|
|
mPaint.setStyle(Paint.Style.STROKE);
|
|
mPaint.setStrokeJoin(Paint.Join.MITER);
|
|
mPaint.setColor(mColor);
|
|
|
|
animDur = Helpers.getSharedIntPref(context, "pref_key_system_visualizer_animdur", 65);
|
|
mFFTPoints = new float[128];
|
|
mValueAnimators = new ValueAnimator[mBandsNum];
|
|
for (int i = 0; i < mBandsNum; i++) {
|
|
final int j = i * 4 + 3;
|
|
mValueAnimators[i] = new ValueAnimator();
|
|
mValueAnimators[i].setDuration(animDur);
|
|
mValueAnimators[i].addUpdateListener(animation -> {
|
|
mFFTPoints[j] = (float)animation.getAnimatedValue();
|
|
postInvalidate();
|
|
});
|
|
mPositions[i] = (i + 1) / (float)mBandsNum;
|
|
}
|
|
|
|
showOnCustom = MainModule.mPrefs.getBoolean("system_visualizer_custom");
|
|
transparency = Math.round(255f - 255f * MainModule.mPrefs.getInt("system_visualizer_transp", 40) / 100f);
|
|
colorMode = ColorMode.values()[MainModule.mPrefs.getStringAsInt("system_visualizer_color", 1)];
|
|
barStyle = BarStyle.values()[MainModule.mPrefs.getStringAsInt("system_visualizer_style", 1)];
|
|
renderType = RenderType.values()[MainModule.mPrefs.getStringAsInt("system_visualizer_render", 0)];
|
|
glowLevel = MainModule.mPrefs.getInt("system_visualizer_glowlevel", 50);
|
|
customColor = MainModule.mPrefs.getInt("system_visualizer_colorval", Color.WHITE);
|
|
randomizeInterval = MainModule.mPrefs.getInt("system_visualizer_dyntime", 10) * 1000;
|
|
showInDrawer = MainModule.mPrefs.getBoolean("system_visualizer_drawer");
|
|
showWithControllerOnly = MainModule.mPrefs.getBoolean("system_visualizer_controller");
|
|
updateBarStyle();
|
|
updateGlowPaint();
|
|
updateRainbowColors();
|
|
|
|
mHandler = new Handler(context.getMainLooper());
|
|
new Helpers.SharedPrefObserver(context, mHandler) {
|
|
@Override
|
|
public void onChange(Uri uri) {
|
|
try {
|
|
String key = uri.getPathSegments().get(2);
|
|
switch (key) {
|
|
case "pref_key_system_visualizer_custom":
|
|
showOnCustom = Helpers.getSharedBoolPref(context, key, false);
|
|
break;
|
|
case "pref_key_system_visualizer_animdur":
|
|
animDur = Helpers.getSharedIntPref(context, key, 65);
|
|
for (int i = 0; i < mBandsNum; i++)
|
|
mValueAnimators[i].setDuration(animDur);
|
|
break;
|
|
case "pref_key_system_visualizer_transp":
|
|
transparency = Math.round(255f - 255f * Helpers.getSharedIntPref(context, key, 40) / 100f);
|
|
setColor(mOpaqueColor);
|
|
updateRainbowColors();
|
|
break;
|
|
case "pref_key_system_visualizer_color":
|
|
colorMode = ColorMode.values()[Integer.parseInt(Helpers.getSharedStringPref(context, key, "1"))];
|
|
updateBarStyle();
|
|
updateColorMode();
|
|
break;
|
|
case "pref_key_system_visualizer_style":
|
|
barStyle = BarStyle.values()[Integer.parseInt(Helpers.getSharedStringPref(context, key, "1"))];
|
|
updateBarStyle();
|
|
break;
|
|
case "pref_key_system_visualizer_render":
|
|
renderType = RenderType.values()[Integer.parseInt(Helpers.getSharedStringPref(context, key, "0"))];
|
|
updateBarStyle();
|
|
break;
|
|
case "pref_key_system_visualizer_glowlevel":
|
|
glowLevel = Helpers.getSharedIntPref(context, key, 50);
|
|
updateGlowPaint();
|
|
break;
|
|
case "pref_key_system_visualizer_colorval":
|
|
customColor = Helpers.getSharedIntPref(context, key, Color.WHITE);
|
|
setColor(customColor);
|
|
break;
|
|
case "pref_key_system_visualizer_dyntime":
|
|
randomizeInterval = Helpers.getSharedIntPref(context, key, 10) * 1000;
|
|
mHandler.removeCallbacks(randomizeColor);
|
|
mHandler.post(randomizeColor);
|
|
break;
|
|
case "pref_key_system_visualizer_drawer":
|
|
showInDrawer = Helpers.getSharedBoolPref(context, key, false);
|
|
break;
|
|
case "pref_key_system_visualizer_controller":
|
|
showWithControllerOnly = Helpers.getSharedBoolPref(context, key, false);
|
|
break;
|
|
}
|
|
} catch (Throwable t) {
|
|
XposedBridge.log(t);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
public AudioVisualizer(Context context, AttributeSet attrs) {
|
|
this(context, attrs, 0);
|
|
}
|
|
|
|
public AudioVisualizer(Context context) {
|
|
this(context, null, 0);
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
}
|
|
|
|
|
|
@Override
|
|
protected void onDetachedFromWindow() {
|
|
super.onDetachedFromWindow();
|
|
mArt = null;
|
|
mProcessedArt = null;
|
|
}
|
|
|
|
@Override
|
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
|
super.onSizeChanged(w, h, oldw, oldh);
|
|
|
|
float barUnit = w / (float)mBandsNum;
|
|
float barWidth = barUnit * 0.80f;
|
|
mHeight = h;
|
|
mWidth = w;
|
|
mPaint.setStrokeWidth(barWidth);
|
|
updateBarStyle();
|
|
|
|
for (int i = 0; i < mBandsNum; i++) {
|
|
mFFTPoints[i * 4] = mFFTPoints[i * 4 + 2] = i * barUnit + (barWidth / 2);
|
|
mFFTPoints[i * 4 + 1] = h;
|
|
mFFTPoints[i * 4 + 3] = h;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean hasOverlappingRendering() {
|
|
return mDisplaying;
|
|
}
|
|
|
|
@Override
|
|
protected void onDraw(Canvas canvas) {
|
|
super.onDraw(canvas);
|
|
|
|
try {
|
|
if (mVisualizer == null || !mVisualizer.getEnabled()) return;
|
|
} catch (Throwable t) { return; }
|
|
|
|
if (barStyle == BarStyle.LINE) {
|
|
mLinePath.reset();
|
|
mLinePath.moveTo(0, mFFTPoints[3]);
|
|
for (int i = 1; i < mBandsNum; i++)
|
|
mLinePath.lineTo(i == mBandsNum - 1 ? mWidth : mFFTPoints[i * 4 + 2], mFFTPoints[i * 4 + 3]);
|
|
if (glowLevel > 0)
|
|
canvas.drawPath(mLinePath, mGlowPaint);
|
|
canvas.drawPath(mLinePath, mPaint);
|
|
return;
|
|
}
|
|
|
|
boolean drawAsLines;
|
|
if (renderType == RenderType.LINES)
|
|
drawAsLines = true;
|
|
else if (renderType == RenderType.PATH)
|
|
drawAsLines = false;
|
|
else
|
|
drawAsLines = glowLevel == 0 && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P || (barStyle != BarStyle.DASHED && barStyle != BarStyle.CIRCLES));
|
|
|
|
if (drawAsLines) {
|
|
if (glowLevel > 0)
|
|
canvas.drawLines(mFFTPoints, mGlowPaint);
|
|
canvas.drawLines(mFFTPoints, mPaint);
|
|
} else {
|
|
mLinePath.reset();
|
|
for (int i = 0; i < mBandsNum; i++) {
|
|
mLinePath.moveTo(mFFTPoints[i * 4], mFFTPoints[i * 4 + 1]);
|
|
mLinePath.lineTo(mFFTPoints[i * 4], mFFTPoints[i * 4 + 3]);
|
|
}
|
|
if (glowLevel > 0)
|
|
canvas.drawPath(mLinePath, mGlowPaint);
|
|
canvas.drawPath(mLinePath, mPaint);
|
|
}
|
|
}
|
|
|
|
public void setPlaying(boolean playing) {
|
|
if (mPlaying != playing) {
|
|
mPlaying = playing;
|
|
checkStateChanged();
|
|
}
|
|
}
|
|
|
|
public interface PaletteAsyncListener {
|
|
void onGenerated(Object palette);
|
|
}
|
|
|
|
private final PaletteAsyncListener paletteResult = new PaletteAsyncListener() {
|
|
@Override
|
|
public void onGenerated(Object palette) {
|
|
try {
|
|
int color = Color.TRANSPARENT;
|
|
color = (int)XposedHelpers.callMethod(palette, "getLightVibrantColor", color);
|
|
if (color == Color.TRANSPARENT) color = (int)XposedHelpers.callMethod(palette, "getVibrantColor", color);
|
|
if (color == Color.TRANSPARENT) color = (int)XposedHelpers.callMethod(palette, "getDarkVibrantColor", color);
|
|
setColor(color);
|
|
} catch (Throwable t) {
|
|
XposedBridge.log(t);
|
|
}
|
|
}
|
|
};
|
|
|
|
private static class PaletteTask extends AsyncTask<Bitmap, Void, Object> {
|
|
PaletteAsyncListener resultListener;
|
|
|
|
PaletteTask(PaletteAsyncListener listener) {
|
|
resultListener = listener;
|
|
}
|
|
|
|
@Override
|
|
protected Object doInBackground(Bitmap... bitmaps) {
|
|
try {
|
|
Class<?> paletteCls = XposedHelpers.findClassIfExists("com.android.internal.graphics.palette.Palette", null);
|
|
return paletteCls == null ? null : XposedHelpers.callStaticMethod(paletteCls, "generate", bitmaps[0]);
|
|
} catch (Throwable t) {
|
|
XposedBridge.log(t);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public void onPostExecute(Object palette) {
|
|
resultListener.onGenerated(palette);
|
|
}
|
|
}
|
|
|
|
public void setBitmap() {
|
|
try {
|
|
if (mProcessedArt != null && mArt != null && !mProcessedArt.isRecycled() && !mArt.isRecycled() && mProcessedArt.sameAs(mArt)) return;
|
|
mProcessedArt = mArt;
|
|
if (mProcessedArt != null) {
|
|
Class<?> paletteCls = XposedHelpers.findClassIfExists("com.android.internal.graphics.palette.Palette", null);
|
|
if (paletteCls != null)
|
|
new PaletteTask(paletteResult).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mProcessedArt);
|
|
else
|
|
setColor(Color.TRANSPARENT);
|
|
} else {
|
|
setColor(Color.TRANSPARENT);
|
|
}
|
|
} catch (Throwable t) {
|
|
XposedBridge.log(t);
|
|
}
|
|
}
|
|
|
|
public void setColor(int color) {
|
|
if (color == Color.TRANSPARENT) color = Color.WHITE;
|
|
int newColor = Color.argb(transparency, Color.red(color), Color.green(color), Color.blue(color));
|
|
if (mColor == newColor) return;
|
|
mColor = newColor;
|
|
mOpaqueColor = color;
|
|
if (mVisualizer != null) {
|
|
if (mVisualizerColorAnimator != null) mVisualizerColorAnimator.cancel();
|
|
mVisualizerColorAnimator = ObjectAnimator.ofArgb(mPaint, "color", mPaint.getColor(), mColor);
|
|
mVisualizerColorAnimator.setStartDelay(Math.round(600 * animDur / 65f));
|
|
mVisualizerColorAnimator.setDuration(Math.round(1200 * animDur / 65f));
|
|
mVisualizerColorAnimator.start();
|
|
|
|
if (glowLevel > 0) {
|
|
if (mVisualizerGlowColorAnimator != null) mVisualizerGlowColorAnimator.cancel();
|
|
mVisualizerGlowColorAnimator = ObjectAnimator.ofArgb(mGlowPaint, "color", mGlowPaint.getColor(), mColor);
|
|
mVisualizerGlowColorAnimator.setStartDelay(Math.round(600 * animDur / 65f));
|
|
mVisualizerGlowColorAnimator.setDuration(Math.round(1200 * animDur / 65f));
|
|
mVisualizerGlowColorAnimator.start();
|
|
}
|
|
} else {
|
|
mPaint.setColor(mColor);
|
|
if (glowLevel > 0) mGlowPaint.setColor(mColor);
|
|
}
|
|
}
|
|
|
|
private void updateColorMode() {
|
|
if (!isMusicPlaying) return;
|
|
if (colorMode == ColorMode.MATCH)
|
|
setBitmap();
|
|
else if (colorMode == ColorMode.DYNAMIC)
|
|
setColor(getRandomColor());
|
|
else if (colorMode == ColorMode.STATIC)
|
|
setColor(customColor);
|
|
else
|
|
setColor(Color.WHITE);
|
|
}
|
|
|
|
private void updateRainbowColors() {
|
|
float jump = 300f / (float)mBandsNum;
|
|
for (int i = 0; i < mRainbow.length; i++)
|
|
mRainbow[i] = Color.HSVToColor(transparency, new float[]{jump * i, 1.0f, 1.0f});
|
|
|
|
for (int i = 0; i < mRainbowVertical.length; i++) {
|
|
float h = 140 + jump * i;
|
|
if (h > 360) h -= 360;
|
|
mRainbowVertical[i] = Color.HSVToColor(transparency, new float[]{h, 1.0f, 1.0f});
|
|
}
|
|
}
|
|
|
|
private void updateBarStyle() {
|
|
if (colorMode == ColorMode.RAINBOW_H)
|
|
mPaint.setShader(new LinearGradient(0, 0, mWidth, 0, mRainbow, mPositions, Shader.TileMode.MIRROR));
|
|
else if (colorMode == ColorMode.RAINBOW_V) {
|
|
float maxHeight = Math.min(0.85f * maxDp * mDensity, mHeight / 2.0f);
|
|
mPaint.setShader(new LinearGradient(0, mHeight, 0, mHeight - maxHeight, mRainbowVertical, mPositions, Shader.TileMode.CLAMP));
|
|
} else
|
|
mPaint.setShader(null);
|
|
|
|
if (barStyle == BarStyle.SOLID) {
|
|
mPaint.setPathEffect(null);
|
|
mPaint.setStrokeCap(Paint.Cap.BUTT);
|
|
} else if (barStyle == BarStyle.SOLID_ROUNDED) {
|
|
mPaint.setPathEffect(null);
|
|
mPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
} else if (barStyle == BarStyle.DASHED) {
|
|
mPaint.setPathEffect(new DashPathEffect(new float[]{4 * mDensity, 2 * mDensity}, 0));
|
|
mPaint.setStrokeCap(Paint.Cap.BUTT);
|
|
} else if (barStyle == BarStyle.CIRCLES) {
|
|
mPaint.setPathEffect(new DashPathEffect(new float[]{1.0f, mPaint.getStrokeWidth() + mDensity}, 0));
|
|
mPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
} else if (barStyle == BarStyle.LINE) {
|
|
mPaint.setPathEffect(new CornerPathEffect(18 * mDensity));
|
|
mPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
mPaint.setStrokeWidth(3 * mDensity);
|
|
}
|
|
|
|
updateGlowPaint();
|
|
}
|
|
|
|
public void updateViewState(boolean isPlaying, boolean isKeyguard, boolean isExpanded) {
|
|
isMusicPlaying = isPlaying;
|
|
isOnKeyguard = isKeyguard;
|
|
isExpandedPanel = showInDrawer && !isOnKeyguard && isExpanded;
|
|
isOnCustomLockScreen = new File("/data/system/theme/lockscreen").exists();
|
|
updatePlaying();
|
|
}
|
|
|
|
public void updateScreenOn(boolean isOn) {
|
|
isScreenOn = isOn;
|
|
updatePlaying();
|
|
}
|
|
|
|
public void updateMusicArt(Bitmap art) {
|
|
mArt = art;
|
|
updateColorMode();
|
|
}
|
|
|
|
public void updatePlaying() {
|
|
setPlaying(isScreenOn && isMusicPlaying && ((isOnKeyguard && (!isOnCustomLockScreen || showOnCustom)) || isExpandedPanel));
|
|
}
|
|
|
|
private void checkStateChanged() {
|
|
if (mPlaying) {
|
|
if (!mDisplaying) {
|
|
mDisplaying = true;
|
|
AsyncTask.execute(mLinkVisualizer);
|
|
mHandler.removeCallbacks(randomizeColor);
|
|
mHandler.postDelayed(randomizeColor, randomizeInterval);
|
|
animate().alpha(1.0f).withEndAction(null).setDuration(Math.round(800 * animDur / 65f));
|
|
}
|
|
} else {
|
|
if (mDisplaying) {
|
|
mDisplaying = false;
|
|
mHandler.removeCallbacks(randomizeColor);
|
|
if (isOnKeyguard) {
|
|
animate().alpha(0.0f).withEndAction(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
AsyncTask.execute(mUnlinkVisualizer);
|
|
}
|
|
}).setDuration(Math.round(600 * animDur / 65f));
|
|
} else {
|
|
setAlpha(0.0f);
|
|
AsyncTask.execute(mUnlinkVisualizer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|