Merge "Switch to libsigchain.a" into lmp-mr1-dev
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 820bf78..54c4505 100644
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -329,7 +329,6 @@
String fullDateText = DateUtils.formatDateTime(mContext, millis, flags);
mAnimator.announceForAccessibility(fullDateText);
}
- updatePickers();
}
private void setCurrentView(final int viewIndex) {
@@ -369,11 +368,14 @@
@Override
public void init(int year, int monthOfYear, int dayOfMonth,
DatePicker.OnDateChangedListener callBack) {
- mDateChangedListener = callBack;
mCurrentDate.set(Calendar.YEAR, year);
mCurrentDate.set(Calendar.MONTH, monthOfYear);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
- updateDisplay(false);
+
+ onDateChanged(false);
+
+ // Set the listener last so that we don't call it.
+ mDateChangedListener = callBack;
}
@Override
@@ -381,10 +383,29 @@
mCurrentDate.set(Calendar.YEAR, year);
mCurrentDate.set(Calendar.MONTH, month);
mCurrentDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+
+ onDateChanged(false);
+ }
+
+ private void onDateChanged(boolean fromUser) {
if (mDateChangedListener != null) {
- mDateChangedListener.onDateChanged(mDelegator, year, month, dayOfMonth);
+ final int year = mCurrentDate.get(Calendar.YEAR);
+ final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
+ final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
+ mDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
}
- updateDisplay(false);
+
+ for (OnDateChangedListener listener : mListeners) {
+ listener.onDateChanged();
+ }
+
+ mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
+
+ updateDisplay(fromUser);
+
+ if (fromUser) {
+ tryVibrate();
+ }
}
@Override
@@ -411,8 +432,7 @@
}
if (mCurrentDate.before(mTempDate)) {
mCurrentDate.setTimeInMillis(minDate);
- updatePickers();
- updateDisplay(false);
+ onDateChanged(false);
}
mMinDate.setTimeInMillis(minDate);
mDayPickerView.setMinDate(minDate);
@@ -433,8 +453,7 @@
}
if (mCurrentDate.after(mTempDate)) {
mCurrentDate.setTimeInMillis(maxDate);
- updatePickers();
- updateDisplay(false);
+ onDateChanged(false);
}
mMaxDate.setTimeInMillis(maxDate);
mDayPickerView.setMaxDate(maxDate);
@@ -573,9 +592,10 @@
public void onYearSelected(int year) {
adjustDayInMonthIfNeeded(mCurrentDate.get(Calendar.MONTH), year);
mCurrentDate.set(Calendar.YEAR, year);
- updatePickers();
+ onDateChanged(true);
+
+ // Auto-advance to month and day view.
setCurrentView(MONTH_AND_DAY_VIEW);
- updateDisplay(true);
}
// If the newly selected month / year does not contain the currently selected day number,
@@ -612,14 +632,6 @@
}
}
- private void updatePickers() {
- for (OnDateChangedListener listener : mListeners) {
- listener.onDateChanged();
- }
-
- mDayPickerView.setDate(getSelectedDay().getTimeInMillis());
- }
-
@Override
public void registerOnDateChangedListener(OnDateChangedListener listener) {
mListeners.add(listener);
@@ -653,11 +665,7 @@
@Override
public void onDaySelected(DayPickerView view, Calendar day) {
mCurrentDate.setTimeInMillis(day.getTimeInMillis());
-
- updatePickers();
- updateDisplay(true);
-
- tryVibrate();
+ onDateChanged(true);
}
};
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index bdb0324..e1e1ffed 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -56,6 +56,7 @@
<dimen name="action_bar_overflow_padding_start_material">6dp</dimen>
<!-- Padding to add to the end of the overflow action button. -->
<dimen name="action_bar_overflow_padding_end_material">10dp</dimen>
+ <dimen name="action_bar_elevation_material">4dp</dimen>
<dimen name="action_button_min_width_overflow_material">36dp</dimen>
<dimen name="action_button_min_width_material">48dp</dimen>
@@ -87,9 +88,9 @@
<dimen name="floating_window_margin_bottom">32dp</dimen>
<!-- Elevation when button is pressed -->
- <dimen name="button_elevation_material">4dp</dimen>
+ <dimen name="button_elevation_material">2dp</dimen>
<!-- Z translation to apply when button is pressed -->
- <dimen name="button_pressed_z_material">2dp</dimen>
+ <dimen name="button_pressed_z_material">4dp</dimen>
<!-- Default insets (outer padding) around buttons -->
<dimen name="button_inset_vertical_material">6dp</dimen>
<dimen name="button_inset_horizontal_material">@dimen/control_inset_material</dimen>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index d3d6d70..6220a1b 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -917,7 +917,7 @@
<item name="gravity">center_vertical</item>
<item name="contentInsetStart">@dimen/action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/action_bar_content_inset_material</item>
- <item name="elevation">8dp</item>
+ <item name="elevation">@dimen/action_bar_elevation_material</item>
<item name="popupTheme">?attr/actionBarPopupTheme</item>
</style>
diff --git a/docs/html/distribute/googleplay/wear.jd b/docs/html/distribute/googleplay/wear.jd
index b6fc6b6..c0a0017 100644
--- a/docs/html/distribute/googleplay/wear.jd
+++ b/docs/html/distribute/googleplay/wear.jd
@@ -210,7 +210,7 @@
and the opt-in checkbox.
</li>
- <li>Click the checkbox next to <em>Distribute your app to Android Wear</em>.
+ <li>Click the checkbox next to <em>Distribute your app on Android Wear</em>.
</li>
<li>Click <strong>Save</strong> to save your Pricing and Distribution changes.
diff --git a/docs/html/tools/studio/index.jd b/docs/html/tools/studio/index.jd
index d1888fa..258fedb 100644
--- a/docs/html/tools/studio/index.jd
+++ b/docs/html/tools/studio/index.jd
@@ -114,8 +114,9 @@
<p> <img src="{@docRoot}images/tools/studio-project-layout.png" alt="" /></p>
<p> <class="img-caption"><strong>Figure 3.</strong> Android Studio project structure</p>
-<p>For more information, see <a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project +Organization"class="external-link">IntelliJ project organization</a> and
-<a href="{@docRoot}tools/workflow/project/index.html">Managing Projects</a>.</p>
+<p>For more information, see
+<a href="http://confluence.jetbrains.com/display/IntelliJIDEA/Project+Organization"class="external-link">IntelliJ project organization</a> and
+<a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.</p>
<h3>Creating new files</h3>
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index cb6a1de..9437c1b 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -122,7 +122,7 @@
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/debugging/index.html"><span class="en">Debugging</span></a></div>
<ul>
- <li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects.html"><span class="en">From Eclipse with ADT</span></a></li>
+ <li><a href="<?cs var:toroot ?>tools/debugging/debugging-studio.html"><span class="en">From Android Studio</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-projects-cmdline.html"><span class="en">From Other IDEs</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/ddms.html"><span class="en">Using DDMS</span></a></li>
<li><a href="<?cs var:toroot ?>tools/debugging/debugging-log.html"><span class="en">Reading and Writing Logs</span></a></li>
@@ -145,14 +145,6 @@
</ul>
</li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>tools/support-library/index.html"><span
-class="en">Support Library</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot ?>tools/support-library/features.html">Features</a></li>
- <li><a href="<?cs var:toroot ?>tools/support-library/setup.html">Setup</a></li>
- </ul>
- </li>
<li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>tools/help/index.html"><span
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 1e360d3..3fe408a 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -714,10 +714,17 @@
mDrawableFutures = new SparseArray<ConstantStateFuture>(mNumChildren);
}
+ // Create futures for drawables with constant states. If a
+ // drawable doesn't have a constant state, then we can't clone
+ // it and we'll have to reference the original.
final int N = mNumChildren;
for (int i = 0; i < N; i++) {
if (origDr[i] != null) {
- mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+ if (origDr[i].getConstantState() != null) {
+ mDrawableFutures.put(i, new ConstantStateFuture(origDr[i]));
+ } else {
+ mDrawables[i] = origDr[i];
+ }
}
}
} else {
diff --git a/include/androidfw/AttributeFinder.h b/include/androidfw/AttributeFinder.h
index a0ffeb3..acf7056 100644
--- a/include/androidfw/AttributeFinder.h
+++ b/include/androidfw/AttributeFinder.h
@@ -64,6 +64,7 @@
void jumpToClosestAttribute(uint32_t packageId);
void markCurrentPackageId(uint32_t packageId);
+ bool mFirstTime;
Iterator mBegin;
Iterator mEnd;
Iterator mCurrent;
@@ -81,7 +82,8 @@
template <typename Derived, typename Iterator> inline
BackTrackingAttributeFinder<Derived, Iterator>::BackTrackingAttributeFinder(const Iterator& begin, const Iterator& end)
- : mBegin(begin)
+ : mFirstTime(true)
+ , mBegin(begin)
, mEnd(end)
, mCurrent(begin)
, mLargest(begin)
@@ -145,8 +147,11 @@
return mEnd;
}
- if (mCurrentAttr == 0) {
- // One-time initialization.
+ if (mFirstTime) {
+ // One-time initialization. We do this here instead of the constructor
+ // because the derived class we access in getAttribute() may not be
+ // fully constructed.
+ mFirstTime = false;
mCurrentAttr = static_cast<const Derived*>(this)->getAttribute(mBegin);
mLastPackageId = getPackage(mCurrentAttr);
markCurrentPackageId(mLastPackageId);
diff --git a/libs/androidfw/tests/AttributeFinder_test.cpp b/libs/androidfw/tests/AttributeFinder_test.cpp
index 664709c..5054624 100644
--- a/libs/androidfw/tests/AttributeFinder_test.cpp
+++ b/libs/androidfw/tests/AttributeFinder_test.cpp
@@ -50,6 +50,10 @@
0x01010002, 0x01010004, 0x7f010001
};
+static const uint32_t singlePackageAttributes[] = {
+ 0x7f010007, 0x7f01000a, 0x7f01000d, 0x00000000
+};
+
TEST(AttributeFinderTest, IteratesSequentially) {
const int end = sizeof(sortedAttributes) / sizeof(*sortedAttributes);
MockAttributeFinder finder(sortedAttributes, end);
@@ -109,3 +113,16 @@
EXPECT_EQ(1, finder.find(0x02010010));
EXPECT_EQ(6, finder.find(0x7f010001));
}
+
+TEST(AttributeFinderTest, FindAttributesInSinglePackageAttributeList) {
+ const int end = sizeof(singlePackageAttributes) / sizeof(*singlePackageAttributes);
+ MockAttributeFinder finder(singlePackageAttributes, end);
+
+ EXPECT_EQ(end, finder.find(0x010100f4));
+ EXPECT_EQ(end, finder.find(0x010100f5));
+ EXPECT_EQ(end, finder.find(0x010100f6));
+ EXPECT_EQ(end, finder.find(0x010100f7));
+ EXPECT_EQ(end, finder.find(0x010100f8));
+ EXPECT_EQ(end, finder.find(0x010100fa));
+ EXPECT_EQ(0, finder.find(0x7f010007));
+}
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 21c869b..b2dba00 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -325,6 +325,7 @@
// At the end, update the real index and vertex buffer size.
shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
shadowVertexBuffer.updateIndexCount(indexBufferIndex);
+ shadowVertexBuffer.computeBounds<AlphaVertex>();
ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Ambient Vertex Buffer");
ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Ambient Index Buffer");
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index cb8a8d1..7a43a2a 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -77,18 +77,14 @@
OpenGLRenderer& mRenderer;
const int mReplayFlags;
- // Allocator with the lifetime of a single frame.
- // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator
+ // Allocator with the lifetime of a single frame. replay uses an Allocator owned by the struct,
+ // while defer shares the DeferredDisplayList's Allocator
+ // TODO: move this allocator to be owned by object with clear frame lifecycle
LinearAllocator * const mAllocator;
SkPath* allocPathForFrame() {
- mTempPaths.push_back();
- return &mTempPaths.back();
+ return mRenderer.allocPathForFrame();
}
-
-private:
- // Paths kept alive for the duration of the frame
- std::vector<SkPath> mTempPaths;
};
class DeferStateStruct : public PlaybackStateStruct {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 075f2c5..96257e4 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -311,6 +311,11 @@
renderOverdraw();
endTiling();
+ for (size_t i = 0; i < mTempPaths.size(); i++) {
+ delete mTempPaths[i];
+ }
+ mTempPaths.clear();
+
// When finish() is invoked on FBO 0 we've reached the end
// of the current frame
if (getTargetFbo() == 0) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index e1c3d10..5eee2e2 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -342,6 +342,12 @@
uint8_t getAmbientShadowAlpha() const { return mAmbientShadowAlpha; }
uint8_t getSpotShadowAlpha() const { return mSpotShadowAlpha; }
+ SkPath* allocPathForFrame() {
+ SkPath* path = new SkPath();
+ mTempPaths.push_back(path);
+ return path;
+ }
+
protected:
/**
* Perform the setup specific to a frame. This method does not
@@ -1014,6 +1020,9 @@
uint8_t mAmbientShadowAlpha;
uint8_t mSpotShadowAlpha;
+ // Paths kept alive for the duration of the frame
+ std::vector<SkPath*> mTempPaths;
+
friend class Layer;
friend class TextSetupFunctor;
friend class DrawBitmapOp;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 89aebe8..63a0cf6 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3421,7 +3421,7 @@
return false;
}
- // Windows are ordered in z order so start from the botton and find
+ // Windows are ordered in z order so start from the bottom and find
// the window of interest. After that all windows that cover it should
// be subtracted from the resulting region. Note that for accessibility
// we are returning only interactive windows.
@@ -3439,7 +3439,8 @@
windowInteractiveRegion = outRegion;
continue;
}
- } else {
+ } else if (currentWindow.getType()
+ != AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY) {
Rect currentWindowBounds = mTempRect;
currentWindow.getBoundsInScreen(currentWindowBounds);
if (windowInteractiveRegion.op(currentWindowBounds, Region.Op.DIFFERENCE)) {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 3117a17..ca376fd 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -535,15 +535,14 @@
Log.d(TAG, "Creating new ProfileServiceConnections object for"
+ " profile: " + bluetoothProfile);
}
- Intent intent = null;
- if (bluetoothProfile == BluetoothProfile.HEADSET) {
- intent = new Intent(IBluetoothHeadset.class.getName());
- } else {
- return false;
- }
+
+ if (bluetoothProfile != BluetoothProfile.HEADSET) return false;
+
+ Intent intent = new Intent(IBluetoothHeadset.class.getName());
psc = new ProfileServiceConnections(intent);
+ if (!psc.bindService()) return false;
+
mProfileServices.put(new Integer(bluetoothProfile), psc);
- psc.bindService();
}
}
@@ -571,7 +570,11 @@
synchronized (mProfileServices) {
for (Integer i : mProfileServices.keySet()) {
ProfileServiceConnections psc = mProfileServices.get(i);
- mContext.unbindService(psc);
+ try {
+ mContext.unbindService(psc);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Unable to unbind service with intent: " + psc.mIntent, e);
+ }
psc.removeAllProxies();
}
mProfileServices.clear();
@@ -596,16 +599,16 @@
mIntent = intent;
}
- private void bindService() {
- if (mIntent != null && mService == null) {
- if (!doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
- Log.w(TAG, "Unable to bind with intent: " + mIntent
- + ". Triggering retry.");
- }
+ private boolean bindService() {
+ if (mIntent != null && mService == null &&
+ doBind(mIntent, this, 0, UserHandle.CURRENT_OR_SELF)) {
Message msg = mHandler.obtainMessage(MESSAGE_BIND_PROFILE_SERVICE);
msg.obj = this;
mHandler.sendMessageDelayed(msg, TIMEOUT_BIND_MS);
+ return true;
}
+ Log.w(TAG, "Unable to bind with intent: " + mIntent);
+ return false;
}
private void addProxy(IBluetoothProfileServiceConnection proxy) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1227148..82afeed 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1841,7 +1841,9 @@
proc = mPendingPssProcesses.remove(0);
procState = proc.pssProcState;
lastPssTime = proc.lastPssTime;
- if (proc.thread != null && procState == proc.setProcState) {
+ if (proc.thread != null && procState == proc.setProcState
+ && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
+ < SystemClock.uptimeMillis()) {
pid = proc.pid;
} else {
proc = null;
@@ -17746,7 +17748,8 @@
+ (app.nextPssTime-now) + ": " + app);
} else {
if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
- && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
+ && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
+ mTestPssMode)))) {
requestPssLocked(app, app.setProcState);
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
mTestPssMode, isSleeping(), now);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index aa86786..ae4af5f 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -238,7 +238,7 @@
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
// Increase the high min-free levels for cached processes for 64-bit
mOomMinFreeHigh[4] = (mOomMinFreeHigh[4]*3)/2;
- mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/8;
+ mOomMinFreeHigh[5] = (mOomMinFreeHigh[5]*7)/4;
}
for (int i=0; i<mOomAdj.length; i++) {
@@ -411,7 +411,10 @@
sb.append(ramKb);
}
- // The minimum amount of time after a state change it is safe ro collect PSS.
+ // How long after a state change that it is safe to collect PSS without it being dirty.
+ public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000;
+
+ // The minimum time interval after a state change it is safe to collect PSS.
public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000;
// The maximum amount of time we want to go between PSS collections.
@@ -441,6 +444,9 @@
// The amount of time until PSS when a cached process stays in the same state.
private static final int PSS_SAME_CACHED_INTERVAL = 30*60*1000;
+ // The minimum time interval after a state change it is safe to collect PSS.
+ public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000;
+
// The amount of time during testing until PSS when a process first becomes top.
private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000;
@@ -548,6 +554,10 @@
return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2];
}
+ public static long minTimeFromStateChange(boolean test) {
+ return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE;
+ }
+
public static long computeNextPssTime(int procState, boolean first, boolean test,
boolean sleeping, long now) {
final long[] table = test
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bb99916..650f0e2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1028,6 +1028,7 @@
? mListenersDisablingEffects.valueAt(0).component : null;
if (Objects.equals(suppressor, mEffectsSuppressor)) return;
mEffectsSuppressor = suppressor;
+ mZenModeHelper.setEffectsSuppressed(suppressor != null);
getContext().sendBroadcast(new Intent(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 012e22f..31d5cd7 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -17,6 +17,7 @@
package com.android.server.notification;
import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
import android.app.AppOpsManager;
@@ -77,6 +78,7 @@
private ZenModeConfig mConfig;
private AudioManagerInternal mAudioManager;
private int mPreviousRingerMode = -1;
+ private boolean mEffectsSuppressed;
public ZenModeHelper(Context context, Looper looper) {
mContext = context;
@@ -153,6 +155,12 @@
}
}
+ public void setEffectsSuppressed(boolean effectsSuppressed) {
+ if (mEffectsSuppressed == effectsSuppressed) return;
+ mEffectsSuppressed = effectsSuppressed;
+ applyRestrictions();
+ }
+
public boolean shouldIntercept(NotificationRecord record) {
if (isSystem(record)) {
return false;
@@ -225,29 +233,35 @@
ZenLog.traceUpdateZenMode(oldMode, newMode);
}
mZenMode = newMode;
+ applyRestrictions();
+ onZenUpdated(oldMode, newMode);
+ dispatchOnZenModeChanged();
+ }
+
+ private void applyRestrictions() {
final boolean zen = mZenMode != Global.ZEN_MODE_OFF;
- final String[] exceptionPackages = null; // none (for now)
+
+ // notification restrictions
+ final boolean muteNotifications = mEffectsSuppressed;
+ applyRestrictions(muteNotifications, USAGE_NOTIFICATION);
// call restrictions
- final boolean muteCalls = zen && !mConfig.allowCalls;
- mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_NOTIFICATION_RINGTONE,
- muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
- mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_NOTIFICATION_RINGTONE,
- muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
+ final boolean muteCalls = zen && !mConfig.allowCalls || mEffectsSuppressed;
+ applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
// alarm restrictions
final boolean muteAlarms = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
- mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, USAGE_ALARM,
- muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
- mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, USAGE_ALARM,
- muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
- exceptionPackages);
+ applyRestrictions(muteAlarms, USAGE_ALARM);
+ }
- onZenUpdated(oldMode, newMode);
- dispatchOnZenModeChanged();
+ private void applyRestrictions(boolean mute, int usage) {
+ final String[] exceptionPackages = null; // none (for now)
+ mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, usage,
+ mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+ exceptionPackages);
+ mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, usage,
+ mute ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+ exceptionPackages);
}
public void dump(PrintWriter pw, String prefix) {
@@ -257,6 +271,7 @@
pw.print(prefix); pw.print("mDefaultConfig="); pw.println(mDefaultConfig);
pw.print(prefix); pw.print("mPreviousRingerMode="); pw.println(mPreviousRingerMode);
pw.print(prefix); pw.print("mDefaultPhoneApp="); pw.println(mDefaultPhoneApp);
+ pw.print(prefix); pw.print("mEffectsSuppressed="); pw.println(mEffectsSuppressed);
}
public void readXml(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index c1420a8..37d811f 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -68,9 +68,18 @@
break;
case KEYGUARD_POLICY_CHANGED:
- mPolicy.enableKeyguard(true);
- // lazily evaluate this next time we're asked to disable keyguard
mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN;
+ if (mKeyguardTokenWatcher.isAcquired()) {
+ // If we are currently disabled we need to know if the keyguard
+ // should be re-enabled, so determine the allow state immediately.
+ mKeyguardTokenWatcher.updateAllowState();
+ if (mAllowDisableKeyguard != ALLOW_DISABLE_YES) {
+ mPolicy.enableKeyguard(true);
+ }
+ } else {
+ // lazily evaluate this next time we're asked to disable keyguard
+ mPolicy.enableKeyguard(true);
+ }
break;
}
}
@@ -81,24 +90,28 @@
super(handler, TAG);
}
- @Override
- public void acquired() {
+ public void updateAllowState() {
// We fail safe and prevent disabling keyguard in the unlikely event this gets
// called before DevicePolicyManagerService has started.
- if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
- DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (dpm != null) {
- try {
- mAllowDisableKeyguard = dpm.getPasswordQuality(null,
- ActivityManagerNative.getDefault().getCurrentUser().id)
- == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
- ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
- } catch (RemoteException re) {
- // Nothing much we can do
- }
+ DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+ if (dpm != null) {
+ try {
+ mAllowDisableKeyguard = dpm.getPasswordQuality(null,
+ ActivityManagerNative.getDefault().getCurrentUser().id)
+ == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ?
+ ALLOW_DISABLE_YES : ALLOW_DISABLE_NO;
+ } catch (RemoteException re) {
+ // Nothing much we can do
}
}
+ }
+
+ @Override
+ public void acquired() {
+ if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) {
+ updateAllowState();
+ }
if (mAllowDisableKeyguard == ALLOW_DISABLE_YES) {
mPolicy.enableKeyguard(false);
} else {