diff options
author | Utkarsh Gupta <utkarsh.eminem@gmail.com> | 2015-08-18 12:27:39 +0530 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-12-16 15:40:50 -0800 |
commit | 19e458f4a26fe7c8b6419cadba81a0c46dc79dad (patch) | |
tree | 92b6807c477a3661869a2eb7b2b312e310729bcc /packages/SystemUI/src/com | |
parent | 1d87c14008301f5488c1ebece0345eef2afe2cf1 (diff) | |
download | frameworks_base-19e458f4a26fe7c8b6419cadba81a0c46dc79dad.zip frameworks_base-19e458f4a26fe7c8b6419cadba81a0c46dc79dad.tar.gz frameworks_base-19e458f4a26fe7c8b6419cadba81a0c46dc79dad.tar.bz2 |
SystemUI: use new visualizer from Eleven
Change-Id: I4441440868cac71caa32c91a0875f00a630fe596
Signed-off-by: Utkarsh Gupta <utkarsh.eminem@gmail.com>
Signed-off-by: Roman Birg <roman@cyngn.com>
Diffstat (limited to 'packages/SystemUI/src/com')
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java | 365 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 39 |
2 files changed, 402 insertions, 2 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java new file mode 100644 index 0000000..44794ed --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java @@ -0,0 +1,365 @@ +/* +* Copyright (C) 2015 The CyanogenMod Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.android.systemui.statusbar; + +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.media.audiofx.Visualizer; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.UserHandle; +import android.provider.Settings; +import android.support.v7.graphics.Palette; +import android.util.AttributeSet; +import android.view.View; +import com.android.systemui.cm.UserContentObserver; +import com.android.systemui.statusbar.policy.KeyguardMonitor; +import cyanogenmod.providers.CMSettings; + +import java.util.Arrays; + +public class VisualizerView extends View implements Palette.PaletteAsyncListener, + KeyguardMonitor.Callback { + + private Paint mPaint; + private Visualizer mVisualizer; + private ObjectAnimator mVisualizerColorAnimator; + + private ValueAnimator[] mValueAnimators; + private float[] mFFTPoints; + + private boolean mVisualizerEnabled = false; + private boolean mVisible = false; + private boolean mPlaying = false; + private boolean mPowerSaveMode = false; + private boolean mDisplaying = false; // the state we're animating to + private boolean mDozing = false; + + private int mColor; + private Bitmap mCurrentBitmap; + + private KeyguardMonitor mKeyguardMonitor; + private SettingsObserver mObserver; + + private Visualizer.OnDataCaptureListener mVisualizerListener = + new Visualizer.OnDataCaptureListener() { + byte rfk, ifk; + int dbValue; + float magnitude; + + @Override + public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { + } + + @Override + public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { + for (int i = 0; i < 32; i++) { + mValueAnimators[i].cancel(); + rfk = fft[i * 2 + 2]; + ifk = fft[i * 2 + 3]; + magnitude = rfk * rfk + ifk * ifk; + dbValue = magnitude > 0 ? (int) (10 * Math.log10(magnitude)) : 0; + + mValueAnimators[i].setFloatValues(mFFTPoints[i * 4 + 1], + mFFTPoints[3] - (dbValue * 16f)); + mValueAnimators[i].start(); + } + } + }; + + private final Runnable mLinkVisualizer = new Runnable() { + @Override + public void run() { + try { + mVisualizer = new Visualizer(0); + } catch (Exception e) { + return; + } + + mVisualizer.setEnabled(false); + mVisualizer.setCaptureSize(66); + mVisualizer.setDataCaptureListener(mVisualizerListener,Visualizer.getMaxCaptureRate(), + false, true); + mVisualizer.setEnabled(true); + + } + }; + + private final Runnable mUnlinkVisualizer = new Runnable() { + @Override + public void run() { + mVisualizer.setEnabled(false); + mVisualizer.release(); + mVisualizer = null; + } + }; + + public VisualizerView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + mColor = Color.TRANSPARENT; + + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setColor(mColor); + + mFFTPoints = new float[128]; + mValueAnimators = new ValueAnimator[32]; + for (int i = 0; i < 32; i++) { + final int j = i * 4 + 1; + mValueAnimators[i] = new ValueAnimator(); + mValueAnimators[i].setDuration(128); + mValueAnimators[i].addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + mFFTPoints[j] = (float) animation.getAnimatedValue(); + postInvalidate(); + } + }); + } + } + + public VisualizerView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public VisualizerView(Context context) { + this(context, null, 0); + } + + @Override + public void onKeyguardChanged() { + updateViewVisibility(); + } + + private void updateViewVisibility() { + setVisibility(mKeyguardMonitor != null && mKeyguardMonitor.isShowing() + && mVisualizerEnabled ? View.VISIBLE : View.GONE); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mKeyguardMonitor != null) { + mKeyguardMonitor.addCallback(this); + } + mObserver = new SettingsObserver(new Handler()); + mObserver.observe(); + mObserver.update(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mKeyguardMonitor != null) { + mKeyguardMonitor.removeCallback(this); + } + mObserver.unobserve(); + mObserver = null; + mCurrentBitmap = null; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int size = Math.min(getMeasuredWidth(), getMeasuredHeight()); + setMeasuredDimension(size, size); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + float barUnit = w / 32f; + float barWidth = barUnit * 8f / 9f; + barUnit = barWidth + (barUnit - barWidth) * 32f / 31f; + mPaint.setStrokeWidth(barWidth); + + for (int i = 0; i < 32; 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 mVisualizerEnabled && mDisplaying; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + if (mVisualizer != null) { + canvas.drawLines(mFFTPoints, mPaint); + } + } + + public void setKeyguardMonitor(KeyguardMonitor kgm) { + mKeyguardMonitor = kgm; + if (isAttachedToWindow()) { + // otherwise we might never register ourselves + mKeyguardMonitor.addCallback(this); + updateViewVisibility(); + } + } + + public void setVisible(boolean visible) { + if (mVisible != visible) { + mVisible = visible; + checkStateChanged(); + } + } + + public void setDozing(boolean dozing) { + if (mDozing != dozing) { + mDozing = dozing; + checkStateChanged(); + } + } + + public void setPlaying(boolean playing) { + if (mPlaying != playing) { + mPlaying = playing; + checkStateChanged(); + } + } + + public void setPowerSaveMode(boolean powerSaveMode) { + if (mPowerSaveMode != powerSaveMode) { + mPowerSaveMode = powerSaveMode; + checkStateChanged(); + } + } + + public void setBitmap(Bitmap bitmap) { + if (mCurrentBitmap == bitmap) { + return; + } + mCurrentBitmap = bitmap; + if (bitmap != null) { + Palette.generateAsync(bitmap, this); + } else { + setColor(Color.TRANSPARENT); + } + } + + @Override + public void onGenerated(Palette palette) { + int color = Color.TRANSPARENT; + + color = palette.getVibrantColor(color); + if (color == Color.TRANSPARENT) { + color = palette.getLightVibrantColor(color); + if (color == Color.TRANSPARENT) { + color = palette.getDarkVibrantColor(color); + } + } + + setColor(color); + } + + private void setColor(int color) { + if (color == Color.TRANSPARENT) { + color = Color.WHITE; + } + + color = Color.argb(140, Color.red(color), Color.green(color), Color.blue(color)); + + if (mColor != color) { + mColor = color; + + if (mVisualizer != null) { + if (mVisualizerColorAnimator != null) { + mVisualizerColorAnimator.cancel(); + } + + mVisualizerColorAnimator = ObjectAnimator.ofArgb(mPaint, "color", + mPaint.getColor(), mColor); + mVisualizerColorAnimator.setStartDelay(600); + mVisualizerColorAnimator.setDuration(1200); + mVisualizerColorAnimator.start(); + } else { + mPaint.setColor(mColor); + } + } + } + + private void checkStateChanged() { + if (mVisible && mPlaying && !mDozing && !mPowerSaveMode && mVisualizerEnabled) { + if (!mDisplaying) { + mDisplaying = true; + AsyncTask.execute(mLinkVisualizer); + animate() + .alpha(1f) + .withEndAction(null) + .setDuration(800); + } + } else { + if (mDisplaying) { + mDisplaying = false; + if (mVisible) { + animate() + .alpha(0f) + .withEndAction(mUnlinkVisualizer) + .setDuration(600); + } else { + AsyncTask.execute(mUnlinkVisualizer); + animate(). + alpha(0f) + .withEndAction(null) + .setDuration(0); + } + } + } + } + + private class SettingsObserver extends UserContentObserver { + + public SettingsObserver(Handler handler) { + super(handler); + } + + @Override + protected void update() { + mVisualizerEnabled = CMSettings.Secure.getInt(getContext().getContentResolver(), + CMSettings.Secure.LOCKSCREEN_VISUALIZER_ENABLED, 1) != 0; + checkStateChanged(); + updateViewVisibility(); + } + + @Override + protected void observe() { + super.observe(); + getContext().getContentResolver().registerContentObserver( + CMSettings.Secure.getUriFor(CMSettings.Secure.LOCKSCREEN_VISUALIZER_ENABLED), + false, this, UserHandle.USER_CURRENT); + } + + @Override + protected void unobserve() { + super.unobserve(); + getContext().getContentResolver().unregisterContentObserver(this); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 8671ba5..ba3dca8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -155,6 +155,7 @@ import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.SpeedBumpView; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.VisualizerView; import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener; import com.android.systemui.statusbar.policy.AccessibilityController; import com.android.systemui.statusbar.policy.BatteryController; @@ -614,6 +615,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC); private PorterDuffXfermode mSrcOverXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER); + private VisualizerView mVisualizerView; + private boolean mScreenOn; + private MediaSessionManager mMediaSessionManager; private MediaController mMediaController; private String mMediaNotificationKey; @@ -629,6 +633,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, clearCurrentMediaNotification(); updateMediaMetaData(true); } + mVisualizerView.setPlaying(state.getState() == PlaybackState.STATE_PLAYING); } } @@ -994,8 +999,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front); mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back); - ScrimView scrimBehind = (ScrimView) mStatusBarWindowContent.findViewById(R.id.scrim_behind); - ScrimView scrimInFront = (ScrimView) mStatusBarWindowContent.findViewById(R.id.scrim_in_front); + FrameLayout scrimView = (FrameLayout) mStatusBarWindowContent.findViewById(R.id.scrimview); + ScrimView scrimBehind = (ScrimView) scrimView.findViewById(R.id.scrim_behind); + ScrimView scrimInFront = + (ScrimView) mStatusBarWindowContent.findViewById(R.id.scrim_in_front); View headsUpScrim = mStatusBarWindowContent.findViewById(R.id.heads_up_scrim); mScrimController = new ScrimController(scrimBehind, scrimInFront, headsUpScrim, mScrimSrcModeEnabled); @@ -1004,6 +1011,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mScrimController.setBackDropView(mBackdrop); mStatusBarView.setScrimController(mScrimController); mDozeScrimController = new DozeScrimController(mScrimController, context); + mVisualizerView = (VisualizerView) scrimView.findViewById(R.id.visualizerview); mHeader = (StatusBarHeaderView) mStatusBarWindowContent.findViewById(R.id.header); mHeader.setActivityStarter(this); @@ -1182,6 +1190,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, ((BatteryLevelTextView) mStatusBarView.findViewById(R.id.battery_level_text)) .setBatteryController(mBatteryController); mKeyguardStatusBar.setBatteryController(mBatteryController); + mVisualizerView.setKeyguardMonitor(mKeyguardMonitor); mHeader.setNextAlarmController(mNextAlarmController); mHeader.setWeatherController(mWeatherController); @@ -2058,6 +2067,26 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, backdropBitmap = mKeyguardWallpaper; } + boolean keyguardVisible = (mState != StatusBarState.SHADE); + + if (!mKeyguardFadingAway && keyguardVisible && backdropBitmap != null && mScreenOn) { + // if there's album art, ensure visualizer is visible + mVisualizerView.setVisible(true); + mVisualizerView.setPlaying(mMediaController != null + && mMediaController.getPlaybackState() != null + && mMediaController.getPlaybackState().getState() + == PlaybackState.STATE_PLAYING); + } + + if (backdropBitmap == null && mMediaMetadata == null) { + backdropBitmap = mKeyguardWallpaper; + } + + if (keyguardVisible) { + // always use current backdrop to color eq + mVisualizerView.setBitmap(backdropBitmap); + } + final boolean hasBackdrop = backdropBitmap != null; mKeyguardShowingMedia = hasBackdrop; if (mStatusBarWindowManager != null) { @@ -3396,12 +3425,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { + mScreenOn = false; notifyNavigationBarScreenOn(false); notifyHeadsUpScreenOff(); finishBarAnimations(); resetUserExpandedStates(); } else if (Intent.ACTION_SCREEN_ON.equals(action)) { + mScreenOn = true; notifyNavigationBarScreenOn(true); } } @@ -4290,6 +4321,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, - StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION, StatusBarIconController.DEFAULT_TINT_ANIMATION_DURATION); disable(mDisabledUnmodified1, mDisabledUnmodified2, fadeoutDuration > 0 /* animate */); + mVisualizerView.setVisible(false); } public boolean isKeyguardFadingAway() { @@ -4354,6 +4386,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mDozeScrimController.setDozing(mDozing && mFingerprintUnlockController.getMode() != FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING, animate); + mVisualizerView.setDozing(mDozing); } public void updateStackScrollerState(boolean goingToFullShade) { @@ -4627,6 +4660,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mWakeUpTouchLocation = null; mStackScroller.setAnimationsEnabled(false); updateVisibleToUser(); + mVisualizerView.setVisible(false); if (mLaunchCameraOnFinishedGoingToSleep) { mLaunchCameraOnFinishedGoingToSleep = false; @@ -4665,6 +4699,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onScreenTurnedOn() { mScreenTurningOn = false; mDozeScrimController.onScreenTurnedOn(); + mVisualizerView.setVisible(true); } /** |