summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com')
-rw-r--r--packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java38
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/BatteryMeterView.java41
-rw-r--r--packages/SystemUI/src/com/android/systemui/DockBatteryLevelTextView.java30
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/DockBatteryMeterView.java192
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java144
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSBooleanSettingRow.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSSettings.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java202
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/LiveDisplayTile.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/LockscreenToggleTile.java70
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenTimeoutTile.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java4
-rwxr-xr-xpackages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java162
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateRegistar.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java159
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java18
48 files changed, 1624 insertions, 384 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java b/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java
index 4717a0b..247e965 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryLevelTextView.java
@@ -17,6 +17,7 @@
package com.android.systemui;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryStateRegistar;
import android.content.Context;
import android.content.res.Configuration;
@@ -28,7 +29,10 @@ import java.text.NumberFormat;
public class BatteryLevelTextView extends TextView implements
BatteryController.BatteryStateChangeCallback{
- private BatteryController mBatteryController;
+
+ private BatteryStateRegistar mBatteryStateRegistar;
+ private boolean mBatteryPresent;
+
private boolean mBatteryCharging;
private boolean mForceShow;
private boolean mAttached;
@@ -38,7 +42,9 @@ public class BatteryLevelTextView extends TextView implements
public BatteryLevelTextView(Context context, AttributeSet attrs) {
super(context, attrs);
- mRequestedVisibility = getVisibility();
+ // setBatteryStateRegistar (if called) will made the view visible and ready to be hidden
+ // if the view shouldn't be displayed. Otherwise this view should be hidden from start.
+ mRequestedVisibility = GONE;
}
public void setForceShown(boolean forceShow) {
@@ -46,10 +52,11 @@ public class BatteryLevelTextView extends TextView implements
updateVisibility();
}
- public void setBatteryController(BatteryController batteryController) {
- mBatteryController = batteryController;
+ public void setBatteryStateRegistar(BatteryStateRegistar batteryStateRegistar) {
+ mRequestedVisibility = VISIBLE;
+ mBatteryStateRegistar = batteryStateRegistar;
if (mAttached) {
- mBatteryController.addStateChangedCallback(this);
+ mBatteryStateRegistar.addStateChangedCallback(this);
}
}
@@ -69,10 +76,12 @@ public class BatteryLevelTextView extends TextView implements
}
@Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ public void onBatteryLevelChanged(boolean present, int level, boolean pluggedIn,
+ boolean charging) {
String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
setText(percentage);
- if (mBatteryCharging != charging) {
+ if (mBatteryPresent != present || mBatteryCharging != charging) {
+ mBatteryPresent = present;
mBatteryCharging = charging;
updateVisibility();
}
@@ -94,8 +103,8 @@ public class BatteryLevelTextView extends TextView implements
public void onAttachedToWindow() {
super.onAttachedToWindow();
- if (mBatteryController != null) {
- mBatteryController.addStateChangedCallback(this);
+ if (mBatteryStateRegistar != null) {
+ mBatteryStateRegistar.addStateChangedCallback(this);
}
mAttached = true;
@@ -106,21 +115,22 @@ public class BatteryLevelTextView extends TextView implements
super.onDetachedFromWindow();
mAttached = false;
- if (mBatteryController != null) {
- mBatteryController.removeStateChangedCallback(this);
+ if (mBatteryStateRegistar != null) {
+ mBatteryStateRegistar.removeStateChangedCallback(this);
}
}
private void updateVisibility() {
- boolean showNextPercent = mPercentMode == BatteryController.PERCENTAGE_MODE_OUTSIDE
- || (mBatteryCharging && mPercentMode == BatteryController.PERCENTAGE_MODE_INSIDE);
+ boolean showNextPercent = mBatteryPresent && (
+ mPercentMode == BatteryController.PERCENTAGE_MODE_OUTSIDE
+ || (mBatteryCharging && mPercentMode == BatteryController.PERCENTAGE_MODE_INSIDE));
if (mStyle == BatteryController.STYLE_GONE) {
showNextPercent = false;
} else if (mStyle == BatteryController.STYLE_TEXT) {
showNextPercent = true;
}
- if (showNextPercent || mForceShow) {
+ if (mBatteryStateRegistar != null && (showNextPercent || mForceShow)) {
super.setVisibility(mRequestedVisibility);
} else {
super.setVisibility(GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 244b7f7..e606156 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -17,6 +17,7 @@
package com.android.systemui;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.BatteryStateRegistar;
import android.animation.ArgbEvaluator;
import android.content.BroadcastReceiver;
@@ -73,6 +74,7 @@ public class BatteryMeterView extends View implements DemoMode,
private final Path mClipPath = new Path();
private final Path mTextPath = new Path();
+ private BatteryStateRegistar mBatteryStateRegistar;
private BatteryController mBatteryController;
private boolean mPowerSaveEnabled;
@@ -92,7 +94,7 @@ public class BatteryMeterView extends View implements DemoMode,
private BatteryMeterDrawable mBatteryMeterDrawable;
private int mIconTint = Color.WHITE;
- private class BatteryTracker extends BroadcastReceiver {
+ protected class BatteryTracker extends BroadcastReceiver {
public static final int UNKNOWN_LEVEL = -1;
// current battery status
@@ -128,7 +130,6 @@ public class BatteryMeterView extends View implements DemoMode,
technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
-
setContentDescription(
context.getString(R.string.accessibility_battery_level, level));
if (mBatteryMeterDrawable != null) {
@@ -193,7 +194,9 @@ public class BatteryMeterView extends View implements DemoMode,
// preload the battery level
mTracker.onReceive(getContext(), sticky);
}
- mBatteryController.addStateChangedCallback(this);
+ if (mBatteryStateRegistar != null) {
+ mBatteryStateRegistar.addStateChangedCallback(this);
+ }
mAttached = true;
}
@@ -203,7 +206,9 @@ public class BatteryMeterView extends View implements DemoMode,
mAttached = false;
getContext().unregisterReceiver(mTracker);
- mBatteryController.removeStateChangedCallback(this);
+ if (mBatteryStateRegistar != null) {
+ mBatteryStateRegistar.removeStateChangedCallback(this);
+ }
}
public BatteryMeterView(Context context) {
@@ -279,20 +284,28 @@ public class BatteryMeterView extends View implements DemoMode,
width = height;
} else if (mMeterMode == BatteryMeterMode.BATTERY_METER_TEXT) {
onSizeChanged(width, height, 0, 0); // Force a size changed event
- } else if (mMeterMode.compareTo(BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE) == 0) {
+ } else if (mMeterMode == BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE) {
width = (int)(height * 1.2f);
}
setMeasuredDimension(width, height);
}
+ public void setBatteryStateRegistar(BatteryStateRegistar batteryStateRegistar) {
+ mBatteryStateRegistar = batteryStateRegistar;
+ if (!mAttached) {
+ mBatteryStateRegistar.addStateChangedCallback(this);
+ }
+ }
+
public void setBatteryController(BatteryController batteryController) {
mBatteryController = batteryController;
mPowerSaveEnabled = mBatteryController.isPowerSave();
}
@Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ public void onBatteryLevelChanged(boolean present, int level, boolean pluggedIn,
+ boolean charging) {
// TODO: Use this callback instead of own broadcast receiver.
}
@@ -742,9 +755,7 @@ public class BatteryMeterView extends View implements DemoMode,
}
private float[] loadBoltPoints(Resources res) {
- final int[] pts = res.getIntArray((mHorizontal
- ? R.array.batterymeter_inverted_bolt_points
- : R.array.batterymeter_bolt_points));
+ final int[] pts = res.getIntArray(getBoltPointsArrayResource());
int maxX = 0, maxY = 0;
for (int i = 0; i < pts.length; i += 2) {
maxX = Math.max(maxX, pts[i]);
@@ -757,6 +768,12 @@ public class BatteryMeterView extends View implements DemoMode,
}
return ptsF;
}
+
+ protected int getBoltPointsArrayResource() {
+ return mHorizontal
+ ? R.array.batterymeter_inverted_bolt_points
+ : R.array.batterymeter_bolt_points;
+ }
}
protected class CircleBatteryMeterDrawable implements BatteryMeterDrawable {
@@ -858,7 +875,7 @@ public class BatteryMeterView extends View implements DemoMode,
}
private float[] loadBoltPoints(Resources res) {
- final int[] pts = res.getIntArray(R.array.batterymeter_bolt_points);
+ final int[] pts = res.getIntArray(getBoltPointsArrayResource());
int maxX = 0, maxY = 0;
for (int i = 0; i < pts.length; i += 2) {
maxX = Math.max(maxX, pts[i]);
@@ -872,6 +889,10 @@ public class BatteryMeterView extends View implements DemoMode,
return ptsF;
}
+ protected int getBoltPointsArrayResource() {
+ return R.array.batterymeter_bolt_points;
+ }
+
private void drawCircle(Canvas canvas, BatteryTracker tracker,
float textX, RectF drawRect) {
boolean unknownStatus = tracker.status == BatteryManager.BATTERY_STATUS_UNKNOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/DockBatteryLevelTextView.java b/packages/SystemUI/src/com/android/systemui/DockBatteryLevelTextView.java
new file mode 100644
index 0000000..1678e94
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DockBatteryLevelTextView.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+
+public class DockBatteryLevelTextView extends BatteryLevelTextView {
+
+ public DockBatteryLevelTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setPaintFlags(getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/DockBatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/DockBatteryMeterView.java
new file mode 100755
index 0000000..b80e6d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/DockBatteryMeterView.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.BatteryManager;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class DockBatteryMeterView extends BatteryMeterView {
+
+ private BatteryManager mBatteryService;
+ private final boolean mSupported;
+
+ private class DockBatteryTracker extends BatteryTracker {
+
+ public DockBatteryTracker() {
+ super();
+ present = false;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ if (testmode && ! intent.getBooleanExtra("testmode", false)) return;
+
+ if (mSupported) {
+ level = (int)(100f
+ * intent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0)
+ / intent.getIntExtra(BatteryManager.EXTRA_DOCK_SCALE, 100));
+
+ present = intent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, false);
+ plugType = intent.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0);
+ // We need to add a extra check over the status because of dock batteries
+ // PlugType doesn't means that the dock battery is charging (some devices
+ // doesn't charge under dock usb)
+ plugged = plugType != 0 && (status == BatteryManager.BATTERY_STATUS_CHARGING ||
+ status == BatteryManager.BATTERY_STATUS_FULL);
+ health = intent.getIntExtra(BatteryManager.EXTRA_DOCK_HEALTH,
+ BatteryManager.BATTERY_HEALTH_UNKNOWN);
+ status = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ technology = intent.getStringExtra(BatteryManager.EXTRA_DOCK_TECHNOLOGY);
+ voltage = intent.getIntExtra(BatteryManager.EXTRA_DOCK_VOLTAGE, 0);
+ temperature = intent.getIntExtra(BatteryManager.EXTRA_DOCK_TEMPERATURE, 0);
+
+
+ if (present && (mMeterMode != BatteryMeterMode.BATTERY_METER_GONE &&
+ mMeterMode != BatteryMeterMode.BATTERY_METER_TEXT)) {
+ setContentDescription(context.getString(
+ R.string.accessibility_dock_battery_level, level));
+ setVisibility(View.VISIBLE);
+ invalidate();
+ } else {
+ setContentDescription(null);
+ setVisibility(View.GONE);
+ }
+ } else {
+ setContentDescription(null);
+ setVisibility(View.GONE);
+
+ // If dock is not supported then we don't need this receiver anymore
+ getContext().unregisterReceiver(this);
+ }
+ } else if (action.equals(ACTION_LEVEL_TEST)) {
+ testmode = true;
+ post(new Runnable() {
+ int curLevel = 0;
+ int incr = 1;
+ int saveLevel = level;
+ int savePlugged = plugType;
+ Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
+ @Override
+ public void run() {
+ if (curLevel < 0) {
+ testmode = false;
+ dummy.putExtra("level", saveLevel);
+ dummy.putExtra("plugged", savePlugged);
+ dummy.putExtra("testmode", false);
+ } else {
+ dummy.putExtra("level", curLevel);
+ dummy.putExtra("plugged", incr > 0
+ ? BatteryManager.BATTERY_DOCK_PLUGGED_AC : 0);
+ dummy.putExtra("testmode", true);
+ }
+ getContext().sendBroadcast(dummy);
+
+ if (!testmode) return;
+
+ curLevel += incr;
+ if (curLevel == 100) {
+ incr *= -1;
+ }
+ postDelayed(this, 200);
+ }
+ });
+ }
+ }
+ }
+
+ public DockBatteryMeterView(Context context) {
+ this(context, null, 0);
+ }
+
+ public DockBatteryMeterView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public DockBatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mBatteryService = ((BatteryManager) context.getSystemService(Context.BATTERY_SERVICE));
+ mSupported = mBatteryService.isDockBatterySupported();
+ mDemoTracker = new DockBatteryTracker();
+ mTracker = new DockBatteryTracker();
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ // We already unregistered the listener once when we decided
+ // support was absent. Don't do it again.
+ if (mSupported) {
+ super.onDetachedFromWindow();
+ }
+ }
+
+ @Override
+ public void setMode(BatteryMeterMode mode) {
+ super.setMode(mode);
+ int visibility = getVisibility();
+ if (visibility == View.VISIBLE && !mSupported) {
+ setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ protected BatteryMeterDrawable createBatteryMeterDrawable(BatteryMeterMode mode) {
+ Resources res = mContext.getResources();
+ switch (mode) {
+ case BATTERY_METER_CIRCLE:
+ return new DockCircleBatteryMeterDrawable(res);
+ case BATTERY_METER_ICON_LANDSCAPE:
+ return new DockNormalBatteryMeterDrawable(res, true);
+ case BATTERY_METER_TEXT:
+ case BATTERY_METER_GONE:
+ return null;
+ default:
+ return new DockNormalBatteryMeterDrawable(res, false);
+ }
+ }
+
+ protected class DockNormalBatteryMeterDrawable extends NormalBatteryMeterDrawable {
+
+ public DockNormalBatteryMeterDrawable(Resources res, boolean horizontal) {
+ super(res, horizontal);
+ }
+
+ @Override
+ protected int getBoltPointsArrayResource() {
+ return mHorizontal
+ ? R.array.dockbatterymeter_inverted_bolt_points
+ : R.array.dockbatterymeter_bolt_points;
+ }
+ }
+
+ protected class DockCircleBatteryMeterDrawable extends CircleBatteryMeterDrawable {
+ public DockCircleBatteryMeterDrawable(Resources res) {
+ super(res);
+ }
+
+ @Override
+ protected int getBoltPointsArrayResource() {
+ return R.array.dockbatterymeter_bolt_points;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 17fadbd..06ce8cc 100755
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -151,6 +151,8 @@ public class KeyguardViewMediator extends SystemUI {
"com.android.internal.action.KEYGUARD_SERVICE_STATE_CHANGED";
private static final String KEYGUARD_SERVICE_EXTRA_ACTIVE = "active";
+ private static final String DECRYPT_STATE = "trigger_restart_framework";
+
// used for handler messages
private static final int SHOW = 2;
private static final int HIDE = 3;
@@ -203,7 +205,6 @@ public class KeyguardViewMediator extends SystemUI {
private AudioManager mAudioManager;
private StatusBarManager mStatusBarManager;
private boolean mSwitchingUser;
- private ProfileManager mProfileManager;
private boolean mSystemReady;
private boolean mBootCompleted;
private boolean mBootSendUserPresent;
@@ -290,7 +291,7 @@ public class KeyguardViewMediator extends SystemUI {
/**
* Whether we are disabling the lock screen internally
*/
- private Boolean mInternallyDisabled = null;
+ private boolean mInternallyDisabled = false;
/**
* we send this intent when the keyguard is dismissed.
@@ -344,6 +345,8 @@ public class KeyguardViewMediator extends SystemUI {
*/
private boolean mPendingLock;
+ private boolean mCryptKeeperEnabled = true;
+
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
@@ -517,7 +520,10 @@ public class KeyguardViewMediator extends SystemUI {
break;
case READY:
synchronized (this) {
- if (mShowing) {
+ if ((mInternallyDisabled || isProfileDisablingKeyguard())
+ && !mUpdateMonitor.isSimPinSecure()) {
+ hideLocked();
+ } else if (mShowing) {
resetStateLocked();
}
}
@@ -625,12 +631,12 @@ public class KeyguardViewMediator extends SystemUI {
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
- mProfileManager = ProfileManager.getInstance(mContext);
mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DISMISS_KEYGUARD_SECURELY_ACTION),
android.Manifest.permission.CONTROL_KEYGUARD, null);
mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(KEYGUARD_SERVICE_ACTION_STATE_CHANGE),
android.Manifest.permission.CONTROL_KEYGUARD, null);
+ mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED));
mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
@@ -691,18 +697,12 @@ public class KeyguardViewMediator extends SystemUI {
getPersistedDefaultOldSetting() ? 1 : 0,
UserHandle.USER_CURRENT) == 0;
- if (mKeyguardBound) {
- if (mInternallyDisabled == null) {
- // if it's enabled on boot, don't go through the notions of
- // setting it enabled, as it might cause a flicker, just set the state
- if (newDisabledState) {
- setKeyguardEnabledInternal(false); // will set mInternallyDisabled
- } else {
- mInternallyDisabled = false;
+ synchronized (KeyguardViewMediator.this) {
+ if (mKeyguardBound) {
+ if (newDisabledState != mInternallyDisabled) {
+ // it was updated,
+ setKeyguardEnabledInternal(!newDisabledState);
}
- } else if (newDisabledState != mInternallyDisabled) {
- // it was updated,
- setKeyguardEnabledInternal(!newDisabledState);
}
}
}
@@ -761,7 +761,7 @@ public class KeyguardViewMediator extends SystemUI {
Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
}
mExitSecureCallback = null;
- if (!mExternallyEnabled) {
+ if (!mInternallyDisabled && !mExternallyEnabled) {
hideLocked();
}
} else if (mShowing) {
@@ -914,15 +914,27 @@ public class KeyguardViewMediator extends SystemUI {
if (DEBUG) Log.d(TAG, "isKeyguardDisabled: keyguard is disabled by setting");
return true;
}
- Profile profile = mProfileManager.getActiveProfile();
- if (profile != null) {
- if (profile.getScreenLockMode().getValue() == Profile.LockMode.DISABLE) {
- if (DEBUG) Log.d(TAG, "isKeyguardDisabled: keyguard is disabled by profile");
- return true;
- }
- }
+ if (mInternallyDisabled) {
+ if (DEBUG) Log.d(TAG, "isKeyguardDisabled: keyguard is disabled internally");
+ return true;
+ }
+ if (isProfileDisablingKeyguard()) {
+ if (DEBUG) Log.d(TAG, "isKeyguardDisabled: keyguard is disabled by profile");
+ return true;
+ }
return false;
- }
+ }
+
+ private boolean isCryptKeeperEnabled() {
+ if (!mCryptKeeperEnabled) {
+ // once it's disabled, it's disabled.
+ return false;
+ }
+ final String state = SystemProperties.get("vold.decrypt");
+ mCryptKeeperEnabled = !"".equals(state) && !DECRYPT_STATE.equals(state);
+ if (DEBUG) Log.w(TAG, "updated crypt keeper state to: " + mCryptKeeperEnabled);
+ return mCryptKeeperEnabled;
+ }
/**
* A dream started. We should lock after the usual screen-off lock timeout but only
@@ -955,6 +967,10 @@ public class KeyguardViewMediator extends SystemUI {
*/
public void setKeyguardEnabledInternal(boolean enabled) {
mInternallyDisabled = !enabled;
+ if (!mUpdateMonitor.isSimPinSecure()) {
+ // disable when sim is ready
+ return;
+ }
setKeyguardEnabled(enabled);
if (mInternallyDisabled) {
mNeedToReshowWhenReenabled = false;
@@ -965,6 +981,12 @@ public class KeyguardViewMediator extends SystemUI {
return !mInternallyDisabled;
}
+ public boolean isProfileDisablingKeyguard() {
+ final Profile activeProfile = ProfileManager.getInstance(mContext).getActiveProfile();
+ return activeProfile != null
+ && activeProfile.getScreenLockMode().getValue() == Profile.LockMode.DISABLE;
+ }
+
/**
* Same semantics as {@link android.view.WindowManagerPolicy#enableKeyguard}; provide
* a way for external stuff to override normal keyguard behavior. For instance
@@ -973,15 +995,15 @@ public class KeyguardViewMediator extends SystemUI {
public void setKeyguardEnabled(boolean enabled) {
synchronized (this) {
if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")");
-
- if (mInternallyDisabled && enabled && !lockscreenEnforcedByDevicePolicy()) {
+ mExternallyEnabled = enabled;
+ if (mInternallyDisabled
+ && enabled
+ && !lockscreenEnforcedByDevicePolicy()) {
// if keyguard is forcefully disabled internally (by lock screen tile), don't allow
// it to be enabled externally, unless the device policy manager says so.
return;
}
- mExternallyEnabled = enabled;
-
if (!enabled && mShowing) {
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring");
@@ -993,7 +1015,7 @@ public class KeyguardViewMediator extends SystemUI {
// hiding keyguard that is showing, remember to reshow later
if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
+ "disabling status bar expansion");
- mNeedToReshowWhenReenabled = true;
+ mNeedToReshowWhenReenabled = !isProfileDisablingKeyguard();
updateInputRestrictedLocked();
hideLocked();
} else if (enabled && mNeedToReshowWhenReenabled) {
@@ -1173,22 +1195,6 @@ public class KeyguardViewMediator extends SystemUI {
* Enable the keyguard if the settings are appropriate.
*/
private void doKeyguardLocked(Bundle options) {
- // if another app is disabling us, don't show
- if (!mExternallyEnabled) {
- if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
-
- // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
- // for an occasional ugly flicker in this situation:
- // 1) receive a call with the screen on (no keyguard) or make a call
- // 2) screen times out
- // 3) user hits key to turn screen back on
- // instead, we reenable the keyguard when we know the screen is off and the call
- // ends (see the broadcast receiver below)
- // TODO: clean this up when we have better support at the window manager level
- // for apps that wish to be on top of the keyguard
- return;
- }
-
// if the keyguard is already showing, don't bother
if (mStatusBarKeyguardViewManager.isShowing()) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
@@ -1196,6 +1202,14 @@ public class KeyguardViewMediator extends SystemUI {
return;
}
+ // Ugly hack to ensure keyguard is not shown on top of the CryptKeeper which prevents
+ // a user from being able to decrypt their device.
+ if (isCryptKeeperEnabled()) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because CryptKeeper is enabled");
+ resetStateLocked();
+ return;
+ }
+
// if the setup wizard hasn't run yet, don't show
final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", false);
final boolean absent = SubscriptionManager.isValidSubscriptionId(
@@ -1211,9 +1225,30 @@ public class KeyguardViewMediator extends SystemUI {
return;
}
+ // if another app is disabling us, don't show
+ if (!mExternallyEnabled && !lockedOrMissing) {
+ if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
+
+ // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
+ // for an occasional ugly flicker in this situation:
+ // 1) receive a call with the screen on (no keyguard) or make a call
+ // 2) screen times out
+ // 3) user hits key to turn screen back on
+ // instead, we reenable the keyguard when we know the screen is off and the call
+ // ends (see the broadcast receiver below)
+ // TODO: clean this up when we have better support at the window manager level
+ // for apps that wish to be on top of the keyguard
+ return;
+ }
+
if (isKeyguardDisabled(KeyguardUpdateMonitor.getCurrentUser())
&& !lockedOrMissing) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
+ // update state
+ setShowingLocked(false);
+ updateActivityLockScreenState();
+ adjustStatusBarLocked();
+ userActivity();
return;
}
@@ -1238,15 +1273,7 @@ public class KeyguardViewMediator extends SystemUI {
DevicePolicyManager dpm = (DevicePolicyManager)
mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm != null) {
- int passwordQuality = dpm.getPasswordQuality(null);
- switch (passwordQuality) {
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- return true;
- }
+ return dpm.requireSecureKeyguard();
}
return false;
}
@@ -1376,6 +1403,9 @@ public class KeyguardViewMediator extends SystemUI {
} else {
mSettingsObserver.unobserve();
}
+ } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(intent.getAction())) {
+ mPhoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
+ if (DEBUG) Log.d(TAG, "phone state change, new state: " + mPhoneState);
}
}
};
@@ -1541,6 +1571,10 @@ public class KeyguardViewMediator extends SystemUI {
private void playSound(int soundId) {
if (soundId == 0) return;
+ if (mInternallyDisabled) {
+ Log.d(TAG, "suppressing lock screen sounds because it is disabled");
+ return;
+ }
final ContentResolver cr = mContext.getContentResolver();
if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) {
@@ -1726,7 +1760,7 @@ public class KeyguardViewMediator extends SystemUI {
private void handleReset() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleReset");
- mStatusBarKeyguardViewManager.reset();
+ mStatusBarKeyguardViewManager.reset(false);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index a1a11ca..e519e34 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -237,8 +237,8 @@ public class PowerUI extends SystemUI {
if (mIgnoreFirstPowerEvent) {
mIgnoreFirstPowerEvent = false;
} else {
- if (CMSettings.Global.getInt(cr,
- CMSettings.Global.POWER_NOTIFICATIONS_ENABLED, 0) == 1) {
+ if (Settings.Global.getInt(cr,
+ Settings.Global.CHARGING_SOUNDS_ENABLED, 0) == 1) {
playPowerNotificationSound();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSBooleanSettingRow.java b/packages/SystemUI/src/com/android/systemui/qs/QSBooleanSettingRow.java
index d2d13ae..50845da 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSBooleanSettingRow.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSBooleanSettingRow.java
@@ -49,6 +49,7 @@ public class QSBooleanSettingRow extends LinearLayout implements View.OnClickLis
private TextView mText;
private Switch mSwitch;
private int mDefaultValue;
+ private CompoundButton.OnCheckedChangeListener mOnCheckedChangeListener;
public QSBooleanSettingRow(Context context) {
this(context, null);
@@ -99,6 +100,9 @@ public class QSBooleanSettingRow extends LinearLayout implements View.OnClickLis
+ "buttonView = [" + buttonView + "], isChecked = [" + isChecked
+ "] and table: " + mWhichTable + ", and key: " + mKey);
applyChange(isChecked);
+ if (mOnCheckedChangeListener != null) {
+ mOnCheckedChangeListener.onCheckedChanged(buttonView, isChecked);
+ }
}
});
}
@@ -106,6 +110,13 @@ public class QSBooleanSettingRow extends LinearLayout implements View.OnClickLis
a.recycle();
}
+ public void setChecked(boolean checked) {
+ if (mSwitch.isChecked() == checked) {
+ return;
+ }
+ mSwitch.setChecked(checked);
+ }
+
private void applyChange(boolean value) {
ContentResolver cr = getContext().getContentResolver();
switch (mWhichTable) {
@@ -160,4 +171,8 @@ public class QSBooleanSettingRow extends LinearLayout implements View.OnClickLis
public void onClick(View v) {
mSwitch.setChecked(!mSwitch.isChecked());
}
+
+ public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener l) {
+ mOnCheckedChangeListener = l;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
index 0615842..86fc49e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDragPanel.java
@@ -89,6 +89,9 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
private static final int MAX_ROW_COUNT = 3;
+ // how long to wait before resetting the page
+ private static final int PAGE_RESET_DELAY = 10000;
+
protected final ArrayList<QSPage> mPages = new ArrayList<>();
protected QSViewPager mViewPager;
@@ -119,6 +122,16 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
private Point mDisplaySize;
private int[] mTmpLoc;
+ private Runnable mResetPage = new Runnable() {
+ @Override
+ public void run() {
+ if (!mListening) {
+ // only reset when the user isn't interacting at all
+ mViewPager.setCurrentItem(0);
+ }
+ }
+ };
+
public QSDragPanel(Context context) {
this(context, null);
}
@@ -369,6 +382,12 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
public void setListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
+ // reset the page when inactive for a while
+ if (listening) {
+ removeCallbacks(mResetPage);
+ } else {
+ postDelayed(mResetPage, PAGE_RESET_DELAY);
+ }
for (TileRecord r : mRecords) {
r.tile.setListening(mListening);
}
@@ -481,36 +500,6 @@ public class QSDragPanel extends QSPanel implements View.OnDragListener, View.On
mDetailRemoveButton.setText(R.string.quick_settings_remove);
}
- /**
- * @return returns the number of pages that has at least 1 visible tile
- */
- protected int getVisibleTilePageCount() {
- // if all tiles are invisible on the page, do not count it
- int pages = 0;
-
- int lastPage = -1;
- boolean allTilesInvisible = true;
-
- for (TileRecord record : mRecords) {
- DragTileRecord dr = (DragTileRecord) record;
- if (dr.destinationPage != lastPage) {
- if (!allTilesInvisible) {
- pages++;
- }
- lastPage = dr.destinationPage;
- allTilesInvisible = true;
- }
- if (allTilesInvisible && dr.tile.getState().visible) {
- allTilesInvisible = false;
- }
- }
- // last tile may have set this
- if (!allTilesInvisible) {
- pages++;
- }
- return pages;
- }
-
public void setTiles(final Collection<QSTile<?>> tilesCollection) {
final List<QSTile<?>> tiles = new ArrayList<>(tilesCollection);
if (DEBUG_TILES) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSettings.java b/packages/SystemUI/src/com/android/systemui/qs/QSSettings.java
index 7766ca4..0a2b937 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSettings.java
@@ -15,15 +15,22 @@
*/
package com.android.systemui.qs;
+import android.Manifest;
import android.annotation.Nullable;
+import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ResultReceiver;
import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
import android.view.View;
-import android.widget.LinearLayout;
+import android.widget.CompoundButton;
import android.widget.ScrollView;
import com.android.systemui.R;
@@ -32,9 +39,16 @@ import com.android.systemui.statusbar.phone.SystemUIDialog;
public class QSSettings extends ScrollView {
+ private static final String RESULT_RECEIVER_EXTRA = "result_receiver";
+ private static final String LOCK_CLOCK_PACKAGENAME = "com.cyanogenmod.lockclock";
+ private static final String LOCK_CLOCK_PERM_CLASS = LOCK_CLOCK_PACKAGENAME
+ + ".weather.PermissionRequestActivity";
+
private QSTileHost mHost;
private boolean mAdapterEditingState;
+ private QSBooleanSettingRow mShowWeather;
+ private ResultReceiver mResultReceiver;
public QSSettings(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -51,6 +65,51 @@ public class QSSettings extends ScrollView {
initiateTileReset();
}
});
+
+ mShowWeather = (QSBooleanSettingRow) findViewById(R.id.show_weather);
+ mShowWeather.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ PackageManager packageManager = getContext().getPackageManager();
+ if (packageManager.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION,
+ LOCK_CLOCK_PACKAGENAME) != PackageManager.PERMISSION_GRANTED) {
+ mShowWeather.setChecked(false);
+ requestPermission();
+ mHost.collapsePanels();
+ }
+ }
+ }
+ });
+ }
+
+ public Parcelable getResultReceiverForSending() {
+ if (mResultReceiver == null) {
+ mResultReceiver = new ResultReceiver(new Handler()) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ super.onReceiveResult(resultCode, resultData);
+ if (resultCode == Activity.RESULT_OK) {
+ mShowWeather.setChecked(true);
+ }
+ mResultReceiver = null;
+ }
+ };
+ }
+ Parcel parcel = Parcel.obtain();
+ mResultReceiver.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ ResultReceiver receiverForSending = ResultReceiver.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+ return receiverForSending;
+ }
+
+ private void requestPermission() {
+ Intent i = new Intent();
+ i.setClassName(LOCK_CLOCK_PACKAGENAME, LOCK_CLOCK_PERM_CLASS);
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ i.putExtra(RESULT_RECEIVER_EXTRA, getResultReceiverForSending());
+ getContext().startActivity(i);
}
private void initiateTileReset() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java
new file mode 100644
index 0000000..fb6ec42
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CaffeineTile.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2016 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.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.CountDownTimer;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.provider.Settings;
+
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.R;
+
+import org.cyanogenmod.internal.logging.CMMetricsLogger;
+
+/** Quick settings tile: Caffeine **/
+public class CaffeineTile extends QSTile<QSTile.BooleanState> {
+
+ private final PowerManager.WakeLock mWakeLock;
+ private int mSecondsRemaining;
+ private int mDuration;
+ private static int[] DURATIONS = new int[] {
+ 5 * 60, // 5 min
+ 10 * 60, // 10 min
+ 30 * 60, // 30 min
+ -1, // infinity
+ };
+ private CountDownTimer mCountdownTimer = null;
+ public long mLastClickTime = -1;
+ private final Receiver mReceiver = new Receiver();
+ private boolean mListening;
+
+ public CaffeineTile(Host host) {
+ super(host);
+ mWakeLock = ((PowerManager) mContext.getSystemService(Context.POWER_SERVICE)).newWakeLock(
+ PowerManager.FULL_WAKE_LOCK, "CaffeineTile");
+ mReceiver.init();
+ }
+
+ @Override
+ protected BooleanState newTileState() {
+ return new BooleanState();
+ }
+
+ @Override
+ protected void handleDestroy() {
+ super.handleDestroy();
+ stopCountDown();
+ mReceiver.destroy();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ }
+
+ @Override
+ public void handleClick() {
+ // If last user clicks < 5 seconds
+ // we cycle different duration
+ // otherwise toggle on/off
+ if (mWakeLock.isHeld() && (mLastClickTime != -1) &&
+ (SystemClock.elapsedRealtime() - mLastClickTime < 5000)) {
+ // cycle duration
+ mDuration++;
+ if (mDuration >= DURATIONS.length) {
+ // all durations cycled, turn if off
+ mDuration = -1;
+ stopCountDown();
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ } else {
+ // change duration
+ startCountDown(DURATIONS[mDuration]);
+ if (!mWakeLock.isHeld()) {
+ mWakeLock.acquire();
+ }
+ }
+ } else {
+ // toggle
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ stopCountDown();
+ } else {
+ mWakeLock.acquire();
+ mDuration = 0;
+ startCountDown(DURATIONS[mDuration]);
+ }
+ }
+ mLastClickTime = SystemClock.elapsedRealtime();
+ refreshState();
+ }
+
+ private void startCountDown(long duration) {
+ stopCountDown();
+ mSecondsRemaining = (int)duration;
+ if (duration == -1) {
+ // infinity timing, no need to start timer
+ return;
+ }
+ mCountdownTimer = new CountDownTimer(duration * 1000, 1000) {
+
+ @Override
+ public void onTick(long millisUntilFinished) {
+ mSecondsRemaining = (int) (millisUntilFinished / 1000);
+ refreshState();
+ }
+
+ @Override
+ public void onFinish() {
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ refreshState();
+ }
+
+ }.start();
+ }
+
+ private void stopCountDown() {
+ if (mCountdownTimer != null) {
+ mCountdownTimer.cancel();
+ mCountdownTimer = null;
+ }
+ }
+
+ private String formatValueWithRemainingTime() {
+ if (mSecondsRemaining == -1) {
+ return "\u221E"; // infinity
+ }
+ return String.format("%02d:%02d",
+ mSecondsRemaining / 60 % 60, mSecondsRemaining % 60);
+ }
+
+ @Override
+ protected void handleUpdateState(BooleanState state, Object arg) {
+ state.value = mWakeLock.isHeld();
+ state.visible = true;
+ if (state.value) {
+ state.label = formatValueWithRemainingTime();
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_caffeine_on);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_caffeine_on);
+ } else {
+ state.label = mContext.getString(R.string.quick_settings_caffeine_label);
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_caffeine_off);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_caffeine_off);
+ }
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return CMMetricsLogger.TILE_CAFFEINE;
+ }
+
+ private final class Receiver extends BroadcastReceiver {
+ public void init() {
+ // Register for Intent broadcasts for...
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ mContext.registerReceiver(this, filter, null, mHandler);
+ }
+
+ public void destroy() {
+ mContext.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+ // disable caffeine if user force off (power button)
+ stopCountDown();
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ refreshState();
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index f83bbf4..cd608d6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -208,12 +208,14 @@ public class CastTile extends QSTile<QSTile.BooleanState> {
@Override
public void onViewAttachedToWindow(View v) {
if (DEBUG) Log.d(TAG, "onViewAttachedToWindow");
+ mController.setDiscovering(true);
}
@Override
public void onViewDetachedFromWindow(View v) {
if (DEBUG) Log.d(TAG, "onViewDetachedFromWindow");
mVisibleOrder.clear();
+ mController.setDiscovering(false);
}
});
}
@@ -221,7 +223,6 @@ public class CastTile extends QSTile<QSTile.BooleanState> {
R.string.quick_settings_cast_detail_empty_text);
mItems.setCallback(this);
updateItems(mController.getCastDevices());
- mController.setDiscovering(true);
return mItems;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index f4602de..038fa5e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -17,10 +17,12 @@
package com.android.systemui.qs.tiles;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
import android.view.View;
@@ -47,11 +49,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
private static final Intent MOBILE_NETWORK_SETTINGS = new Intent(Intent.ACTION_MAIN)
.setComponent(new ComponentName("com.android.phone",
"com.android.phone.MobileNetworkSettings"));
- private static final Intent MOBILE_NETWORK_SETTINGS_MSIM = new Intent(Intent.ACTION_MAIN)
- .setClassName("com.android.phone", "com.android.phone.msim.SelectSubscription")
- .putExtra("PACKAGE", "com.android.phone")
- .putExtra("TARGET_CLASS", "com.android.phone.MobileNetworkSettings")
- .putExtra("TARGET_THEME", "Theme.Material.Settings");
+ private static final Intent MOBILE_NETWORK_SETTINGS_MSIM
+ = new Intent("com.android.settings.sim.SIM_SUB_INFO_SETTINGS");
private final NetworkController mController;
private final MobileDataController mDataController;
@@ -93,6 +92,13 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
}
@Override
+ protected void handleUserSwitch(int newUserId) {
+ if (newUserId != UserHandle.USER_OWNER) {
+ refreshState();
+ }
+ }
+
+ @Override
protected void handleClick() {
MetricsLogger.action(mContext, getMetricsCategory());
if (mDataController.isMobileDataSupported()) {
@@ -118,7 +124,8 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
@Override
protected void handleUpdateState(SignalState state, Object arg) {
- state.visible = mController.hasMobileDataFeature();
+ state.visible = mController.hasMobileDataFeature()
+ && (ActivityManager.getCurrentUser() == UserHandle.USER_OWNER);
if (!state.visible) return;
CallbackInfo cb = (CallbackInfo) arg;
if (cb == null) {
@@ -140,7 +147,9 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
state.label = cb.enabled
? removeTrailingPeriod(cb.enabledDesc)
- : r.getString(R.string.quick_settings_rssi_emergency_only);
+ : mDataController.isMobileDataSupported() ?
+ r.getString(R.string.data_sim_not_configured) :
+ r.getString(R.string.quick_settings_rssi_emergency_only);
final String signalContentDesc = cb.enabled && (cb.mobileSignalIconId > 0)
? cb.signalContentDescription
@@ -225,10 +234,14 @@ public class CellularTile extends QSTile<QSTile.SignalState> {
// Make sure signal gets cleared out when no sims.
mInfo.mobileSignalIconId = 0;
mInfo.dataTypeIconId = 0;
- // Show a No SIMs description to avoid emergency calls message.
+ // Show a No SIMs description if we're incapable of supporting mobile data
+ // to avoid showing an emergency mode description. If we're still capable of
+ // supporting mobile data, notify the user that the data sim is not configured
+ // only relevant in MSIM scenario: CYNGNOS-2211
mInfo.enabled = true;
- mInfo.enabledDesc = mContext.getString(
- R.string.keyguard_missing_sim_message_short);
+ mInfo.enabledDesc = mDataController.isMobileDataSupported() ?
+ mContext.getString(R.string.data_sim_not_configured)
+ : mContext.getString(R.string.keyguard_missing_sim_message_short);
mInfo.signalContentDescription = mInfo.enabledDesc;
}
refreshState(mInfo);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 0cb9dcf..0d43f8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -114,7 +114,7 @@ public class DndTile extends QSTile<QSTile.BooleanState> {
mDisableTotalSilence.setAllowAnimation(true);
MetricsLogger.action(mContext, getMetricsCategory(), !mState.value);
if (mState.value) {
- showDetail(true);
+ mController.setZen(Global.ZEN_MODE_OFF, null, TAG);
} else {
int zen = Prefs.getInt(mContext, Prefs.Key.DND_FAVORITE_ZEN, Global.ZEN_MODE_ALARMS);
mController.setZen(zen, null, TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index d1b167e..25a7fb7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -21,6 +21,9 @@ import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiDevice;
import android.provider.Settings;
import com.android.internal.logging.MetricsLogger;
@@ -31,6 +34,8 @@ import com.android.systemui.qs.UsageTracker;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.statusbar.policy.HotspotController;
+import java.util.List;
+
/** Quick settings tile: Hotspot **/
public class HotspotTile extends QSTile<QSTile.BooleanState> {
@@ -44,12 +49,16 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> {
private final HotspotController mController;
private final Callback mCallback = new Callback();
private final UsageTracker mUsageTracker;
+ private final ConnectivityManager mConnectivityManager;
+ private boolean mListening;
+ private int mNumConnectedClients = 0;
public HotspotTile(Host host) {
super(host);
mController = host.getHotspotController();
mUsageTracker = newUsageTracker(host.getContext());
mUsageTracker.setListening(true);
+ mConnectivityManager = host.getContext().getSystemService(ConnectivityManager.class);
}
@Override
@@ -65,11 +74,16 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> {
@Override
public void setListening(boolean listening) {
+ if (mListening == listening) return;
if (listening) {
mController.addCallback(mCallback);
+ mContext.registerReceiver(mTetherConnectStateChangedReceiver,
+ new IntentFilter(ConnectivityManager.TETHER_CONNECT_STATE_CHANGED));
} else {
mController.removeCallback(mCallback);
+ mContext.unregisterReceiver(mTetherConnectStateChangedReceiver);
}
+ mListening = listening;
}
@Override
@@ -111,13 +125,19 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> {
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.visible = mController.isHotspotSupported() && mUsageTracker.isRecentlyUsed();
- state.label = mContext.getString(R.string.quick_settings_hotspot_label);
if (arg instanceof Boolean) {
state.value = (boolean) arg;
} else {
state.value = mController.isHotspotEnabled();
}
+ if (state.visible && state.value) {
+ state.label = mContext.getResources().getQuantityString(
+ R.plurals.wifi_hotspot_connected_clients_label, mNumConnectedClients,
+ mNumConnectedClients);
+ } else {
+ state.label = mContext.getString(R.string.quick_settings_hotspot_label);
+ }
state.icon = state.visible && state.value ? mEnable : mDisable;
}
@@ -140,6 +160,15 @@ public class HotspotTile extends QSTile<QSTile.BooleanState> {
R.integer.days_to_show_hotspot_tile);
}
+ private BroadcastReceiver mTetherConnectStateChangedReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final List<WifiDevice> clients = mConnectivityManager.getTetherConnectedSta();
+ mNumConnectedClients = clients != null ? clients.size() : 0;
+ refreshState();
+ }
+ };
+
private final class Callback implements HotspotController.Callback {
@Override
public void onHotspotChanged(boolean enabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LiveDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LiveDisplayTile.java
index b14934f..f59c876 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LiveDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LiveDisplayTile.java
@@ -16,14 +16,12 @@
package com.android.systemui.qs.tiles;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.UserHandle;
-import android.provider.Settings;
import com.android.internal.util.ArrayUtils;
import com.android.systemui.R;
@@ -40,10 +38,10 @@ public class LiveDisplayTile extends QSTile<LiveDisplayTile.LiveDisplayState> {
new Intent("android.settings.LIVEDISPLAY_SETTINGS");
private final LiveDisplayObserver mObserver;
- private final String[] mEntries;
- private final String[] mDescriptionEntries;
- private final String[] mAnnouncementEntries;
- private final String[] mValues;
+ private String[] mEntries;
+ private String[] mDescriptionEntries;
+ private String[] mAnnouncementEntries;
+ private String[] mValues;
private final int[] mEntryIconRes;
private boolean mListening;
@@ -69,10 +67,7 @@ public class LiveDisplayTile extends QSTile<LiveDisplayTile.LiveDisplayState> {
}
typedArray.recycle();
- mEntries = res.getStringArray(com.android.internal.R.array.live_display_entries);
- mDescriptionEntries = res.getStringArray(R.array.live_display_description);
- mAnnouncementEntries = res.getStringArray(R.array.live_display_announcement);
- mValues = res.getStringArray(com.android.internal.R.array.live_display_values);
+ updateEntries();
mOutdoorModeAvailable =
CMHardwareManager.getInstance(mContext)
@@ -86,6 +81,14 @@ public class LiveDisplayTile extends QSTile<LiveDisplayTile.LiveDisplayState> {
mObserver.startObserving();
}
+ private void updateEntries() {
+ Resources res = mContext.getResources();
+ mEntries = res.getStringArray(com.android.internal.R.array.live_display_entries);
+ mDescriptionEntries = res.getStringArray(R.array.live_display_description);
+ mAnnouncementEntries = res.getStringArray(R.array.live_display_announcement);
+ mValues = res.getStringArray(com.android.internal.R.array.live_display_values);
+ }
+
@Override
protected LiveDisplayState newTileState() {
return new LiveDisplayState();
@@ -115,6 +118,7 @@ public class LiveDisplayTile extends QSTile<LiveDisplayTile.LiveDisplayState> {
@Override
protected void handleUpdateState(LiveDisplayState state, Object arg) {
+ updateEntries();
state.visible = true;
state.mode = arg == null ? getCurrentModeIndex() : (Integer) arg;
state.label = mEntries[state.mode];
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LockscreenToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LockscreenToggleTile.java
index 2d764ba..a147d30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LockscreenToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LockscreenToggleTile.java
@@ -23,6 +23,9 @@ import com.android.systemui.SystemUIApplication;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
+
+import cyanogenmod.app.Profile;
+import cyanogenmod.app.ProfileManager;
import cyanogenmod.providers.CMSettings;
import org.cyanogenmod.internal.logging.CMMetricsLogger;
@@ -32,7 +35,6 @@ public class LockscreenToggleTile extends QSTile<QSTile.BooleanState>
private static final Intent LOCK_SCREEN_SETTINGS =
new Intent("android.settings.LOCK_SCREEN_SETTINGS");
- private KeyguardViewMediator mKeyguardViewMediator;
private KeyguardMonitor mKeyguard;
private boolean mListening;
@@ -42,21 +44,13 @@ public class LockscreenToggleTile extends QSTile<QSTile.BooleanState>
super(host);
mKeyguard = host.getKeyguardMonitor();
- mKeyguardViewMediator =
- ((SystemUIApplication)
- mContext.getApplicationContext()).getComponent(KeyguardViewMediator.class);
mSettingsObserver = new KeyguardViewMediator.LockscreenEnabledSettingsObserver(mContext,
mUiHandler) {
@Override
public void update() {
- boolean newState = CMSettings.Secure.getIntForUser(
- mContext.getContentResolver(),
- CMSettings.Secure.LOCKSCREEN_INTERNALLY_ENABLED,
- getPersistedDefaultOldSetting() ? 1 : 0,
- UserHandle.USER_CURRENT) != 0;
- refreshState(newState);
+ refreshState();
}
};
@@ -97,24 +91,46 @@ public class LockscreenToggleTile extends QSTile<QSTile.BooleanState>
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- final boolean lockscreenEnforced = mKeyguardViewMediator.lockscreenEnforcedByDevicePolicy();
- final boolean lockscreenEnabled = lockscreenEnforced ||
- arg != null ? (Boolean) arg : mKeyguardViewMediator.getKeyguardEnabledInternal();
-
- state.value = lockscreenEnabled;
- state.visible = mKeyguardViewMediator.isKeyguardBound();
- state.enabled = !mKeyguard.isShowing() || !mKeyguard.isSecure();
- state.label = mContext.getString(lockscreenEnforced
- ? R.string.quick_settings_lockscreen_label_enforced
- : R.string.quick_settings_lockscreen_label);
- if (lockscreenEnabled) {
- state.icon = ResourceIcon.get(R.drawable.ic_qs_lock_screen_on);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_lock_screen_on);
+ KeyguardViewMediator mediator = ((SystemUIApplication)
+ mContext.getApplicationContext()).getComponent(KeyguardViewMediator.class);
+
+ if (mediator == null) {
+ state.visible = false;
+ state.value = false;
+ state.enabled = false;
} else {
- state.icon = ResourceIcon.get(R.drawable.ic_qs_lock_screen_off);
- state.contentDescription = mContext.getString(
- R.string.accessibility_quick_settings_lock_screen_off);
+ final boolean lockscreenEnforced = mediator.lockscreenEnforcedByDevicePolicy();
+ final boolean lockscreenEnabled = lockscreenEnforced ||
+ arg != null ? (Boolean) arg : mediator.getKeyguardEnabledInternal();
+
+ state.visible = mediator.isKeyguardBound();
+
+ if (mediator.isProfileDisablingKeyguard()) {
+ state.value = false;
+ state.enabled = false;
+ state.label = mContext.getString(
+ R.string.quick_settings_lockscreen_label_locked_by_profile);
+ } else if (lockscreenEnforced) {
+ state.value = true;
+ state.enabled = false;
+ state.label = mContext.getString(
+ R.string.quick_settings_lockscreen_label_enforced);
+ } else {
+ state.value = lockscreenEnabled;
+ state.enabled = !mKeyguard.isShowing() || !mKeyguard.isSecure();
+
+ state.label = mContext.getString(R.string.quick_settings_lockscreen_label);
+ }
+ // update icon
+ if (lockscreenEnabled) {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_lock_screen_on);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_lock_screen_on);
+ } else {
+ state.icon = ResourceIcon.get(R.drawable.ic_qs_lock_screen_off);
+ state.contentDescription = mContext.getString(
+ R.string.accessibility_quick_settings_lock_screen_off);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenTimeoutTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenTimeoutTile.java
index 81899d3..e933787 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenTimeoutTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenTimeoutTile.java
@@ -61,9 +61,6 @@ public class ScreenTimeoutTile extends QSTile<ScreenTimeoutTile.TimeoutState> {
new AnimationIcon(R.drawable.ic_qs_screen_timeout_long_reverse_avd);
private String[] mEntries, mValues;
- private boolean mShowingDetail;
- ArrayList<Integer> mAnimationList
- = new ArrayList<Integer>();
public ScreenTimeoutTile(Host host) {
super(host);
@@ -127,8 +124,6 @@ public class ScreenTimeoutTile extends QSTile<ScreenTimeoutTile.TimeoutState> {
@Override
protected void handleClick() {
if (mEntries.length > 0) {
- mShowingDetail = true;
- mAnimationList.clear();
showDetail(true);
}
}
@@ -190,10 +185,6 @@ public class ScreenTimeoutTile extends QSTile<ScreenTimeoutTile.TimeoutState> {
}
@Override
protected void handleUpdateState(final TimeoutState state, Object arg) {
- if (mAnimationList.isEmpty() && mShowingDetail && arg == null) {
- return;
- }
-
int newTimeout = getScreenTimeout();
AnimationIcon d = null;
@@ -334,7 +325,6 @@ public class ScreenTimeoutTile extends QSTile<ScreenTimeoutTile.TimeoutState> {
mUiHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mShowingDetail = false;
refreshState(true);
}
}, 100);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 3917bab..b3a3dfd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -46,6 +46,7 @@ import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIApplication;
+import com.android.systemui.cm.UserContentObserver;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoadPlan;
@@ -61,6 +62,8 @@ import com.android.systemui.statusbar.phone.PhoneStatusBar;
import java.util.ArrayList;
+import cyanogenmod.providers.CMSettings;
+
/**
* Annotation for a method that is only called from the primary user's SystemUI process and will be
* proxied to the current user.
@@ -161,6 +164,35 @@ public class Recents extends SystemUI
}
}
+ class RecentsSettingsObserver extends UserContentObserver {
+
+ public RecentsSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ protected void observe() {
+ super.observe();
+ mContext.getContentResolver().registerContentObserver(
+ CMSettings.System.getUriFor(CMSettings.System.RECENTS_SHOW_SEARCH_BAR),
+ false, this);
+ update();
+ }
+
+ @Override
+ protected void unobserve() {
+ super.unobserve();
+ mContext.getContentResolver().unregisterContentObserver(this);
+ }
+
+ @Override
+ protected void update() {
+ if (mConfig.updateShowSearch(mContext)) {
+ reloadHeaderBarLayout();
+ }
+ }
+ }
+
static RecentsComponent.Callbacks sRecentsComponentCallbacks;
static RecentsTaskLoadPlan sInstanceLoadPlan;
static Recents sInstance;
@@ -171,6 +203,7 @@ public class Recents extends SystemUI
TaskStackListenerImpl mTaskStackListener;
RecentsOwnerEventProxyReceiver mProxyBroadcastReceiver;
RecentsAppWidgetHost mAppWidgetHost;
+ RecentsSettingsObserver mSettingsObserver;
boolean mBootCompleted;
boolean mStartAnimationTriggered;
boolean mCanReuseTaskStackViews = true;
@@ -259,6 +292,9 @@ public class Recents extends SystemUI
// Load the header bar layout
reloadHeaderBarLayout();
+ mSettingsObserver = new RecentsSettingsObserver(mHandler);
+ mSettingsObserver.observe();
+
// When we start, preload the data associated with the previous recent tasks.
// We can use a new plan since the caches will be the same.
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
@@ -549,7 +585,8 @@ public class Recents extends SystemUI
// Try and pre-emptively bind the search widget on startup to ensure that we
// have the right thumbnail bounds to animate to.
// Note: We have to reload the widget id before we get the task stack bounds below
- if (mSystemServicesProxy.getOrBindSearchAppWidget(mContext, mAppWidgetHost) != null) {
+ if (mConfig.searchBarEnabled &&
+ mSystemServicesProxy.getOrBindSearchAppWidget(mContext, mAppWidgetHost) != null) {
mConfig.getSearchBarBounds(mWindowRect.width(), mWindowRect.height(),
mStatusBarHeight, searchBarBounds);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index d1d642f..f4fe677 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -25,11 +25,9 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.res.Resources;
import android.os.Bundle;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.provider.Settings;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewStub;
@@ -38,7 +36,6 @@ import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.Prefs;
import com.android.systemui.R;
-import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
@@ -133,7 +130,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
/**
* Broadcast receiver to handle messages from AlternateRecentsComponent.
*/
- private final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
+ final BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -163,7 +160,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
/**
* Broadcast receiver to handle messages from the system
*/
- private final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
+ final BroadcastReceiver mSystemBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -182,7 +179,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
/**
* A custom debug trigger to listen for a debug key chord.
*/
- private final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() {
+ final DebugTrigger mDebugTrigger = new DebugTrigger(new Runnable() {
@Override
public void run() {
onDebugModeTriggered();
@@ -211,9 +208,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
ArrayList<TaskStack> stacks = plan.getAllTaskStacks();
mConfig.launchedWithNoRecentTasks = !plan.hasTasks();
- if (!mConfig.launchedWithNoRecentTasks) {
- mRecentsView.setTaskStacks(stacks);
- }
+ mRecentsView.setTaskStacks(stacks);
// Create the home intent runnable
Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
@@ -222,10 +217,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
mFinishLaunchHomeRunnable = new FinishRecentsRunnable(homeIntent,
ActivityOptions.makeCustomAnimation(this,
- mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_enter :
- R.anim.recents_to_launcher_enter,
- mConfig.launchedFromSearchHome ? R.anim.recents_to_search_launcher_exit :
- R.anim.recents_to_launcher_exit));
+ R.anim.recents_to_search_launcher_enter,
+ R.anim.recents_to_search_launcher_exit));
// Mark the task that is the launch target
int taskStackCount = stacks.size();
@@ -264,28 +257,15 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
mEmptyView.setVisibility(View.GONE);
mEmptyView.setOnClickListener(null);
}
- boolean showSearchBar = CMSettings.System.getInt(getContentResolver(),
- CMSettings.System.RECENTS_SHOW_SEARCH_BAR, 1) == 1;
-
- if (mRecentsView.hasValidSearchBar()) {
- if (showSearchBar) {
+ if (!mConfig.searchBarEnabled) {
+ mRecentsView.setSearchBarVisibility(View.GONE);
+ } else {
+ if (mRecentsView.hasValidSearchBar()) {
mRecentsView.setSearchBarVisibility(View.VISIBLE);
} else {
- mRecentsView.setSearchBarVisibility(View.GONE);
- }
- } else {
- if (showSearchBar) {
refreshSearchWidgetView();
}
}
-
- // Update search bar space height
- if (showSearchBar) {
- mConfig.searchBarSpaceHeightPx = getResources().getDimensionPixelSize(
- R.dimen.recents_search_bar_space_height);
- } else {
- mConfig.searchBarSpaceHeightPx = 0;
- }
}
// Animate the SystemUI scrims into view
@@ -459,6 +439,14 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
}
@Override
+ protected void onResume() {
+ if (mConfig.searchBarEnabled && mConfig.launchedFromHome) {
+ overridePendingTransition(0, 0);
+ }
+ super.onResume();
+ }
+
+ @Override
protected void onPause() {
super.onPause();
if (mAfterPauseRunnable != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 41d52b8..d7e8b99 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -31,6 +31,7 @@ import com.android.systemui.R;
import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.misc.SystemServicesProxy;
+import cyanogenmod.providers.CMSettings;
/** A static Recents configuration for the current context
* NOTE: We should not hold any references to a Context from a static instance */
@@ -73,6 +74,7 @@ public class RecentsConfiguration {
public int maxNumTasksToLoad;
/** Search bar */
+ public boolean searchBarEnabled = true;
public int searchBarSpaceHeightPx;
/** Task stack */
@@ -279,6 +281,13 @@ public class RecentsConfiguration {
svelteLevel = res.getInteger(R.integer.recents_svelte_level);
}
+ public boolean updateShowSearch(Context context) {
+ boolean wasEnabled = searchBarEnabled;
+ searchBarEnabled = CMSettings.System.getInt(context.getContentResolver(),
+ CMSettings.System.RECENTS_SHOW_SEARCH_BAR, 1) == 1;
+ return wasEnabled != searchBarEnabled;
+ }
+
/** Updates the system insets */
public void updateSystemInsets(Rect insets) {
systemInsets.set(insets);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 947c19c..64622620 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -323,7 +323,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
// Get the search bar bounds and measure the search bar layout
Rect searchBarSpaceBounds = new Rect();
- if (mSearchBar != null) {
+ if (mSearchBar != null && mConfig.searchBarEnabled) {
mConfig.getSearchBarBounds(width, height, mConfig.systemInsets.top, searchBarSpaceBounds);
mSearchBar.measure(
MeasureSpec.makeMeasureSpec(searchBarSpaceBounds.width(), MeasureSpec.EXACTLY),
@@ -360,7 +360,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
// Get the search bar bounds so that we lay it out
- if (mSearchBar != null) {
+ if (mSearchBar != null && mConfig.searchBarEnabled) {
Rect searchBarSpaceBounds = new Rect();
mConfig.getSearchBarBounds(getMeasuredWidth(), getMeasuredHeight(),
mConfig.systemInsets.top, searchBarSpaceBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ce5cce5..7b608bb 100755
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1345,27 +1345,50 @@ public abstract class BaseStatusBar extends SystemUI implements
View contentViewLocal = null;
View bigContentViewLocal = null;
View headsUpContentViewLocal = null;
- String themePackageName = mCurrentTheme != null ?
- mCurrentTheme.getOverlayForStatusBar() : null;
+ String themePackageName = mCurrentTheme != null
+ ? mCurrentTheme.getOverlayPkgNameForApp(sbn.getPackageName()) : null;
+ String statusBarThemePackageName = mCurrentTheme != null
+ ? mCurrentTheme.getOverlayForStatusBar() : null;
+
try {
contentViewLocal = contentView.apply(
sbn.getPackageContext(mContext),
contentContainer,
mOnClickHandler,
- themePackageName);
+ statusBarThemePackageName);
+
+ final int platformTemplateRootViewId =
+ com.android.internal.R.id.status_bar_latest_event_content;
+ final String inflationThemePackageName;
+ if (themePackageName != null
+ && !TextUtils.equals(themePackageName, statusBarThemePackageName)
+ && contentViewLocal.getId() != platformTemplateRootViewId) {
+ // This notification uses custom RemoteViews, and its app uses a different
+ // theme than the status bar. Re-inflate the views using the app's theme,
+ // as the RemoteViews likely will contain resources of the app, not the platform
+ inflationThemePackageName = themePackageName;
+ contentViewLocal = contentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer,
+ mOnClickHandler,
+ inflationThemePackageName);
+ } else {
+ inflationThemePackageName = statusBarThemePackageName;
+ }
+
if (bigContentView != null) {
bigContentViewLocal = bigContentView.apply(
sbn.getPackageContext(mContext),
contentContainer,
mOnClickHandler,
- themePackageName);
+ inflationThemePackageName);
}
if (headsUpContentView != null) {
headsUpContentViewLocal = headsUpContentView.apply(
sbn.getPackageContext(mContext),
contentContainer,
mOnClickHandler,
- themePackageName);
+ inflationThemePackageName);
}
}
catch (RuntimeException e) {
@@ -1904,8 +1927,9 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean shouldInterrupt = shouldInterrupt(entry, notification);
boolean alertAgain = alertAgain(entry, n);
+ final StatusBarNotification oldNotification = entry.notification;
entry.notification = notification;
- mGroupManager.onEntryUpdated(entry, entry.notification);
+ mGroupManager.onEntryUpdated(entry, oldNotification);
boolean updateSuccessful = false;
if (applyInPlace) {
@@ -1947,7 +1971,9 @@ public abstract class BaseStatusBar extends SystemUI implements
entry.icon.set(ic);
inflateViews(entry, mStackScroller);
}
- updateHeadsUp(key, entry, shouldInterrupt, alertAgain);
+ if (mUseHeadsUp) {
+ updateHeadsUp(key, entry, shouldInterrupt, alertAgain);
+ }
mNotificationData.updateRanking(ranking);
updateNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 2233d13..ecaa809 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -353,10 +353,13 @@ public class SignalClusterView
for (PhoneState state : mPhoneStates) {
if (state.mMobile != null) {
+ state.maybeStopAnimatableDrawable(state.mMobile);
state.mMobile.setImageDrawable(null);
+ state.mLastMobileStrengthId = -1;
}
if (state.mMobileType != null) {
state.mMobileType.setImageDrawable(null);
+ state.mLastMobileTypeId = -1;
}
}
@@ -484,6 +487,8 @@ public class SignalClusterView
private final int mSubId;
private boolean mMobileVisible = false;
private int mMobileStrengthId = 0, mMobileTypeId = 0;
+ private int mLastMobileStrengthId = -1;
+ private int mLastMobileTypeId = -1;
private boolean mIsMobileTypeIconWide;
private String mMobileDescription, mMobileTypeDescription;
private boolean mShowRoamingIndicator;
@@ -509,25 +514,16 @@ public class SignalClusterView
public boolean apply(boolean isSecondaryIcon) {
if (mMobileVisible && !mIsAirplaneMode) {
- mMobile.setImageResource(mMobileStrengthId);
- Drawable mobileDrawable = mMobile.getDrawable();
- if (mobileDrawable instanceof Animatable) {
- Animatable ad = (Animatable) mobileDrawable;
- if (!ad.isRunning()) {
- ad.start();
- }
+ if (mLastMobileStrengthId != mMobileStrengthId) {
+ updateAnimatableIcon(mMobile, mMobileStrengthId);
+ updateAnimatableIcon(mMobileDark, mMobileStrengthId);
+ mLastMobileStrengthId = mMobileStrengthId;
}
- mMobileDark.setImageResource(mMobileStrengthId);
- Drawable mobileDarkDrawable = mMobileDark.getDrawable();
- if (mobileDarkDrawable instanceof Animatable) {
- Animatable ad = (Animatable) mobileDarkDrawable;
- if (!ad.isRunning()) {
- ad.start();
- }
+ if (mLastMobileTypeId != mMobileTypeId) {
+ mMobileType.setImageResource(mMobileTypeId);
+ mLastMobileTypeId = mMobileTypeId;
}
-
- mMobileType.setImageResource(mMobileTypeId);
mMobileGroup.setContentDescription(mMobileTypeDescription
+ " " + mMobileDescription);
mMobileGroup.setVisibility(View.VISIBLE);
@@ -552,6 +548,32 @@ public class SignalClusterView
return mMobileVisible;
}
+ private void updateAnimatableIcon(ImageView view, int resId) {
+ maybeStopAnimatableDrawable(view);
+ view.setImageResource(resId);
+ maybeStartAnimatableDrawable(view);
+ }
+
+ private void maybeStopAnimatableDrawable(ImageView view) {
+ Drawable drawable = view.getDrawable();
+ if (drawable instanceof Animatable) {
+ Animatable ad = (Animatable) drawable;
+ if (ad.isRunning()) {
+ ad.stop();
+ }
+ }
+ }
+
+ private void maybeStartAnimatableDrawable(ImageView view) {
+ Drawable drawable = view.getDrawable();
+ if (drawable instanceof Animatable) {
+ Animatable ad = (Animatable) drawable;
+ if (!ad.isRunning()) {
+ ad.start();
+ }
+ }
+ }
+
public void populateAccessibilityEvent(AccessibilityEvent event) {
if (mMobileVisible && mMobileGroup != null
&& mMobileGroup.getContentDescription() != null) {
@@ -562,6 +584,7 @@ public class SignalClusterView
public void setIconTint(int tint, float darkIntensity) {
applyDarkIntensity(darkIntensity, mMobile, mMobileDark);
setTint(mMobileType, tint);
+ setTint(mMobileRoaming, tint);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java
index 1991602..40e4330 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/VisualizerView.java
@@ -26,19 +26,21 @@ 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.util.Log;
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 static final String TAG = VisualizerView.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
private Paint mPaint;
private Visualizer mVisualizer;
private ObjectAnimator mVisualizerColorAnimator;
@@ -89,9 +91,14 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
private final Runnable mLinkVisualizer = new Runnable() {
@Override
public void run() {
+ if (DEBUG) {
+ Log.w(TAG, "+++ mLinkVisualizer run()");
+ }
+
try {
mVisualizer = new Visualizer(0);
} catch (Exception e) {
+ Log.e(TAG, "error initializing visualizer", e);
return;
}
@@ -101,17 +108,26 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
false, true);
mVisualizer.setEnabled(true);
+ if (DEBUG) {
+ Log.w(TAG, "--- mLinkVisualizer run()");
+ }
}
};
private final Runnable mUnlinkVisualizer = new Runnable() {
@Override
public void run() {
+ if (DEBUG) {
+ Log.w(TAG, "+++ mUnlinkVisualizer run(), mVisualizer: " + mVisualizer);
+ }
if (mVisualizer != null) {
mVisualizer.setEnabled(false);
mVisualizer.release();
mVisualizer = null;
}
+ if (DEBUG) {
+ Log.w(TAG, "--- mUninkVisualizer run()");
+ }
}
};
@@ -223,6 +239,7 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
mKeyguardMonitor = kgm;
if (isAttachedToWindow()) {
// otherwise we might never register ourselves
+ mKeyguardMonitor.removeCallback(this);
mKeyguardMonitor.addCallback(this);
updateViewVisibility();
}
@@ -230,6 +247,9 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
public void setVisible(boolean visible) {
if (mVisible != visible) {
+ if (DEBUG) {
+ Log.i(TAG, "setVisible() called with visible = [" + visible + "]");
+ }
mVisible = visible;
checkStateChanged();
}
@@ -237,6 +257,9 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
public void setDozing(boolean dozing) {
if (mDozing != dozing) {
+ if (DEBUG) {
+ Log.i(TAG, "setDozing() called with dozing = [" + dozing + "]");
+ }
mDozing = dozing;
checkStateChanged();
}
@@ -244,6 +267,9 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
public void setPlaying(boolean playing) {
if (mPlaying != playing) {
+ if (DEBUG) {
+ Log.i(TAG, "setPlaying() called with playing = [" + playing + "]");
+ }
mPlaying = playing;
checkStateChanged();
}
@@ -251,6 +277,9 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
public void setPowerSaveMode(boolean powerSaveMode) {
if (mPowerSaveMode != powerSaveMode) {
+ if (DEBUG) {
+ Log.i(TAG, "setPowerSaveMode() called with powerSaveMode = [" + powerSaveMode + "]");
+ }
mPowerSaveMode = powerSaveMode;
checkStateChanged();
}
@@ -258,6 +287,9 @@ public class VisualizerView extends View implements Palette.PaletteAsyncListener
public void setOccluded(boolean occluded) {
if (mOccluded != occluded) {
+ if (DEBUG) {
+ Log.i(TAG, "setOccluded() called with occluded = [" + occluded + "]");
+ }
mOccluded = occluded;
checkStateChanged();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 2912963..7135836 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -173,7 +173,7 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
if (DEBUG_FP_WAKELOCK) {
Log.i(TAG, "fp wakelock: Authenticated, waking up...");
}
- mPowerManager.wakeUp(SystemClock.uptimeMillis());
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.policy:FINGERPRINT");
}
releaseFingerprintWakeLock();
switch (mMode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index ecc3a9b..d95a46a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -221,6 +221,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mShortcutHelper = new LockscreenShortcutsHelper(mContext, this);
watchForCameraPolicyChanges();
updateCameraVisibility();
+ updateLeftButtonVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
mLockIcon.update();
@@ -257,6 +258,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mCameraImageView.setContentDescription(contentDescription);
mCameraImageView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
private void initAccessibility() {
@@ -299,11 +301,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
mPhoneStatusBar = phoneStatusBar;
updateCameraVisibility(); // in case onFinishInflate() was called too early
+ updateLeftButtonVisibility();
}
public void setUserSetupComplete(boolean userSetupComplete) {
mUserSetupComplete = userSetupComplete;
updateCameraVisibility();
+ updateLeftButtonVisibility();
updateLeftAffordanceIcon();
}
@@ -324,6 +328,21 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
KeyguardUpdateMonitor.getCurrentUser());
}
+ private void updateLeftButtonVisibility() {
+ if (mLeftAffordanceView == null) {
+ return;
+ }
+ boolean visible = mUserSetupComplete;
+ if (visible) {
+ if (isTargetCustom(Shortcuts.LEFT_SHORTCUT)) {
+ visible = !mShortcutHelper.isTargetEmpty(Shortcuts.LEFT_SHORTCUT);
+ } else {
+ // Display left shortcut
+ }
+ }
+ mLeftAffordanceView.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
private void updateCameraVisibility() {
if (mCameraImageView == null) {
// Things are not set up yet; reply hazy, ask again later
@@ -364,6 +383,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLeftAffordanceView.setImageDrawable(drawable);
mLeftAffordanceView.setContentDescription(contentDescription);
mLeftAffordanceView.setDefaultFilter(shouldGrayScale ? mGrayScaleFilter : null);
+ updateLeftButtonVisibility();
}
public boolean isLeftVoiceAssist() {
@@ -592,6 +612,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
if (changedView == this && visibility == VISIBLE) {
mLockIcon.update();
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
}
@@ -628,6 +649,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public void onUnlockMethodStateChanged() {
mLockIcon.update();
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
private void inflateCameraPreview() {
@@ -699,6 +721,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void run() {
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
});
}
@@ -709,6 +732,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public void onUserSwitchComplete(int userId) {
updateCameraVisibility();
+ updateLeftButtonVisibility();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 395f350..65e2096 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -32,6 +32,8 @@ import com.android.keyguard.R;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
+import org.cyanogenmod.internal.util.CmLockPatternUtils;
+
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
@@ -40,9 +42,14 @@ import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
*/
public class KeyguardBouncer {
+ public static final int UNLOCK_SEQUENCE_DEFAULT = 0;
+ public static final int UNLOCK_SEQUENCE_BOUNCER_FIRST = 1;
+ public static final int UNLOCK_SEQUENCE_FORCE_BOUNCER = 2;
+
private Context mContext;
private ViewMediatorCallback mCallback;
private LockPatternUtils mLockPatternUtils;
+ private CmLockPatternUtils mCmLockPatternUtils;
private ViewGroup mContainer;
private StatusBarWindowManager mWindowManager;
private KeyguardHostView mKeyguardView;
@@ -65,6 +72,7 @@ public class KeyguardBouncer {
mLockPatternUtils = lockPatternUtils;
mContainer = container;
mWindowManager = windowManager;
+ mCmLockPatternUtils = new CmLockPatternUtils(mContext);
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
}
@@ -207,28 +215,42 @@ public class KeyguardBouncer {
}
/**
- * @return True if and only if the security method should be shown before showing the
- * notifications on Keyguard, like SIM PIN/PUK.
+ * @return Whether the bouncer should be shown first, this could be because of SIM PIN/PUK
+ * or it just could be chosen to be shown first.
*/
- public boolean needsFullscreenBouncer() {
+ public int needsFullscreenBouncer() {
ensureView();
if (mKeyguardView != null) {
SecurityMode mode = mKeyguardView.getSecurityMode();
- return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
+ if (mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk)
+ return UNLOCK_SEQUENCE_FORCE_BOUNCER;
+ // "Bouncer first" mode currently only available to some security methods.
+ else if ((mode == SecurityMode.Pattern || mode == SecurityMode.Password
+ || mode == SecurityMode.PIN) && (mLockPatternUtils != null &&
+ mCmLockPatternUtils.shouldPassToSecurityView(
+ KeyguardUpdateMonitor.getCurrentUser())))
+ return UNLOCK_SEQUENCE_BOUNCER_FIRST;
}
- return false;
+ return UNLOCK_SEQUENCE_DEFAULT;
}
/**
* Like {@link #needsFullscreenBouncer}, but uses the currently visible security method, which
* makes this method much faster.
*/
- public boolean isFullscreenBouncer() {
+ public int isFullscreenBouncer() {
if (mKeyguardView != null) {
SecurityMode mode = mKeyguardView.getCurrentSecurityMode();
- return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
+ if (mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk)
+ return UNLOCK_SEQUENCE_FORCE_BOUNCER;
+ // "Bouncer first" mode currently only available to some security methods.
+ else if ((mode == SecurityMode.Pattern || mode == SecurityMode.Password
+ || mode == SecurityMode.PIN) && (mLockPatternUtils != null &&
+ mCmLockPatternUtils.shouldPassToSecurityView(
+ KeyguardUpdateMonitor.getCurrentUser())))
+ return UNLOCK_SEQUENCE_BOUNCER_FIRST;
}
- return false;
+ return UNLOCK_SEQUENCE_DEFAULT;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 7524732..ec307de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- *
+ * Copyright (C) 2016 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
@@ -31,8 +31,10 @@ import android.widget.TextView;
import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.BatteryMeterView;
+import com.android.systemui.DockBatteryMeterView;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.DockBatteryController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -49,8 +51,8 @@ public class KeyguardStatusBarView extends RelativeLayout {
private MultiUserSwitch mMultiUserSwitch;
private ImageView mMultiUserAvatar;
private BatteryLevelTextView mBatteryLevel;
+ private BatteryLevelTextView mDockBatteryLevel;
- private BatteryController mBatteryController;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private int mSystemIconsSwitcherHiddenExpandedMargin;
@@ -69,6 +71,7 @@ public class KeyguardStatusBarView extends RelativeLayout {
mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
mBatteryLevel = (BatteryLevelTextView) findViewById(R.id.battery_level_text);
+ mDockBatteryLevel = (BatteryLevelTextView) findViewById(R.id.dock_battery_level_text);
mCarrierLabel = (TextView) findViewById(R.id.keyguard_carrier_text);
loadDimens();
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
@@ -110,6 +113,9 @@ public class KeyguardStatusBarView extends RelativeLayout {
removeView(mMultiUserSwitch);
}
mBatteryLevel.setVisibility(View.VISIBLE);
+ if (mDockBatteryLevel != null) {
+ mDockBatteryLevel.setVisibility(View.VISIBLE);
+ }
}
private void updateSystemIconsLayoutParams() {
@@ -130,9 +136,26 @@ public class KeyguardStatusBarView extends RelativeLayout {
}
public void setBatteryController(BatteryController batteryController) {
- mBatteryController = batteryController;
- ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
- mBatteryLevel.setBatteryController(batteryController);
+ BatteryMeterView v = ((BatteryMeterView) findViewById(R.id.battery));
+ v.setBatteryStateRegistar(batteryController);
+ v.setBatteryController(batteryController);
+ mBatteryLevel.setBatteryStateRegistar(batteryController);
+ }
+
+ public void setDockBatteryController(DockBatteryController dockBatteryController) {
+ DockBatteryMeterView v = ((DockBatteryMeterView) findViewById(R.id.dock_battery));
+ if (dockBatteryController != null) {
+ v.setBatteryStateRegistar(dockBatteryController);
+ mDockBatteryLevel.setBatteryStateRegistar(dockBatteryController);
+ } else {
+ if (v != null ) {
+ removeView(v);
+ }
+ if (mDockBatteryLevel != null) {
+ removeView(mDockBatteryLevel);
+ mDockBatteryLevel = null;
+ }
+ }
}
public void setUserSwitcherController(UserSwitcherController controller) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index b3ba926..c10f45b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -34,15 +34,14 @@ import android.database.ContentObserver;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
-import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
@@ -50,18 +49,15 @@ import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
-import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.android.systemui.R;
-import com.android.systemui.cm.UserContentObserver;
import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.ArrayList;
import cyanogenmod.providers.CMSettings;
@@ -227,7 +223,8 @@ public class NavigationBarView extends LinearLayout {
mBarTransitions = new NavigationBarTransitions(this);
mNavBarReceiver = new NavBarReceiver();
- getContext().registerReceiver(mNavBarReceiver, new IntentFilter(NAVBAR_EDIT_ACTION));
+ getContext().registerReceiverAsUser(mNavBarReceiver, UserHandle.ALL,
+ new IntentFilter(NAVBAR_EDIT_ACTION), null, null);
mSettingsObserver = new SettingsObserver(new Handler());
}
@@ -425,6 +422,19 @@ public class NavigationBarView extends LinearLayout {
setSideButtonVisibility(false, -1);
}
}
+ } else {
+ setVisibleOrGone(getCurrentView().findViewById(R.id.dpad_left), false);
+ setVisibleOrGone(getCurrentView().findViewById(R.id.dpad_right), false);
+ View one = getCurrentView().findViewById(mVertical ? R.id.six : R.id.one);
+ View six = getCurrentView().findViewById(mVertical ? R.id.one : R.id.six);
+ if (getSideButtonVisibility(true) != -1) {
+ one.setVisibility(getSideButtonVisibility(true));
+ setSideButtonVisibility(true, - 1);
+ }
+ if (getSideButtonVisibility(false) != -1) {
+ six.setVisibility(getSideButtonVisibility(false));
+ setSideButtonVisibility(false, -1);
+ }
}
}
@@ -879,19 +889,17 @@ public class NavigationBarView extends LinearLayout {
mEditBar.updateKeys();
removeButtonListeners();
updateButtonListeners();
- setDisabledFlags(mDisabledFlags, true /* force */);
+ updateShowDpadKeys();
setMenuVisibility(mShowMenu, true);
}
- private class SettingsObserver extends UserContentObserver {
+ private class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
}
- @Override
public void observe() {
- super.observe();
ContentResolver resolver = getContext().getContentResolver();
resolver.registerContentObserver(
CMSettings.System.getUriFor(CMSettings.System.NAVIGATION_BAR_MENU_ARROW_KEYS),
@@ -901,23 +909,20 @@ public class NavigationBarView extends LinearLayout {
onChange(false);
}
- @Override
public void unobserve() {
- super.unobserve();
getContext().getContentResolver().unregisterContentObserver(this);
}
@Override
- protected void update() {
- mShowDpadArrowKeys = CMSettings.System.getIntForUser(getContext().getContentResolver(),
- CMSettings.System.NAVIGATION_BAR_MENU_ARROW_KEYS, 0, UserHandle.USER_CURRENT) != 0;
- // reset saved side button visibilities
- for (int i = 0; i < mSideButtonVisibilities.length; i++) {
- for (int j = 0; j < mSideButtonVisibilities[i].length; j++) {
- mSideButtonVisibilities[i][j] = -1;
- }
- }
- setNavigationIconHints(mNavigationIconHints, true);
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ updateShowDpadKeys();
}
}
+
+ private void updateShowDpadKeys() {
+ mShowDpadArrowKeys = CMSettings.System.getIntForUser(getContext().getContentResolver(),
+ CMSettings.System.NAVIGATION_BAR_MENU_ARROW_KEYS, 0, UserHandle.USER_CURRENT) != 0;
+ setNavigationIconHints(mNavigationIconHints, true);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6adbe85..aaa7019 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1116,7 +1116,8 @@ public class NotificationPanelView extends PanelView implements
mAfforanceHelper.updatePreviews();
}
}
- if (keyguardShowing) {
+ if (statusBarState == StatusBarState.KEYGUARD ||
+ statusBarState == StatusBarState.SHADE_LOCKED) {
updateDozingVisibilities(false /* animate */);
if (mThirdPartyKeyguardViewComponent != null) {
if (mKeyguardExternalView == null) {
@@ -1237,7 +1238,8 @@ public class NotificationPanelView extends PanelView implements
@Override
public void run() {
mStatusBar.showKeyguard();
- mStatusBar.startActivity(intent, true);
+ mStatusBar.startActivityDismissingKeyguard(intent, false, true, true,
+ null);
}
});
}
@@ -2540,7 +2542,7 @@ public class NotificationPanelView extends PanelView implements
* @param x the x-coordinate the touch event
*/
private void updateVerticalPanelPosition(float x) {
- if (mNotificationStackScroller.getWidth() * 1.75f > getWidth()) {
+ if (mNotificationStackScroller.getWidth() * 1.75f >= getWidth()) {
resetVerticalPanelPosition();
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index f5cdcd1..e5711b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -42,8 +42,6 @@ import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import cyanogenmod.power.PerformanceManager;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -90,8 +88,6 @@ public abstract class PanelView extends FrameLayout {
private VelocityTrackerInterface mVelocityTracker;
private FlingAnimationUtils mFlingAnimationUtils;
- private final PerformanceManager mPerf;
-
private boolean mUpdateExpandOnLayout;
private View.OnLayoutChangeListener mLayoutChangeListener = new OnLayoutChangeListener() {
@Override
@@ -222,8 +218,6 @@ public abstract class PanelView extends FrameLayout {
mLinearOutSlowInInterpolator =
AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);
mBounceInterpolator = new BounceInterpolator();
-
- mPerf = PerformanceManager.getInstance(context);
}
protected void loadDimens() {
@@ -695,8 +689,6 @@ public abstract class PanelView extends FrameLayout {
}
}
- mPerf.cpuBoost((int)animator.getDuration() * 1000);
-
animator.addListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
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 41fd86a..adff973 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -42,7 +42,6 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
-import android.content.res.ThemeChangeRequest.RequestType;
import android.content.res.ThemeConfig;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -65,6 +64,7 @@ import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
import android.media.session.PlaybackState;
import android.os.AsyncTask;
+import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
@@ -125,6 +125,7 @@ import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.DemoMode;
+import com.android.systemui.DockBatteryMeterView;
import com.android.systemui.EventLogConstants;
import com.android.systemui.EventLogTags;
import com.android.systemui.Prefs;
@@ -161,10 +162,11 @@ 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;
-import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
+import com.android.systemui.statusbar.policy.BatteryStateRegistar.BatteryStateChangeCallback;
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
+import com.android.systemui.statusbar.policy.DockBatteryController;
import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HotspotControllerImpl;
@@ -188,6 +190,7 @@ import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChil
import com.android.systemui.statusbar.stack.StackStateAnimator;
import com.android.systemui.statusbar.stack.StackViewState;
import com.android.systemui.volume.VolumeComponent;
+import cyanogenmod.app.CMContextConstants;
import cyanogenmod.app.CustomTileListenerService;
import cyanogenmod.app.StatusBarPanelCustomTile;
@@ -216,6 +219,7 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import cyanogenmod.providers.CMSettings;
+import cyanogenmod.themes.IThemeService;
public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
@@ -241,7 +245,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private static final int MSG_CLOSE_PANELS = 1001;
private static final int MSG_OPEN_SETTINGS_PANEL = 1002;
private static final int MSG_LAUNCH_TRANSITION_TIMEOUT = 1003;
- private static final int MSG_UPDATE_NOTIFICATIONS = 1004;
// 1020-1040 reserved for BaseStatusBar
// Time after we abort the launch transition.
@@ -297,7 +300,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// These are no longer handled by the policy, because we need custom strategies for them
BluetoothControllerImpl mBluetoothController;
SecurityControllerImpl mSecurityController;
+ BatteryManager mBatteryManager;
BatteryController mBatteryController;
+ DockBatteryController mDockBatteryController;
LocationControllerImpl mLocationController;
NetworkControllerImpl mNetworkController;
HotspotControllerImpl mHotspotController;
@@ -420,6 +425,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private int mNavigationIconHints = 0;
private HandlerThread mHandlerThread;
+ private IThemeService mThemeService;
+ private long mLastThemeChangeTime = 0;
+
Runnable mLongPressBrightnessChange = new Runnable() {
@Override
public void run() {
@@ -861,6 +869,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mScreenPinningRequest = new ScreenPinningRequest(mContext);
updateCustomRecentsLongPressHandler(true);
+
+ mThemeService = IThemeService.Stub.asInterface(ServiceManager.getService(
+ CMContextConstants.CM_THEME_SERVICE));
}
// ================================================================================
@@ -1046,6 +1057,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mLocationController = new LocationControllerImpl(mContext,
mHandlerThread.getLooper()); // will post a notification
}
+ if (mBatteryManager == null) {
+ mBatteryManager = (BatteryManager) mContext.getSystemService(Context.BATTERY_SERVICE);
+ }
if (mBatteryController == null) {
mBatteryController = new BatteryController(mContext, mHandler);
mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
@@ -1058,7 +1072,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
+ public void onBatteryLevelChanged(boolean present, int level,
+ boolean pluggedIn, boolean charging) {
// noop
}
@@ -1068,6 +1083,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
});
}
+ if (mBatteryManager.isDockBatterySupported()) {
+ if (mDockBatteryController == null) {
+ mDockBatteryController = new DockBatteryController(mContext, mHandler);
+ }
+ }
if (mNetworkController == null) {
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
}
@@ -1265,13 +1285,36 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mUserInfoController.reloadUserInfo();
mHeader.setBatteryController(mBatteryController);
+
BatteryMeterView batteryMeterView =
((BatteryMeterView) mStatusBarView.findViewById(R.id.battery));
+ batteryMeterView.setBatteryStateRegistar(mBatteryController);
batteryMeterView.setBatteryController(mBatteryController);
batteryMeterView.setAnimationsEnabled(false);
((BatteryLevelTextView) mStatusBarView.findViewById(R.id.battery_level_text))
- .setBatteryController(mBatteryController);
+ .setBatteryStateRegistar(mBatteryController);
mKeyguardStatusBar.setBatteryController(mBatteryController);
+ mHeader.setDockBatteryController(mDockBatteryController);
+ mKeyguardStatusBar.setDockBatteryController(mDockBatteryController);
+ if (mDockBatteryController != null) {
+ DockBatteryMeterView dockBatteryMeterView =
+ ((DockBatteryMeterView) mStatusBarView.findViewById(R.id.dock_battery));
+ dockBatteryMeterView.setBatteryStateRegistar(mDockBatteryController);
+ ((BatteryLevelTextView) mStatusBarView.findViewById(R.id.dock_battery_level_text))
+ .setBatteryStateRegistar(mDockBatteryController);
+ } else {
+ DockBatteryMeterView dockBatteryMeterView =
+ (DockBatteryMeterView) mStatusBarView.findViewById(R.id.dock_battery);
+ if (dockBatteryMeterView != null) {
+ mStatusBarView.removeView(dockBatteryMeterView);
+ }
+ BatteryLevelTextView dockBatteryLevel =
+ (BatteryLevelTextView) mStatusBarView.findViewById(R.id.dock_battery_level_text);
+ if (dockBatteryLevel != null) {
+ mStatusBarView.removeView(dockBatteryLevel);
+ }
+ }
+
mVisualizerView.setKeyguardMonitor(mKeyguardMonitor);
mHeader.setNextAlarmController(mNextAlarmController);
mHeader.setWeatherController(mWeatherController);
@@ -1289,6 +1332,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_KEYGUARD_WALLPAPER_CHANGED);
+ filter.addAction(cyanogenmod.content.Intent.ACTION_SCREEN_CAMERA_GESTURE);
context.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
IntentFilter demoFilter = new IntentFilter();
@@ -1913,7 +1957,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
return entry.row.getParent() instanceof NotificationStackScrollLayout;
}
- private void handleUpdateNotifications() {
+ @Override
+ protected void updateNotifications() {
mNotificationData.filterAndSort();
updateNotificationShade();
@@ -1921,13 +1966,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- protected void updateNotifications() {
- if (!mHandler.hasMessages(MSG_UPDATE_NOTIFICATIONS)) {
- mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATIONS);
- }
- }
-
- @Override
protected void updateRowStates() {
super.updateRowStates();
mNotificationPanel.notifyVisibleChildrenChanged();
@@ -2144,23 +2182,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
- // apply user lockscreen image
- if (mMediaMetadata == null && backdropBitmap == null) {
- backdropBitmap = mKeyguardWallpaper;
- }
-
- boolean keyguardVisible = (mState != StatusBarState.SHADE);
+ // HACK: Consider keyguard as visible if showing sim pin security screen
+ KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ boolean keyguardVisible = mState != StatusBarState.SHADE || updateMonitor.isSimPinSecure();
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) {
+ // apply user lockscreen image
+ if (backdropBitmap == null && !mNotificationPanel.hasExternalKeyguardView()) {
backdropBitmap = mKeyguardWallpaper;
}
@@ -2578,9 +2613,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
case MSG_LAUNCH_TRANSITION_TIMEOUT:
onLaunchTransitionTimeout();
break;
- case MSG_UPDATE_NOTIFICATIONS:
- handleUpdateNotifications();
- break;
}
}
}
@@ -3352,6 +3384,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mBatteryController != null) {
mBatteryController.dump(fd, pw, args);
}
+ if (mDockBatteryController != null) {
+ mDockBatteryController.dump(fd, pw, args);
+ }
if (mNextAlarmController != null) {
mNextAlarmController.dump(fd, pw, args);
}
@@ -3421,10 +3456,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
final boolean dismissShade, final Callback callback) {
- if (onlyProvisioned && !isDeviceProvisioned()) return;
-
final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
mContext, intent, mCurrentUserId);
+ startActivityDismissingKeyguard(intent, onlyProvisioned, dismissShade, afterKeyguardGone,
+ callback);
+ }
+
+ public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
+ final boolean dismissShade, final boolean afterKeyguardGone, final Callback callback) {
+ if (onlyProvisioned && !isDeviceProvisioned()) return;
+
final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
Runnable runnable = new Runnable() {
public void run() {
@@ -3521,6 +3562,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Context.WALLPAPER_SERVICE);
mKeyguardWallpaper = wm.getKeyguardBitmap();
updateMediaMetaData(true);
+ } else if (cyanogenmod.content.Intent.ACTION_SCREEN_CAMERA_GESTURE.equals(action)) {
+ boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+ if (!userSetupComplete) {
+ if (DEBUG) Log.d(TAG, String.format(
+ "userSetupComplete = %s, ignoring camera launch gesture.",
+ userSetupComplete));
+ return;
+ }
+
+ onCameraLaunchGestureDetected(StatusBarManager.CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE);
}
}
};
@@ -3644,6 +3696,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mBatteryController != null) {
mBatteryController.setUserId(mCurrentUserId);
}
+ if (mDockBatteryController != null) {
+ mDockBatteryController.setUserId(mCurrentUserId);
+ }
}
private void resetUserSetupObserver() {
@@ -3720,14 +3775,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
int nNotifs = mNotificationData.size();
ArrayList<Pair<String, StatusBarNotification>> notifications = new ArrayList<>(nNotifs);
copyNotifications(notifications, mNotificationData);
- // now remove all the notification views since we'll be re-inflating these with the copied
- // data
- for (int i = 0; i < nNotifs; i++) {
- final NotificationData.Entry entry = mNotificationData.get(i);
- if (entry != null) {
- removeNotificationViews(entry.key, rankingMap);
- }
- }
+ // now remove all the notifications since we'll be re-creating these with the copied data
+ mNotificationData.clear();
if (mCustomTileListenerService != null) {
try {
@@ -3788,6 +3837,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// this will make sure the keyguard is showing
showKeyguard();
}
+
+ // update mLastThemeChangeTime
+ try {
+ mLastThemeChangeTime = mThemeService.getLastThemeChangeTime();
+ } catch (RemoteException e) {
+ /* ignore */
+ }
}
private void removeAllViews(ViewGroup parent) {
@@ -3841,8 +3897,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
/**
* Determines if we need to recreate the status bar due to a theme change. We currently
- * check if the overlay for the status bar, fonts, or icons, or forced update count have
- * changed.
+ * check if the overlay for the status bar, fonts, or icons, or last theme change time is
+ * greater than mLastThemeChangeTime
*
* @param oldTheme
* @param newTheme
@@ -3855,17 +3911,24 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final String overlay = newTheme.getOverlayForStatusBar();
final String icons = newTheme.getIconPackPkgName();
final String fonts = newTheme.getFontPkgName();
+ boolean isNewThemeChange = false;
+ try {
+ isNewThemeChange = mLastThemeChangeTime < mThemeService.getLastThemeChangeTime();
+ } catch (RemoteException e) {
+ /* ignore */
+ }
return oldTheme == null ||
(overlay != null && !overlay.equals(oldTheme.getOverlayForStatusBar()) ||
(fonts != null && !fonts.equals(oldTheme.getFontPkgName())) ||
(icons != null && !icons.equals(oldTheme.getIconPackPkgName())) ||
- newTheme.getLastThemeChangeRequestType() == RequestType.THEME_UPDATED);
+ isNewThemeChange);
}
/**
* Determines if we need to update the navbar resources due to a theme change. We currently
- * check if the overlay for the navbar, or request type is {@link RequestType.THEME_UPDATED}.
+ * check if the overlay for the navbar, or last theme change time is greater than
+ * mLastThemeChangeTime
*
* @param oldTheme
* @param newTheme
@@ -3876,10 +3939,16 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (newTheme == null) return false;
final String overlay = newTheme.getOverlayForNavBar();
+ boolean isNewThemeChange = false;
+ try {
+ isNewThemeChange = mLastThemeChangeTime < mThemeService.getLastThemeChangeTime();
+ } catch (RemoteException e) {
+ /* ignore */
+ }
return oldTheme == null ||
(overlay != null && !overlay.equals(oldTheme.getOverlayForNavBar()) ||
- newTheme.getLastThemeChangeRequestType() == RequestType.THEME_UPDATED);
+ isNewThemeChange);
}
protected void loadDimens() {
@@ -4157,6 +4226,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
if (modeChange || command.equals(COMMAND_BATTERY)) {
dispatchDemoCommandToView(command, args, R.id.battery);
+ dispatchDemoCommandToView(command, args, R.id.dock_battery);
}
if (modeChange || command.equals(COMMAND_STATUS)) {
mIconController.dispatchDemoCommand(command, args);
@@ -4439,7 +4509,6 @@ 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() {
@@ -4510,7 +4579,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void updateStackScrollerState(boolean goingToFullShade) {
if (mStackScroller == null) return;
boolean onKeyguard = mState == StatusBarState.KEYGUARD;
- mStackScroller.setHideSensitive(isLockscreenPublicMode(), goingToFullShade);
+ mStackScroller.setHideSensitive(isLockscreenPublicMode()
+ || (!userAllowsPrivateNotificationsInPublic(mCurrentUserId) && onKeyguard),
+ goingToFullShade);
mStackScroller.setDimmed(onKeyguard, false /* animate */);
mStackScroller.setExpandingEnabled(!onKeyguard);
ActivatableNotificationView activatedChild = mStackScroller.getActivatedChild();
@@ -4798,7 +4869,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mWakeUpTouchLocation = null;
mStackScroller.setAnimationsEnabled(false);
updateVisibleToUser();
- mVisualizerView.setVisible(false);
+ if (mQSTileHost.isEditing()) {
+ mQSTileHost.setEditing(false);
+ }
if (mLaunchCameraOnFinishedGoingToSleep) {
mLaunchCameraOnFinishedGoingToSleep = false;
@@ -4844,6 +4917,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
public void onScreenTurnedOff() {
+ mVisualizerView.setVisible(false);
if (mNotificationPanel.hasExternalKeyguardView()) {
mNotificationPanel.getExternalKeyguardView().onScreenTurnedOff();
}
@@ -5211,7 +5285,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
- vibrateForCameraGesture();
+ if (source != StatusBarManager.CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE) {
+ vibrateForCameraGesture();
+ }
if (!mStatusBarKeyguardViewManager.isShowing()) {
startActivity(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
true /* dismissShade */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index c4ce350..b776a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -42,6 +42,7 @@ import com.android.systemui.qs.tiles.AirplaneModeTile;
import com.android.systemui.qs.tiles.AmbientDisplayTile;
import com.android.systemui.qs.tiles.BatterySaverTile;
import com.android.systemui.qs.tiles.BluetoothTile;
+import com.android.systemui.qs.tiles.CaffeineTile;
import com.android.systemui.qs.tiles.CastTile;
import com.android.systemui.qs.tiles.CellularTile;
import com.android.systemui.qs.tiles.ColorInversionTile;
@@ -363,6 +364,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
else if (tileSpec.equals("live_display")) return new LiveDisplayTile(this);
else if (tileSpec.equals("heads_up")) return new HeadsUpTile(this);
else if (tileSpec.equals("battery_saver")) return new BatterySaverTile(this);
+ else if (tileSpec.equals("caffeine")) return new CaffeineTile(this);
else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(this,tileSpec);
else throw new IllegalArgumentException("Bad tile spec: " + tileSpec);
}
@@ -456,6 +458,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
else if (spec.equals("live_display")) return R.string.live_display_title;
else if (spec.equals("heads_up")) return R.string.quick_settings_heads_up_label;
else if (spec.equals("battery_saver")) return R.string.quick_settings_battery_saver_label;
+ else if (spec.equals("caffeine")) return R.string.quick_settings_caffeine_label;
return 0;
}
@@ -486,6 +489,7 @@ public class QSTileHost implements QSTile.Host, Tunable {
else if (spec.equals("live_display")) return R.drawable.ic_livedisplay_auto;
else if (spec.equals("heads_up")) return R.drawable.ic_qs_heads_up_on;
else if (spec.equals("battery_saver")) return R.drawable.ic_qs_battery_saver_on;
+ else if (spec.equals("caffeine")) return R.drawable.ic_qs_caffeine_on;
return 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 27c8a4d..339d469 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -17,9 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
import android.app.AlarmManager;
-import android.app.IUserSwitchObserver;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.ContentResolver;
@@ -58,6 +56,7 @@ import android.widget.Toast;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.BatteryLevelTextView;
import com.android.systemui.BatteryMeterView;
+import com.android.systemui.DockBatteryMeterView;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.cm.UserContentObserver;
@@ -65,6 +64,7 @@ import com.android.systemui.qs.QSDragPanel;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTile;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.DockBatteryController;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.UserInfoController;
@@ -108,6 +108,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
private ImageView mQsDetailHeaderProgress;
private TextView mEmergencyCallsOnly;
private BatteryLevelTextView mBatteryLevel;
+ private BatteryLevelTextView mDockBatteryLevel;
private TextView mAlarmStatus;
private TextView mWeatherLine1, mWeatherLine2;
private TextView mEditTileDoneText;
@@ -138,7 +139,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
private float mAvatarCollapsedScaleFactor;
private ActivityStarter mActivityStarter;
- private BatteryController mBatteryController;
private NextAlarmController mNextAlarmController;
private WeatherController mWeatherController;
private QSDragPanel mQSPanel;
@@ -193,6 +193,7 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
mEmergencyCallsOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
mBatteryLevel = (BatteryLevelTextView) findViewById(R.id.battery_level_text);
+ mDockBatteryLevel = (BatteryLevelTextView) findViewById(R.id.dock_battery_level_text);
mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
mAlarmStatus.setOnClickListener(this);
mSignalCluster = findViewById(R.id.signal_cluster);
@@ -340,9 +341,26 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
}
public void setBatteryController(BatteryController batteryController) {
- mBatteryController = batteryController;
- ((BatteryMeterView) findViewById(R.id.battery)).setBatteryController(batteryController);
- mBatteryLevel.setBatteryController(batteryController);
+ BatteryMeterView v = ((BatteryMeterView) findViewById(R.id.battery));
+ v.setBatteryStateRegistar(batteryController);
+ v.setBatteryController(batteryController);
+ mBatteryLevel.setBatteryStateRegistar(batteryController);
+ }
+
+ public void setDockBatteryController(DockBatteryController dockBatteryController) {
+ DockBatteryMeterView v = ((DockBatteryMeterView) findViewById(R.id.dock_battery));
+ if (dockBatteryController != null) {
+ v.setBatteryStateRegistar(dockBatteryController);
+ mDockBatteryLevel.setBatteryStateRegistar(dockBatteryController);
+ } else {
+ if (v != null) {
+ removeView(v);
+ }
+ if (mDockBatteryLevel != null) {
+ removeView(mDockBatteryLevel);
+ mDockBatteryLevel = null;
+ }
+ }
}
public void setNextAlarmController(NextAlarmController nextAlarmController) {
@@ -414,6 +432,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
mEmergencyCallsOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly ? VISIBLE : GONE);
mBatteryLevel.setForceShown(mExpanded && mShowBatteryTextExpanded);
mBatteryLevel.setVisibility(View.VISIBLE);
+ if (mDockBatteryLevel != null) {
+ mDockBatteryLevel.setForceShown(mExpanded && mShowBatteryTextExpanded);
+ mDockBatteryLevel.setVisibility(View.VISIBLE);
+ }
}
private void updateSignalClusterDetachment() {
@@ -763,6 +785,9 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
applyAlpha(mDateCollapsed, values.dateCollapsedAlpha);
applyAlpha(mDateExpanded, values.dateExpandedAlpha);
applyAlpha(mBatteryLevel, values.batteryLevelAlpha);
+ if (mDockBatteryLevel != null) {
+ applyAlpha(mDockBatteryLevel, values.batteryLevelAlpha);
+ }
applyAlpha(mSettingsContainer, values.settingsAlpha);
applyAlpha(mWeatherLine1, values.settingsAlpha);
applyAlpha(mWeatherLine2, values.settingsAlpha);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 2347a33..19f2b09 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -114,23 +114,38 @@ public class StatusBarKeyguardViewManager {
mShowing = true;
mStatusBarWindowManager.setKeyguardShowing(true);
mScrimController.abortKeyguardFadingOut();
- reset();
+ reset(false);
}
/**
* Shows the notification keyguard or the bouncer depending on
* {@link KeyguardBouncer#needsFullscreenBouncer()}.
*/
- private void showBouncerOrKeyguard() {
- if (mBouncer.needsFullscreenBouncer()) {
-
- // The keyguard might be showing (already). So we need to hide it.
- mPhoneStatusBar.hideKeyguard();
- mBouncer.show(true /* resetSecuritySelection */);
- } else {
- mPhoneStatusBar.showKeyguard();
- mBouncer.hide(false /* destroyView */);
- mBouncer.prepare();
+ private void showBouncerOrKeyguard(boolean isBackPressed) {
+ switch (mBouncer.needsFullscreenBouncer()) {
+ case KeyguardBouncer.UNLOCK_SEQUENCE_FORCE_BOUNCER:
+ // SIM PIN/PUK
+ // The keyguard might be showing (already). So we need to hide it.
+ mPhoneStatusBar.hideKeyguard();
+ mBouncer.show(true /* resetSecuritySelection */);
+ break;
+ case KeyguardBouncer.UNLOCK_SEQUENCE_BOUNCER_FIRST:
+ // Pattern/PIN/Password with "Directly pass to security view" enabled
+ if (isBackPressed) {
+ mPhoneStatusBar.showKeyguard();
+ mBouncer.hide(false /* destroyView */);
+ mBouncer.prepare();
+ } else {
+ // The keyguard might be showing (already). So we need to hide it.
+ mPhoneStatusBar.hideKeyguard();
+ mBouncer.show(true /* resetSecuritySelection */);
+ }
+ break;
+ case KeyguardBouncer.UNLOCK_SEQUENCE_DEFAULT:
+ mPhoneStatusBar.showKeyguard();
+ mBouncer.hide(false /* destroyView */);
+ mBouncer.prepare();
+ break;
}
}
@@ -157,14 +172,14 @@ public class StatusBarKeyguardViewManager {
/**
* Reset the state of the view.
*/
- public void reset() {
+ public void reset(boolean isBackPressed) {
if (mShowing) {
if (mOccluded) {
mPhoneStatusBar.hideKeyguard();
mPhoneStatusBar.stopWaitingForKeyguardExit();
mBouncer.hide(false /* destroyView */);
} else {
- showBouncerOrKeyguard();
+ showBouncerOrKeyguard(isBackPressed);
}
KeyguardUpdateMonitor.getInstance(mContext).sendKeyguardReset();
updateStates();
@@ -233,7 +248,7 @@ public class StatusBarKeyguardViewManager {
@Override
public void run() {
mStatusBarWindowManager.setKeyguardOccluded(mOccluded);
- reset();
+ reset(false);
}
});
return;
@@ -245,7 +260,7 @@ public class StatusBarKeyguardViewManager {
if (mUnlockFab != null && mUnlockFab.isAttachedToWindow() && !occluded) {
hideUnlockFab();
}
- reset();
+ reset(false);
}
public boolean isOccluded() {
@@ -372,6 +387,7 @@ public class StatusBarKeyguardViewManager {
private void executeAfterKeyguardGoneAction() {
if (mAfterKeyguardGoneAction != null) {
+ dismiss();
mAfterKeyguardGoneAction.onDismiss();
mAfterKeyguardGoneAction = null;
}
@@ -416,7 +432,7 @@ public class StatusBarKeyguardViewManager {
public boolean onBackPressed() {
if (mBouncer.isShowing()) {
mPhoneStatusBar.endAffordanceLaunch();
- reset();
+ reset(true);
return true;
}
return false;
@@ -449,7 +465,8 @@ public class StatusBarKeyguardViewManager {
boolean showing = mShowing;
boolean occluded = mOccluded;
boolean bouncerShowing = mBouncer.isShowing();
- boolean bouncerDismissible = !mBouncer.isFullscreenBouncer();
+ boolean bouncerDismissible = (mBouncer.isFullscreenBouncer() !=
+ KeyguardBouncer.UNLOCK_SEQUENCE_FORCE_BOUNCER);
if ((bouncerDismissible || !showing) != (mLastBouncerDismissible || !mLastShowing)
|| mFirstUpdate) {
@@ -547,6 +564,10 @@ public class StatusBarKeyguardViewManager {
public void animateCollapsePanels(float speedUpFactor) {
mPhoneStatusBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
false /* delayed */, speedUpFactor);
+ if (mStatusBarWindowManager.keyguardExternalViewHasFocus()) {
+ mStatusBarWindowManager.setKeyguardExternalViewFocus(false);
+ dismiss(false);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index b5099e7..9a991f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -35,6 +35,8 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import cyanogenmod.providers.CMSettings;
+import org.cyanogenmod.internal.util.CmLockPatternUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -258,7 +260,8 @@ public class StatusBarWindowManager implements KeyguardMonitor.Callback {
boolean isblur = false;
if (mCurrentState.keyguardShowing && mKeyguardBlurEnabled
&& !mCurrentState.keyguardOccluded
- && !mShowingMedia) {
+ && !mShowingMedia
+ && !isShowingLiveLockScreen()) {
isblur = true;
}
if (mKeyguardBlur != null) {
@@ -394,6 +397,13 @@ public class StatusBarWindowManager implements KeyguardMonitor.Callback {
return mCurrentState.keyguardExternalViewHasFocus;
}
+ private boolean isShowingLiveLockScreen() {
+ CmLockPatternUtils lockPatternUtils = new CmLockPatternUtils(mContext);
+ return (CMSettings.Secure.getInt(mContext.getContentResolver(),
+ CMSettings.Secure.LIVE_LOCK_SCREEN_ENABLED, 0) == 1)
+ && lockPatternUtils.isThirdPartyKeyguardEnabled();
+ }
+
private static class State {
boolean keyguardShowing;
boolean keyguardOccluded;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
index a154544..c59a0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -34,7 +34,7 @@ import java.util.ArrayList;
import cyanogenmod.providers.CMSettings;
-public class BatteryController extends BroadcastReceiver {
+public class BatteryController extends BroadcastReceiver implements BatteryStateRegistar {
private static final String TAG = "BatteryController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -52,6 +52,7 @@ public class BatteryController extends BroadcastReceiver {
private final PowerManager mPowerManager;
private int mLevel;
+ private boolean mPresent;
private boolean mPluggedIn;
private boolean mCharging;
private boolean mCharged;
@@ -85,18 +86,21 @@ public class BatteryController extends BroadcastReceiver {
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("BatteryController state:");
pw.print(" mLevel="); pw.println(mLevel);
+ pw.print(" mPresent="); pw.println(mPresent);
pw.print(" mPluggedIn="); pw.println(mPluggedIn);
pw.print(" mCharging="); pw.println(mCharging);
pw.print(" mCharged="); pw.println(mCharged);
pw.print(" mPowerSave="); pw.println(mPowerSave);
}
+ @Override
public void addStateChangedCallback(BatteryStateChangeCallback cb) {
mChangeCallbacks.add(cb);
- cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ cb.onBatteryLevelChanged(mPresent, mLevel, mPluggedIn, mCharging);
cb.onBatteryStyleChanged(mStyle, mPercentMode);
}
+ @Override
public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
mChangeCallbacks.remove(cb);
}
@@ -107,6 +111,7 @@ public class BatteryController extends BroadcastReceiver {
mLevel = (int)(100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
/ intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
+ mPresent = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
@@ -140,7 +145,7 @@ public class BatteryController extends BroadcastReceiver {
private void fireBatteryLevelChanged() {
final int N = mChangeCallbacks.size();
for (int i = 0; i < N; i++) {
- mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
+ mChangeCallbacks.get(i).onBatteryLevelChanged(mPresent, mLevel, mPluggedIn, mCharging);
}
}
@@ -158,12 +163,6 @@ public class BatteryController extends BroadcastReceiver {
}
}
- public interface BatteryStateChangeCallback {
- void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
- void onPowerSaveChanged();
- void onBatteryStyleChanged(int style, int percentMode);
- }
-
private final class SettingsObserver extends ContentObserver {
private ContentResolver mResolver;
private boolean mRegistered;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateRegistar.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateRegistar.java
new file mode 100644
index 0000000..9fe9bb4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateRegistar.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 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.policy;
+
+public interface BatteryStateRegistar {
+ interface BatteryStateChangeCallback {
+ void onBatteryLevelChanged(boolean present, int level, boolean pluggedIn, boolean charging);
+ void onPowerSaveChanged();
+ void onBatteryStyleChanged(int style, int percentMode);
+ }
+
+ public void addStateChangedCallback(BatteryStateChangeCallback cb);
+ public void removeStateChangedCallback(BatteryStateChangeCallback cb);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
index 4d3a49f..835c8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CastControllerImpl.java
@@ -115,7 +115,7 @@ public class CastControllerImpl implements CastController {
}
if (mDiscovering) {
mMediaRouter.addCallback(ROUTE_TYPE_REMOTE_DISPLAY, mMediaCallback,
- MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+ MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
mCallbackRegistered = true;
} else if (mCallbacks.size() != 0) {
mMediaRouter.addCallback(ROUTE_TYPE_REMOTE_DISPLAY, mMediaCallback,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java
new file mode 100644
index 0000000..3faf7d0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 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.policy;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.Handler;
+import android.provider.Settings;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+import cyanogenmod.providers.CMSettings;
+
+public class DockBatteryController extends BroadcastReceiver implements BatteryStateRegistar {
+
+ private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+
+ private int mLevel;
+ private boolean mPresent;
+ private boolean mPluggedIn;
+ private boolean mCharging;
+ private boolean mCharged;
+ private boolean mPowerSave;
+
+ private int mStyle;
+ private int mPercentMode;
+ private int mUserId;
+ private SettingsObserver mObserver;
+
+ public DockBatteryController(Context context, Handler handler) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ context.registerReceiver(this, filter);
+
+ mObserver = new SettingsObserver(context, handler);
+ mObserver.observe();
+ }
+
+ public void setUserId(int userId) {
+ mUserId = userId;
+ mObserver.observe();
+ }
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("BatteryController state:");
+ pw.print(" mLevel="); pw.println(mLevel);
+ pw.print(" mPresent="); pw.println(mPresent);
+ pw.print(" mPluggedIn="); pw.println(mPluggedIn);
+ pw.print(" mCharging="); pw.println(mCharging);
+ pw.print(" mCharged="); pw.println(mCharged);
+ pw.print(" mPowerSave="); pw.println(mPowerSave);
+ }
+
+ @Override
+ public void addStateChangedCallback(BatteryStateChangeCallback cb) {
+ mChangeCallbacks.add(cb);
+ cb.onBatteryLevelChanged(mPresent, mLevel, mPluggedIn, mCharging);
+ cb.onBatteryStyleChanged(mStyle, mPercentMode);
+ }
+
+ @Override
+ public void removeStateChangedCallback(BatteryStateChangeCallback cb) {
+ mChangeCallbacks.remove(cb);
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+ mLevel = (int)(100f
+ * intent.getIntExtra(BatteryManager.EXTRA_DOCK_LEVEL, 0)
+ / intent.getIntExtra(BatteryManager.EXTRA_DOCK_SCALE, 100));
+ mPresent = intent.getBooleanExtra(BatteryManager.EXTRA_DOCK_PRESENT, false);
+ mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_DOCK_PLUGGED, 0) != 0;
+
+ final int status = intent.getIntExtra(BatteryManager.EXTRA_DOCK_STATUS,
+ BatteryManager.BATTERY_STATUS_UNKNOWN);
+ mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
+ mCharging = mPluggedIn && (mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING);
+
+ fireBatteryLevelChanged();
+ }
+ }
+
+ private void fireBatteryLevelChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onBatteryLevelChanged(mPresent, mLevel, mPresent, mCharging);
+ }
+ }
+
+ private void fireSettingsChanged() {
+ final int N = mChangeCallbacks.size();
+ for (int i = 0; i < N; i++) {
+ mChangeCallbacks.get(i).onBatteryStyleChanged(mStyle, mPercentMode);
+ }
+ }
+
+ private final class SettingsObserver extends ContentObserver {
+ private ContentResolver mResolver;
+ private boolean mRegistered;
+
+ private final Uri STYLE_URI =
+ CMSettings.System.getUriFor(CMSettings.System.STATUS_BAR_BATTERY_STYLE);
+ private final Uri PERCENT_URI =
+ CMSettings.System.getUriFor(CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT);
+
+ public SettingsObserver(Context context, Handler handler) {
+ super(handler);
+ mResolver = context.getContentResolver();
+ }
+
+ public void observe() {
+ if (mRegistered) {
+ mResolver.unregisterContentObserver(this);
+ }
+ mResolver.registerContentObserver(STYLE_URI, false, this, mUserId);
+ mResolver.registerContentObserver(PERCENT_URI, false, this, mUserId);
+ mRegistered = true;
+
+ update();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ update();
+ }
+
+ private void update() {
+ mStyle = CMSettings.System.getIntForUser(mResolver,
+ CMSettings.System.STATUS_BAR_BATTERY_STYLE, 0, mUserId);
+ mPercentMode = CMSettings.System.getIntForUser(mResolver,
+ CMSettings.System.STATUS_BAR_SHOW_BATTERY_PERCENT, 0, mUserId);
+
+ fireSettingsChanged();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
index 2e348e6..52a2825 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java
@@ -29,6 +29,8 @@ import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.text.TextUtils;
import android.util.Log;
@@ -49,6 +51,8 @@ public class FlashlightController {
private static final int DISPATCH_CHANGED = 1;
private static final int DISPATCH_AVAILABILITY_CHANGED = 2;
+ private static boolean mUseWakeLock;
+
private static final String ACTION_TURN_FLASHLIGHT_OFF =
"com.android.systemui.action.TURN_FLASHLIGHT_OFF";
@@ -66,6 +70,8 @@ public class FlashlightController {
private final String mCameraId;
private boolean mTorchAvailable;
+ private WakeLock mWakeLock;
+
private Notification mNotification = null;
private boolean mReceiverRegistered;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -98,6 +104,11 @@ public class FlashlightController {
mCameraId = cameraId;
}
+ mUseWakeLock = mContext.getResources().getBoolean(R.bool.flashlight_use_wakelock);
+
+ PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
if (mCameraId != null) {
ensureHandler();
mCameraManager.registerTorchCallback(mTorchCallback, mHandler);
@@ -109,12 +120,25 @@ public class FlashlightController {
synchronized (this) {
if (mFlashlightEnabled != enabled) {
mFlashlightEnabled = enabled;
+
+ if (mUseWakeLock) {
+ if (enabled) {
+ if (!mWakeLock.isHeld()) mWakeLock.acquire();
+ } else {
+ if (mWakeLock.isHeld()) mWakeLock.release();
+ }
+ }
+
try {
mCameraManager.setTorchMode(mCameraId, enabled);
} catch (CameraAccessException e) {
Log.e(TAG, "Couldn't set torch mode", e);
mFlashlightEnabled = false;
pendingError = true;
+
+ if (mUseWakeLock && mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
}
}
}
@@ -287,6 +311,11 @@ public class FlashlightController {
synchronized (FlashlightController.this) {
changed = mTorchAvailable != available;
mTorchAvailable = available;
+
+ if (mUseWakeLock && !available) {
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ }
}
if (changed) {
if (DEBUG) Log.d(TAG, "dispatchAvailabilityChanged(" + available + ")");
@@ -299,6 +328,11 @@ public class FlashlightController {
synchronized (FlashlightController.this) {
changed = mFlashlightEnabled != enabled;
mFlashlightEnabled = enabled;
+
+ if (mUseWakeLock && !enabled) {
+ if (mWakeLock.isHeld())
+ mWakeLock.release();
+ }
}
if (changed) {
if (DEBUG) Log.d(TAG, "dispatchModeChanged(" + enabled + ")");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5847f42..3d1212b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -457,7 +457,10 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
mReleaseOnExpandFinish = false;
} else {
for (NotificationData.Entry entry : mEntriesToRemoveAfterExpand) {
- removeHeadsUpEntry(entry);
+ if (isHeadsUp(entry.key)) {
+ // Maybe the heads-up was removed already
+ removeHeadsUpEntry(entry);
+ }
}
}
mEntriesToRemoveAfterExpand.clear();
@@ -576,6 +579,9 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
earliestRemovaltime = currentTime + mMinimumDisplayTime;
postTime = Math.max(postTime, currentTime);
removeAutoRemovalCallbacks();
+ if (mEntriesToRemoveAfterExpand.contains(entry)) {
+ mEntriesToRemoveAfterExpand.remove(entry);
+ }
if (!hasFullScreenIntent(entry)) {
long finishTime = postTime + mHeadsUpNotificationDecay;
long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 435787e..a8e977f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -397,10 +397,10 @@ public class MobileSignalController extends SignalController<
mCurrentState.dataConnected = mCurrentState.connected
&& mDataState == TelephonyManager.DATA_CONNECTED;
+ mCurrentState.showSeparateRoaming = false;
if (isCarrierNetworkChangeActive()) {
mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
} else if (isRoaming()) {
- mCurrentState.showSeparateRoaming = false;
if (SystemProperties.getBoolean("ro.config.always_show_roaming", false)) {
mCurrentState.showSeparateRoaming = true;
} else {
@@ -476,6 +476,7 @@ public class MobileSignalController extends SignalController<
+ " dataState=" + state.getDataRegState());
}
mServiceState = state;
+ mDataNetType = state.getDataNetworkType();
updateTelephony();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 4ec8b43..2f04b42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -211,8 +211,6 @@ public class NotificationStackScrollLayout extends ViewGroup
private boolean mDisallowScrollingInThisMotion;
private long mGoToFullShadeDelay;
- private final PerformanceManager mPerf;
-
private ViewTreeObserver.OnPreDrawListener mChildrenUpdater
= new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -259,8 +257,6 @@ public class NotificationStackScrollLayout extends ViewGroup
mExpandHelper.setEventSource(this);
mExpandHelper.setScrollAdapter(this);
- mPerf = PerformanceManager.getInstance(context);
-
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
mSwipeHelper.setLongPressListener(mLongPressListener);
initView(context);
@@ -847,10 +843,6 @@ public class NotificationStackScrollLayout extends ViewGroup
horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
}
- if (expandWantsIt && mIsBeingDragged) {
- mPerf.cpuBoost(200 * 1000);
- }
-
return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index a2b062c..0ae34bf 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -155,7 +155,7 @@ public class DemoModeFragment extends PreferenceFragment implements OnPreference
getContext().sendBroadcast(intent);
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK);
- intent.putExtra("hhmm", "0600");
+ intent.putExtra("hhmm", "1230");
getContext().sendBroadcast(intent);
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 3ed18c9..27c6601 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -130,6 +130,7 @@ public class VolumeDialog {
private boolean mPendingStateChanged;
private boolean mPendingRecheckAll;
private long mCollapseTime;
+ private int mLastActiveStream;
public VolumeDialog(Context context, int windowType, VolumeDialogController controller,
ZenModeController zenModeController, Callback callback) {
@@ -194,7 +195,7 @@ public class VolumeDialog {
});
addRow(AudioManager.STREAM_RING,
- R.drawable.ic_ringer_audible, R.drawable.ic_volume_ringer_mute, true);
+ R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true);
addRow(AudioManager.STREAM_MUSIC,
R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true);
addRow(AudioManager.STREAM_ALARM,
@@ -275,10 +276,14 @@ public class VolumeDialog {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
- final boolean moved = oldLeft != left || oldTop != top;
+ final boolean moved = mLastActiveStream != mActiveStream ||
+ oldLeft != left || oldTop != top;
if (D.BUG) Log.d(TAG, "onLayoutChange moved=" + moved
+ " old=" + new Rect(oldLeft, oldTop, oldRight, oldBottom).toShortString()
- + " new=" + new Rect(left,top,right,bottom).toShortString());
+ + "," + mLastActiveStream
+ + " new=" + new Rect(left,top,right,bottom).toShortString()
+ + "," + mActiveStream);
+ mLastActiveStream = mActiveStream;
if (moved) {
for (int i = 0; i < mDialogContentView.getChildCount(); i++) {
final View c = mDialogContentView.getChildAt(i);
@@ -652,9 +657,9 @@ public class VolumeDialog {
removeRow(notificationRow);
}
} else if (!mState.linkedNotification) {
- // TODO get icon for mute state
addRow(AudioManager.STREAM_NOTIFICATION,
- R.drawable.ic_notification_audible, R.drawable.ic_notification_audible, true);
+ R.drawable.ic_volume_notification, R.drawable.ic_volume_notification_mute,
+ true);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 024fb8c..9494e27 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -29,6 +29,7 @@ import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.IVolumeController;
+import android.media.ToneGenerator;
import android.media.VolumePolicy;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession.Token;
@@ -54,6 +55,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
+import cyanogenmod.providers.CMSettings;
+
/**
* Source of truth for all state / events related to the volume dialog. No presentation.
*
@@ -67,6 +70,9 @@ public class VolumeDialogController {
private static final int DYNAMIC_STREAM_START_INDEX = 100;
private static final int VIBRATE_HINT_DURATION = 50;
+ private static final int FREE_DELAY = 10000;
+ private static final int BEEP_DURATION = 150;
+
private static final int[] STREAMS = {
AudioSystem.STREAM_ALARM,
AudioSystem.STREAM_BLUETOOTH_SCO,
@@ -102,10 +108,13 @@ public class VolumeDialogController {
private VolumePolicy mVolumePolicy;
private boolean mShowDndTile = true;
+ private ToneGenerator mToneGenerators[];
+
public VolumeDialogController(Context context, ComponentName component) {
mContext = context.getApplicationContext();
Events.writeEvent(mContext, Events.EVENT_COLLECTION_STARTED);
mComponent = component;
+ mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
mWorkerThread = new HandlerThread(VolumeDialogController.class.getSimpleName());
mWorkerThread.start();
mWorker = new W(mWorkerThread.getLooper());
@@ -289,6 +298,7 @@ public class VolumeDialogController {
final boolean fromKey = (flags & AudioManager.FLAG_FROM_KEY) != 0;
final boolean showVibrateHint = (flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0;
final boolean showSilentHint = (flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0;
+ final boolean playSound = (flags & AudioManager.FLAG_PLAY_SOUND) != 0;
boolean changed = false;
if (showUI) {
changed |= updateActiveStreamW(stream);
@@ -308,6 +318,19 @@ public class VolumeDialogController {
if (showSilentHint) {
mCallbacks.onShowSilentHint();
}
+ if (playSound) {
+ if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0) {
+ mWorker.removeMessages(W.PLAY_SOUND);
+ mWorker.sendMessageDelayed(mWorker.obtainMessage(W.PLAY_SOUND, stream, flags),
+ AudioSystem.PLAY_SOUND_DELAY);
+ }
+
+ if ((flags & AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE) != 0) {
+ mWorker.removeMessages(W.PLAY_SOUND);
+ onStopSoundsW();
+ }
+
+ }
if (changed && fromKey) {
Events.writeEvent(mContext, Events.EVENT_KEY, stream, lastAudibleStreamVolume);
}
@@ -566,6 +589,9 @@ public class VolumeDialogController {
private static final int NOTIFY_VISIBLE = 12;
private static final int USER_ACTIVITY = 13;
private static final int SHOW_SAFETY_WARNING = 14;
+ private static final int PLAY_SOUND = 15;
+ private static final int STOP_SOUNDS = 16;
+ private static final int FREE_RESOURCES = 17;
W(Looper looper) {
super(looper);
@@ -588,6 +614,9 @@ public class VolumeDialogController {
case NOTIFY_VISIBLE: onNotifyVisibleW(msg.arg1 != 0); break;
case USER_ACTIVITY: onUserActivityW(); break;
case SHOW_SAFETY_WARNING: onShowSafetyWarningW(msg.arg1); break;
+ case PLAY_SOUND: onPlaySoundW(msg.arg1, msg.arg2); break;
+ case STOP_SOUNDS: onStopSoundsW(); break;
+ case FREE_RESOURCES: onFreeResourcesW(); break;
}
}
}
@@ -717,6 +746,66 @@ public class VolumeDialogController {
}
+ protected void onPlaySoundW(int streamType, int flags) {
+
+ // If preference is no sound - just exit here
+ if (CMSettings.System.getInt(mContext.getContentResolver(),
+ CMSettings.System.VOLUME_ADJUST_SOUNDS_ENABLED, 1) == 0) {
+ return;
+ }
+
+ if (mWorker.hasMessages(W.STOP_SOUNDS)) {
+ mWorker.removeMessages(W.STOP_SOUNDS);
+ // Force stop right now
+ onStopSoundsW();
+ }
+
+ ToneGenerator toneGen = getOrCreateToneGeneratorW(streamType);
+ if (toneGen != null) {
+ toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+ mWorker.sendMessageDelayed(mWorker.obtainMessage(W.STOP_SOUNDS), BEEP_DURATION);
+ }
+
+ mWorker.removeMessages(W.FREE_RESOURCES);
+ mWorker.sendMessageDelayed(mWorker.obtainMessage(W.FREE_RESOURCES), FREE_DELAY);
+ }
+
+ protected void onStopSoundsW() {
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int i = numStreamTypes - 1; i >= 0; i--) {
+ ToneGenerator toneGen = mToneGenerators[i];
+ if (toneGen != null) {
+ toneGen.stopTone();
+ }
+ }
+ }
+
+ private ToneGenerator getOrCreateToneGeneratorW(int streamType) {
+ if (mToneGenerators[streamType] == null) {
+ try {
+ mToneGenerators[streamType] = new ToneGenerator(streamType,
+ ToneGenerator.MAX_VOLUME);
+ } catch (RuntimeException e) {
+ if (false) {
+ Log.d(TAG, "ToneGenerator constructor failed with "
+ + "RuntimeException: " + e);
+ }
+ }
+ }
+ return mToneGenerators[streamType];
+ }
+
+ protected void onFreeResourcesW() {
+ synchronized (this) {
+ for (int i = mToneGenerators.length - 1; i >= 0; i--) {
+ if (mToneGenerators[i] != null) {
+ mToneGenerators[i].release();
+ }
+ mToneGenerators[i] = null;
+ }
+ }
+ }
+
private final class SettingObserver extends ContentObserver {
private final Uri SERVICE_URI = Settings.Secure.getUriFor(
Settings.Secure.VOLUME_CONTROLLER_SERVICE_COMPONENT);
@@ -885,6 +974,13 @@ public class VolumeDialogController {
@Override
public void onRemoteVolumeChanged(Token token, int flags) {
+ // If an inactive session changed the remoteVolume, bail
+ // since we don't have any active streams to update
+ if (!mRemoteStreams.containsKey(token)) {
+ Log.i(TAG, "onRemoteVolumeChanged called on inactive" +
+ "stream. Ignoring");
+ return;
+ }
final int stream = mRemoteStreams.get(token);
final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
boolean changed = updateActiveStreamW(stream);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index 07ec843..ddf623a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -70,9 +70,7 @@ public class ZenModePanel extends LinearLayout {
private static final int SECONDS_MS = 1000;
private static final int MINUTES_MS = 60 * SECONDS_MS;
- private static final int[] MINUTE_BUCKETS = DEBUG
- ? new int[] { 0, 1, 2, 5, 15, 30, 45, 60, 120, 180, 240, 480 }
- : ZenModeConfig.MINUTE_BUCKETS;
+ private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
private static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
private static final int MAX_BUCKET_MINUTES = MINUTE_BUCKETS[MINUTE_BUCKETS.length - 1];
private static final int DEFAULT_BUCKET_INDEX = Arrays.binarySearch(MINUTE_BUCKETS, 60);
@@ -421,8 +419,13 @@ public class ZenModePanel extends LinearLayout {
mZenIntroductionCustomize.setVisibility(zenImportant ? VISIBLE : GONE);
}
final String warning = computeAlarmWarningText(zenNone);
- mZenAlarmWarning.setVisibility(warning != null ? VISIBLE : GONE);
+ final int oldVis = mZenAlarmWarning.getVisibility();
+ final int newVis = warning != null ? VISIBLE : GONE;
+ mZenAlarmWarning.setVisibility(newVis);
mZenAlarmWarning.setText(warning);
+ if (newVis != oldVis) {
+ requestLayout();
+ }
}
private String computeAlarmWarningText(boolean zenNone) {
@@ -603,13 +606,6 @@ public class ZenModePanel extends LinearLayout {
if (DEBUG) Log.d(mTag, "bind i=" + mZenConditions.indexOfChild(row) + " first=" + first
+ " condition=" + conditionId);
tag.rb.setEnabled(enabled);
- final boolean checked = (mSessionExitCondition != null
- || mAttachedZen != Global.ZEN_MODE_OFF)
- && (sameConditionId(mSessionExitCondition, tag.condition));
- if (checked != tag.rb.isChecked()) {
- if (DEBUG) Log.d(mTag, "bind checked=" + checked + " condition=" + conditionId);
- tag.rb.setChecked(checked);
- }
tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {