Merge changes from topic 'xc_remove_shelf'
* changes:
sysui: remove shelf
DO NOT MERGE sysui: remove shelf
diff --git a/Android.mk b/Android.mk
index 53e892f..3f44d62 100644
--- a/Android.mk
+++ b/Android.mk
@@ -430,6 +430,14 @@
core/java/android/service/quicksettings/IQSService.aidl \
core/java/android/service/quicksettings/IQSTileService.aidl \
+# The following are native binders that need to go with the native component
+# at system/update_engine/binder_bindings/. Use relative path to refer to them.
+LOCAL_SRC_FILES += \
+ ../../system/update_engine/binder_bindings/android/os/IUpdateEngine.aidl \
+ ../../system/update_engine/binder_bindings/android/os/IUpdateEngineCallback.aidl \
+
+LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings
+
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
LOCAL_AIDL_INCLUDES += \
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 368b8ef..3288cd9 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -48,13 +48,12 @@
boolean areNotificationsEnabledForPackage(String pkg, int uid);
ParceledListSlice getTopics(String pkg, int uid);
- void setTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
- int getTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
- void setTopicPriority(String pkg, int uid, in Notification.Topic topic, int priority);
- int getTopicPriority(String pkg, int uid, in Notification.Topic topic);
- void setTopicImportance(String pkg, int uid, in Notification.Topic topic, int importance);
- int getTopicImportance(String pkg, int uid, in Notification.Topic topic);
- void setAppImportance(String pkg, int uid, int importance);
+ void setVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
+ int getVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
+ void setPriority(String pkg, int uid, in Notification.Topic topic, int priority);
+ int getPriority(String pkg, int uid, in Notification.Topic topic);
+ void setImportance(String pkg, int uid, in Notification.Topic topic, int importance);
+ int getImportance(String pkg, int uid, in Notification.Topic topic);
boolean doesAppUseTopics(String pkg, int uid);
// TODO: Remove this when callers have been migrated to the equivalent
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 74cb0f6..9cd7d05 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -104,8 +104,6 @@
void getActivityEnergyInfoFromController();
BluetoothActivityEnergyInfo reportActivityInfo();
- // For dumpsys support
- void dump(in ParcelFileDescriptor fd);
void onLeServiceUp();
void onBrEdrDown();
}
diff --git a/core/java/android/print/PrintJob.java b/core/java/android/print/PrintJob.java
index 777baab..66181e0 100644
--- a/core/java/android/print/PrintJob.java
+++ b/core/java/android/print/PrintJob.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import java.util.Objects;
+
/**
* This class represents a print job from the perspective of an
* application. It contains behavior methods for performing operations
@@ -30,11 +32,11 @@
*/
public final class PrintJob {
- private final PrintManager mPrintManager;
+ private final @NonNull PrintManager mPrintManager;
- private PrintJobInfo mCachedInfo;
+ private @NonNull PrintJobInfo mCachedInfo;
- PrintJob(PrintJobInfo info, PrintManager printManager) {
+ PrintJob(@NonNull PrintJobInfo info, @NonNull PrintManager printManager) {
mCachedInfo = info;
mPrintManager = printManager;
}
@@ -44,7 +46,7 @@
*
* @return The id.
*/
- public @NonNull PrintJobId getId() {
+ public @Nullable PrintJobId getId() {
return mCachedInfo.getId();
}
@@ -58,7 +60,7 @@
*
* @return The print job info.
*/
- public @Nullable PrintJobInfo getInfo() {
+ public @NonNull PrintJobInfo getInfo() {
if (isInImmutableState()) {
return mCachedInfo;
}
@@ -193,11 +195,17 @@
return false;
}
PrintJob other = (PrintJob) obj;
- return mCachedInfo.getId().equals(other.mCachedInfo.getId());
+ return Objects.equals(mCachedInfo.getId(), other.mCachedInfo.getId());
}
@Override
public int hashCode() {
- return mCachedInfo.getId().hashCode();
+ PrintJobId printJobId = mCachedInfo.getId();
+
+ if (printJobId == null) {
+ return 0;
+ } else {
+ return printJobId.hashCode();
+ }
}
}
diff --git a/core/java/android/print/PrintJobId.java b/core/java/android/print/PrintJobId.java
index a2ee02b..186ae9b 100644
--- a/core/java/android/print/PrintJobId.java
+++ b/core/java/android/print/PrintJobId.java
@@ -19,7 +19,8 @@
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
-import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
import java.util.UUID;
@@ -27,7 +28,7 @@
* This class represents the id of a print job.
*/
public final class PrintJobId implements Parcelable {
- private final String mValue;
+ private final @NonNull String mValue;
/**
* Creates a new instance.
@@ -45,7 +46,7 @@
*
* @hide
*/
- public PrintJobId(String value) {
+ public PrintJobId(@NonNull String value) {
mValue = value;
}
@@ -53,7 +54,7 @@
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((mValue != null) ? mValue.hashCode() : 0);
+ result = prime * result + mValue.hashCode();
return result;
}
@@ -69,7 +70,7 @@
return false;
}
PrintJobId other = (PrintJobId) obj;
- if (!TextUtils.equals(mValue, other.mValue)) {
+ if (!mValue.equals(other.mValue)) {
return false;
}
return true;
@@ -104,7 +105,7 @@
*
* @hide
*/
- public static PrintJobId unflattenFromString(String string) {
+ public static @NonNull PrintJobId unflattenFromString(@NonNull String string) {
return new PrintJobId(string);
}
@@ -112,7 +113,7 @@
new Parcelable.Creator<PrintJobId>() {
@Override
public PrintJobId createFromParcel(Parcel parcel) {
- return new PrintJobId(parcel.readString());
+ return new PrintJobId(Preconditions.checkNotNull(parcel.readString()));
}
@Override
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 21836b3..7e3a72f 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -244,7 +244,7 @@
*
* @return The id.
*/
- public @NonNull PrintJobId getId() {
+ public @Nullable PrintJobId getId() {
return mId;
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2f2c5e4..a276854 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4185,4 +4185,9 @@
<string name="suspended_package_title">%1$s disabled</string>
<!-- Message for dialog displayed when a packge is suspended by device admin. [CHAR LIMIT=NONE] -->
<string name="suspended_package_message">Disabled by %1$s administrator. Contact them to learn more.</string>
+
+ <!-- Notification title shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
+ <string name="new_sms_notification_title">You have new messages</string>
+ <!-- Notification content shown when new SMS/MMS is received while the device is locked [CHAR LIMIT=NONE] -->
+ <string name="new_sms_notification_content">Open SMS app to view</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1f2c6e1..e59c935 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2499,4 +2499,8 @@
<java-symbol type="string" name="work_mode_turn_on" />
<java-symbol type="string" name="suspended_package_title" />
<java-symbol type="string" name="suspended_package_message" />
+
+ <!-- New SMS notification while phone is locked. -->
+ <java-symbol type="string" name="new_sms_notification_title" />
+ <java-symbol type="string" name="new_sms_notification_content" />
</resources>
diff --git a/libs/hwui/BufferPool.h b/libs/hwui/BufferPool.h
index 9bda233..005b399 100644
--- a/libs/hwui/BufferPool.h
+++ b/libs/hwui/BufferPool.h
@@ -16,8 +16,9 @@
#pragma once
-#include <utils/RefBase.h>
-#include <utils/Log.h>
+#include "utils/RefBase.h"
+#include "utils/Log.h"
+#include "utils/Macros.h"
#include <atomic>
#include <stdint.h>
@@ -37,6 +38,7 @@
class BufferPool : public VirtualLightRefBase {
public:
class Buffer {
+ PREVENT_COPY_AND_ASSIGN(Buffer);
public:
int64_t* getBuffer() { return mBuffer.get(); }
size_t getSize() { return mSize; }
@@ -57,14 +59,17 @@
return refs - 1;
}
+ bool isUniqueRef() {
+ return mRefs.load() == 1;
+ }
+
private:
friend class BufferPool;
- Buffer(BufferPool* pool, size_t size) {
+ Buffer(BufferPool* pool, size_t size) : mRefs(1) {
mSize = size;
mBuffer.reset(new int64_t[size]);
mPool = pool;
- mRefs++;
}
void setPool(BufferPool* pool) {
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 3e37a05..a457212 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -33,6 +33,15 @@
FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
uint32_t viewportWidth, uint32_t viewportHeight,
const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter)
+ : FrameBuilder(layers, clip, viewportWidth, viewportHeight, nodes, lightCenter,
+ Rect(0, 0, 0, 0)) {
+}
+
+
+FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
+ uint32_t viewportWidth, uint32_t viewportHeight,
+ const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter,
+ const Rect &contentDrawBounds)
: mCanvasState(*this) {
ATRACE_NAME("prepare drawing commands");
@@ -72,14 +81,56 @@
}
}
- // Defer Fbo0
+ // It there are multiple render nodes, they are laid out as follows:
+ // #0 - backdrop (content + caption)
+ // #1 - content (positioned at (0,0) and clipped to - its bounds mContentDrawBounds)
+ // #2 - additional overlay nodes
+ // Usually the backdrop cannot be seen since it will be entirely covered by the content. While
+ // resizing however it might become partially visible. The following render loop will crop the
+ // backdrop against the content and draw the remaining part of it. It will then draw the content
+ // cropped to the backdrop (since that indicates a shrinking of the window).
+ //
+ // Additional nodes will be drawn on top with no particular clipping semantics.
+
+ // The bounds of the backdrop against which the content should be clipped.
+ Rect backdropBounds = contentDrawBounds;
+ // Usually the contents bounds should be mContentDrawBounds - however - we will
+ // move it towards the fixed edge to give it a more stable appearance (for the moment).
+ // If there is no content bounds we ignore the layering as stated above and start with 2.
+ int layer = (contentDrawBounds.isEmpty() || nodes.size() == 1) ? 2 : 0;
+
for (const sp<RenderNode>& node : nodes) {
if (node->nothingToDraw()) continue;
node->computeOrdering();
-
int count = mCanvasState.save(SaveFlags::MatrixClip);
+
+ if (layer == 0) {
+ const RenderProperties& properties = node->properties();
+ Rect targetBounds(properties.getLeft(), properties.getTop(),
+ properties.getRight(), properties.getBottom());
+ // Move the content bounds towards the fixed corner of the backdrop.
+ const int x = targetBounds.left;
+ const int y = targetBounds.top;
+ // Remember the intersection of the target bounds and the intersection bounds against
+ // which we have to crop the content.
+ backdropBounds.set(x, y, x + backdropBounds.getWidth(), y + backdropBounds.getHeight());
+ backdropBounds.doIntersect(targetBounds);
+ } else if (layer == 1) {
+ // We shift and clip the content to match its final location in the window.
+ const float left = contentDrawBounds.left;
+ const float top = contentDrawBounds.top;
+ const float dx = backdropBounds.left - left;
+ const float dy = backdropBounds.top - top;
+ const float width = backdropBounds.getWidth();
+ const float height = backdropBounds.getHeight();
+ mCanvasState.translate(dx, dy);
+ // It gets cropped against the bounds of the backdrop to stay inside.
+ mCanvasState.clipRect(left, top, left + width, top + height, SkRegion::kIntersect_Op);
+ }
+
deferNodePropsAndOps(*node);
mCanvasState.restoreToCount(count);
+ layer++;
}
}
diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h
index 4fd39be..dea9934 100644
--- a/libs/hwui/FrameBuilder.h
+++ b/libs/hwui/FrameBuilder.h
@@ -59,6 +59,11 @@
uint32_t viewportWidth, uint32_t viewportHeight,
const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter);
+ FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
+ uint32_t viewportWidth, uint32_t viewportHeight,
+ const std::vector< sp<RenderNode> >& nodes, const Vector3& lightCenter,
+ const Rect &contentDrawBounds);
+
virtual ~FrameBuilder() {}
/**
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 7148c4b..e7cf3ec 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -345,7 +345,7 @@
#if HWUI_NEW_OPS
FrameBuilder frameBuilder(mLayerUpdateQueue, dirty, frame.width(), frame.height(),
- mRenderNodes, mLightCenter);
+ mRenderNodes, mLightCenter, mContentDrawBounds);
mLayerUpdateQueue.clear();
BakedOpRenderer renderer(Caches::getInstance(), mRenderThread.renderState(),
mOpaque, mLightInfo);
diff --git a/libs/hwui/tests/unit/BufferPoolTests.cpp b/libs/hwui/tests/unit/BufferPoolTests.cpp
index 09bd302..44e6d3a 100644
--- a/libs/hwui/tests/unit/BufferPoolTests.cpp
+++ b/libs/hwui/tests/unit/BufferPoolTests.cpp
@@ -36,6 +36,7 @@
ASSERT_EQ(bufferCount - i, pool->getAvailableBufferCount());
acquiredBuffers[i] = pool->acquire();
ASSERT_NE(nullptr, acquiredBuffers[i]);
+ ASSERT_TRUE(acquiredBuffers[i]->isUniqueRef());
}
for (size_t i = 0; i < bufferCount; i++) {
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index b75724c..618df14 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -215,7 +215,8 @@
<< "Expect number of ops = 2 * loop count";
}
-TEST(FrameBuilder, clippedMerging) {
+// TODO: Disabled due to b/26793764
+TEST(FrameBuilder, DISABLED_clippedMerging) {
class ClippedMergingTestRenderer : public TestRendererBase {
public:
void onMergedBitmapOps(const MergedBakedOpList& opList) override {
diff --git a/packages/DocumentsUI/res/layout/item_dir_grid.xml b/packages/DocumentsUI/res/layout/item_dir_grid.xml
index a08e029..b0331be 100644
--- a/packages/DocumentsUI/res/layout/item_dir_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_dir_grid.xml
@@ -17,7 +17,7 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_margin="@dimen/grid_item_margin"
android:background="@color/item_doc_background"
android:elevation="5dp"
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 811adda..743df99 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1003,7 +1003,9 @@
if (currMediaSize == null) {
attributes.setMediaSize(defaults.getMediaSize());
} else {
- boolean foundCurrentMediaSize = false;
+ MediaSize newMediaSize = null;
+ boolean isPortrait = currMediaSize.isPortrait();
+
// Try to find the current media size in the capabilities as
// it may be in a different orientation.
MediaSize currMediaSizePortrait = currMediaSize.asPortrait();
@@ -1011,14 +1013,21 @@
for (int i = 0; i < mediaSizeCount; i++) {
MediaSize mediaSize = sortedMediaSizes.get(i);
if (currMediaSizePortrait.equals(mediaSize.asPortrait())) {
- attributes.setMediaSize(currMediaSize);
- foundCurrentMediaSize = true;
+ newMediaSize = mediaSize;
break;
}
}
// If we did not find the current media size fall back to default.
- if (!foundCurrentMediaSize) {
- attributes.setMediaSize(defaults.getMediaSize());
+ if (newMediaSize == null) {
+ newMediaSize = defaults.getMediaSize();
+ }
+
+ if (newMediaSize != null) {
+ if (isPortrait) {
+ attributes.setMediaSize(newMediaSize.asPortrait());
+ } else {
+ attributes.setMediaSize(newMediaSize.asLandscape());
+ }
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
index 58a477e..eaa563d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
+++ b/packages/SettingsLib/src/com/android/settingslib/SuggestionParser.java
@@ -17,6 +17,7 @@
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -38,14 +39,39 @@
private static final String TAG = "SuggestionParser";
+ // If defined, only returns this suggestion if the feature is supported.
+ public static final String META_DATA_REQUIRE_FEATURE = "com.android.settings.require_feature";
+
+ /**
+ * Allows suggestions to appear after a certain number of days, and to re-appear if dismissed.
+ * For instance:
+ * 0,10
+ * Will appear immediately, but if the user removes it, it will come back after 10 days.
+ *
+ * Another example:
+ * 10,30
+ * Will only show up after 10 days, and then again after 30.
+ */
+ public static final String META_DATA_DISMISS_CONTROL = "com.android.settings.dismiss";
+
+ // Shared prefs keys for storing dismissed state.
+ // Index into current dismissed state.
+ private static final String DISMISS_INDEX = "_dismiss_index";
+ private static final String SETUP_TIME = "_setup_time";
+ private static final String IS_DISMISSED = "_is_dismissed";
+
+ private static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
+
private final Context mContext;
private final List<SuggestionCategory> mSuggestionList;
private final ArrayMap<Pair<String, String>, Tile> addCache = new ArrayMap<>();
+ private final SharedPreferences mSharedPrefs;
- public SuggestionParser(Context context, int orderXml) {
+ public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
mContext = context;
mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
.parse(orderXml);
+ mSharedPrefs = sharedPrefs;
}
public List<Tile> getSuggestions() {
@@ -57,6 +83,23 @@
return suggestions;
}
+ /**
+ * Dismisses a suggestion, returns true if the suggestion has no more dismisses left and should
+ * be disabled.
+ */
+ public boolean dismissSuggestion(Tile suggestion) {
+ String keyBase = suggestion.intent.getComponent().flattenToShortString();
+ int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+ String dismissControl = suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+ if (dismissControl == null || parseDismissString(dismissControl).length == index) {
+ return true;
+ }
+ mSharedPrefs.edit()
+ .putBoolean(keyBase + IS_DISMISSED, true)
+ .commit();
+ return false;
+ }
+
private void readSuggestions(SuggestionCategory category, List<Tile> suggestions) {
int countBefore = suggestions.size();
Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -66,6 +109,11 @@
}
TileUtils.getTilesForIntent(mContext, new UserHandle(UserHandle.myUserId()), intent,
addCache, null, suggestions, true, false);
+ for (int i = countBefore; i < suggestions.size(); i++) {
+ if (!isAvailable(suggestions.get(i)) || isDismissed(suggestions.get(i))) {
+ suggestions.remove(i--);
+ }
+ }
if (!category.multiple && suggestions.size() > (countBefore + 1)) {
// If there are too many, remove them all and only re-add the one with the highest
// priority.
@@ -80,6 +128,58 @@
}
}
+ private boolean isAvailable(Tile suggestion) {
+ String featureRequired = suggestion.metaData.getString(META_DATA_REQUIRE_FEATURE);
+ if (featureRequired != null) {
+ return mContext.getPackageManager().hasSystemFeature(featureRequired);
+ }
+ return true;
+ }
+
+ private boolean isDismissed(Tile suggestion) {
+ String dismissControl = suggestion.metaData.getString(META_DATA_DISMISS_CONTROL);
+ if (dismissControl == null) {
+ return false;
+ }
+ String keyBase = suggestion.intent.getComponent().flattenToShortString();
+ if (!mSharedPrefs.contains(keyBase + SETUP_TIME)) {
+ mSharedPrefs.edit()
+ .putLong(keyBase + SETUP_TIME, System.currentTimeMillis())
+ .commit();
+ }
+ // Default to dismissed, so that we can have suggestions that only first appear after
+ // some number of days.
+ if (!mSharedPrefs.getBoolean(keyBase + IS_DISMISSED, true)) {
+ return false;
+ }
+ int index = mSharedPrefs.getInt(keyBase + DISMISS_INDEX, 0);
+ int currentDismiss = parseDismissString(dismissControl)[index];
+ long time = getEndTime(mSharedPrefs.getLong(keyBase + SETUP_TIME, 0), currentDismiss);
+ if (System.currentTimeMillis() >= time) {
+ // Dismiss timeout has passed, undismiss it.
+ mSharedPrefs.edit()
+ .putBoolean(keyBase + IS_DISMISSED, false)
+ .putInt(keyBase + DISMISS_INDEX, index + 1)
+ .commit();
+ return false;
+ }
+ return true;
+ }
+
+ private long getEndTime(long startTime, int daysDelay) {
+ long days = daysDelay * MILLIS_IN_DAY;
+ return startTime + days;
+ }
+
+ private int[] parseDismissString(String dismissControl) {
+ String[] dismissStrs = dismissControl.split(",");
+ int[] dismisses = new int[dismissStrs.length];
+ for (int i = 0; i < dismissStrs.length; i++) {
+ dismisses[i] = Integer.parseInt(dismissStrs[i]);
+ }
+ return dismisses;
+ }
+
private static class SuggestionCategory {
public String category;
public String pkg;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index e4cd7d9..5abd1d5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -206,13 +206,8 @@
void saveImportance(final StatusBarNotification sbn) {
int progress = mSeekBar.getProgress();
try {
- if (mApplyToTopic.isChecked()) {
- mINotificationManager.setTopicImportance(sbn.getPackageName(), sbn.getUid(), mTopic,
- progress);
- } else {
- mINotificationManager.setAppImportance(
- sbn.getPackageName(), sbn.getUid(), progress);
- }
+ mINotificationManager.setImportance(sbn.getPackageName(), sbn.getUid(),
+ mApplyToTopic.isChecked() ? mTopic : null, progress);
} catch (RemoteException e) {
// :(
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d63dd0c..46198b0 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -1920,7 +1920,9 @@
synchronized (mBackupParticipants) {
if (replacing) {
// This is the package-replaced case; we just remove the entry
- // under the old uid and fall through to re-add.
+ // under the old uid and fall through to re-add. If an app
+ // just added key/value backup participation, this picks it up
+ // as a known participant.
removePackageParticipantsLocked(pkgList, uid);
}
addPackageParticipantsLocked(pkgList);
@@ -1933,6 +1935,14 @@
if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
enqueueFullBackup(packageName, now);
scheduleNextFullBackupJob(0);
+ } else {
+ // The app might have just transitioned out of full-data into
+ // doing key/value backups, or might have just disabled backups
+ // entirely. Make sure it is no longer in the full-data queue.
+ synchronized (mQueueLock) {
+ dequeueFullBackupLocked(packageName);
+ }
+ writeFullBackupScheduleAsync();
}
// Transport maintenance: rebind to known existing transports that have
@@ -1964,6 +1974,9 @@
if (replacing) {
// The package is being updated. We'll receive a PACKAGE_ADDED shortly.
} else {
+ // Outright removal. In the full-data case, the app will be dropped
+ // from the queue when its (now obsolete) name comes up again for
+ // backup.
synchronized (mBackupParticipants) {
removePackageParticipantsLocked(pkgList, uid);
}
@@ -4190,11 +4203,21 @@
// as well as any explicit mention of the 'special' shared-storage agent
// package (we handle that one at the end).
if (MORE_DEBUG) {
- Slog.d(TAG, "Ignoring not eligible package " + pkg);
+ Slog.d(TAG, "Ignoring ineligible package " + pkg);
}
sendBackupOnResult(mBackupObserver, pkg,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
continue;
+ } else if (!appGetsFullBackup(info)) {
+ // Cull any packages that are found in the queue but now aren't supposed
+ // to get full-data backup operations.
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Ignoring full-data backup of key/value participant "
+ + pkg);
+ }
+ sendBackupOnResult(mBackupObserver, pkg,
+ BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ continue;
} else if (appIsStopped(info.applicationInfo)) {
// Cull any packages in the 'stopped' state: they've either just been
// installed or have explicitly been force-stopped by the user. In both
@@ -4592,21 +4615,28 @@
}
/**
+ * Remove a package from the full-data queue.
+ */
+ void dequeueFullBackupLocked(String packageName) {
+ final int N = mFullBackupQueue.size();
+ for (int i = N-1; i >= 0; i--) {
+ final FullBackupEntry e = mFullBackupQueue.get(i);
+ if (packageName.equals(e.packageName)) {
+ mFullBackupQueue.remove(i);
+ }
+ }
+ }
+
+ /**
* Enqueue full backup for the given app, with a note about when it last ran.
*/
void enqueueFullBackup(String packageName, long lastBackedUp) {
FullBackupEntry newEntry = new FullBackupEntry(packageName, lastBackedUp);
synchronized (mQueueLock) {
- int N = mFullBackupQueue.size();
// First, sanity check that we aren't adding a duplicate. Slow but
// straightforward; we'll have at most on the order of a few hundred
// items in this list.
- for (int i = N-1; i >= 0; i--) {
- final FullBackupEntry e = mFullBackupQueue.get(i);
- if (packageName.equals(e.packageName)) {
- mFullBackupQueue.remove(i);
- }
- }
+ dequeueFullBackupLocked(packageName);
// This is also slow but easy for modest numbers of apps: work backwards
// from the end of the queue until we find an item whose last backup
@@ -4700,21 +4730,24 @@
return false;
}
- if (mFullBackupQueue.size() == 0) {
- // no work to do so just bow out
- if (DEBUG) {
- Slog.i(TAG, "Backup queue empty; doing nothing");
- }
- return false;
- }
-
- // At this point we know that we have work to do, but possibly not right now.
+ // At this point we think that we have work to do, but possibly not right now.
// Any exit without actually running backups will also require that we
// reschedule the job.
boolean runBackup = true;
boolean headBusy;
do {
+ // Recheck each time, because culling due to ineligibility may
+ // have emptied the queue.
+ if (mFullBackupQueue.size() == 0) {
+ // no work to do so just bow out
+ if (DEBUG) {
+ Slog.i(TAG, "Backup queue empty; doing nothing");
+ }
+ runBackup = false;
+ break;
+ }
+
headBusy = false;
if (!fullBackupAllowable(getTransport(mCurrentTransport))) {
@@ -4744,6 +4777,19 @@
try {
PackageInfo appInfo = mPackageManager.getPackageInfo(entry.packageName, 0);
+ if (!appGetsFullBackup(appInfo)) {
+ // The head app isn't supposed to get full-data backups [any more];
+ // so we cull it and force a loop around to consider the new head
+ // app.
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Culling package " + entry.packageName
+ + " in full-backup queue but not eligible");
+ }
+ mFullBackupQueue.remove(0);
+ headBusy = true; // force the while() condition
+ continue;
+ }
+
headBusy = mActivityManager.isAppForeground(appInfo.applicationInfo.uid);
if (headBusy) {
@@ -4762,7 +4808,6 @@
enqueueFullBackup(entry.packageName,
nextEligible - MIN_FULL_BACKUP_INTERVAL);
}
-
} catch (NameNotFoundException nnf) {
// So, we think we want to back this up, but it turns out the package
// in question is no longer installed. We want to drop it from the
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index c1a082b..499b706 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -114,13 +114,6 @@
private static final int SERVICE_IBLUETOOTH = 1;
private static final int SERVICE_IBLUETOOTHGATT = 2;
- private static final String[] DEVICE_TYPE_NAMES = new String[] {
- "???",
- "BR/EDR",
- "LE",
- "DUAL"
- };
-
private final Context mContext;
private static int mBleAppCount = 0;
@@ -131,6 +124,7 @@
private final ContentResolver mContentResolver;
private final RemoteCallbackList<IBluetoothManagerCallback> mCallbacks;
private final RemoteCallbackList<IBluetoothStateChangeCallback> mStateChangeCallbacks;
+ private IBinder mBluetoothBinder;
private IBluetooth mBluetooth;
private IBluetoothGatt mBluetoothGatt;
private boolean mBinding;
@@ -242,6 +236,7 @@
mContext = context;
mBluetooth = null;
+ mBluetoothBinder = null;
mBluetoothGatt = null;
mBinding = false;
mUnbinding = false;
@@ -678,6 +673,7 @@
}
if (DBG) Log.d(TAG, "Sending unbind request.");
+ mBluetoothBinder = null;
mBluetooth = null;
//Unbind
mContext.unbindService(mConnection);
@@ -1166,6 +1162,7 @@
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
mBinding = false;
+ mBluetoothBinder = service;
mBluetooth = IBluetooth.Stub.asInterface(service);
try {
@@ -1674,44 +1671,15 @@
}
@Override
- public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
- writer.println("Bluetooth Status");
- writer.println(" enabled: " + mEnable);
- writer.println(" state: " + mState);
- writer.println(" address: " + mAddress);
- writer.println(" name: " + mName + "\n");
- writer.flush();
-
- if (mBluetooth == null) {
- writer.println("Bluetooth Service not connected");
- } else {
- ParcelFileDescriptor pfd = null;
- try {
- writer.println("Bonded devices:");
- for (BluetoothDevice device : mBluetooth.getBondedDevices()) {
- writer.println(" " + device.getAddress() +
- " [" + DEVICE_TYPE_NAMES[device.getType()] + "] " +
- device.getName());
- }
- writer.flush();
-
- pfd = ParcelFileDescriptor.dup(fd);
- mBluetooth.dump(pfd);
- } catch (RemoteException re) {
- writer.println("RemoteException while calling Bluetooth Service");
- } catch (IOException ioe) {
- writer.println("IOException attempting to dup() fd");
- } finally {
- if (pfd != null) {
- try {
- pfd.close();
- } catch (IOException ioe) {
- writer.println("IOException attempting to close() fd");
- }
- }
- }
+ public void dump(FileDescriptor fd, PrintWriter writer, String args[]) {
+ if (mBluetoothBinder == null) {
+ writer.println("Bluetooth Service not connected");
+ } else {
+ try {
+ mBluetoothBinder.dump(fd, args);
+ } catch (RemoteException re) {
+ writer.println("RemoteException while calling Bluetooth Service");
}
+ }
}
}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index dd19c6a..95f5734 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -186,7 +186,6 @@
private final Handler mFgHandler;
private final Handler mDaemonHandler;
- private final PhoneStateListener mPhoneStateListener;
private IBatteryStats mBatteryStats;
@@ -283,22 +282,6 @@
mDaemonHandler = new Handler(FgThread.get().getLooper());
- mPhoneStateListener = new PhoneStateListener(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- mDaemonHandler.getLooper()) {
- @Override
- public void onDataConnectionRealTimeInfoChanged(
- DataConnectionRealTimeInfo dcRtInfo) {
- if (DBG) Slog.d(TAG, "onDataConnectionRealTimeInfoChanged: " + dcRtInfo);
- notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE,
- dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true);
- }
- };
- TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
- if (tm != null) {
- tm.listen(mPhoneStateListener,
- PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO);
- }
-
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 19a4851..9ee8e773 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -34,7 +34,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.CellLocation;
-import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
@@ -179,8 +178,6 @@
private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
- private DataConnectionRealTimeInfo mDcRtInfo = new DataConnectionRealTimeInfo();
-
private int mRingingCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
private int mForegroundCallState = PreciseCallState.PRECISE_CALL_STATE_IDLE;
@@ -624,13 +621,6 @@
remove(r.binder);
}
}
- if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) {
- try {
- r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
- } catch (RemoteException ex) {
- remove(r.binder);
- }
- }
if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
try {
r.callback.onPreciseCallStateChanged(mPreciseCallState);
@@ -921,31 +911,6 @@
}
}
- public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
- if (!checkNotifyPermission("notifyDataConnectionRealTimeInfo()")) {
- return;
- }
-
- synchronized (mRecords) {
- mDcRtInfo = dcRtInfo;
- for (Record r : mRecords) {
- if (validateEventsAndUserLocked(r,
- PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO)) {
- try {
- if (DBG_LOC) {
- log("notifyDataConnectionRealTimeInfo: mDcRtInfo="
- + mDcRtInfo + " r=" + r);
- }
- r.callback.onDataConnectionRealTimeInfoChanged(mDcRtInfo);
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
- }
- }
- }
- handleRemoveListLocked();
- }
- }
-
@Override
public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) {
if (!checkNotifyPermission("notifyMessageWaitingChanged()")) {
@@ -1370,7 +1335,6 @@
pw.println(" mCellLocation=" + mCellLocation[i]);
pw.println(" mCellInfo=" + mCellInfo.get(i));
}
- pw.println(" mDcRtInfo=" + mDcRtInfo);
pw.println("registrations: count=" + recordCount);
for (Record r : mRecords) {
pw.println(" " + r);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 2ee74db..7f783ec 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1242,58 +1242,55 @@
}
@Override
- public void setTopicPriority(String pkg, int uid, Notification.Topic topic, int priority) {
+ public void setPriority(String pkg, int uid, Notification.Topic topic, int priority) {
checkCallerIsSystem();
- mRankingHelper.setTopicPriority(pkg, uid, topic, priority);
+ mRankingHelper.setPriority(pkg, uid, topic, priority);
savePolicyFile();
}
@Override
- public int getTopicPriority(String pkg, int uid, Notification.Topic topic) {
+ public int getPriority(String pkg, int uid, Notification.Topic topic) {
checkCallerIsSystem();
- return mRankingHelper.getTopicPriority(pkg, uid, topic);
+ return mRankingHelper.getPriority(pkg, uid, topic);
}
@Override
- public void setTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic,
+ public void setVisibilityOverride(String pkg, int uid, Notification.Topic topic,
int visibility) {
checkCallerIsSystem();
- mRankingHelper.setTopicVisibilityOverride(pkg, uid, topic, visibility);
+ mRankingHelper.setVisibilityOverride(pkg, uid, topic, visibility);
savePolicyFile();
}
@Override
- public int getTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
+ public int getVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
checkCallerIsSystem();
- return mRankingHelper.getTopicVisibilityOverride(pkg, uid, topic);
+ return mRankingHelper.getVisibilityOverride(pkg, uid, topic);
}
@Override
- public void setTopicImportance(String pkg, int uid, Notification.Topic topic,
+ public void setImportance(String pkg, int uid, Notification.Topic topic,
int importance) {
enforceSystemOrSystemUI("Caller not system or systemui");
- if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
- cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
- UserHandle.getUserId(uid),
- REASON_TOPIC_BANNED, topic, null);
+ if (topic == null) {
+ // App wide, potentially store block in app ops.
+ setNotificationsEnabledForPackageImpl(pkg, uid,
+ importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
+ } else {
+ if (NotificationListenerService.Ranking.IMPORTANCE_NONE == importance) {
+ cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true,
+ UserHandle.getUserId(uid),
+ REASON_TOPIC_BANNED, topic, null);
+ }
}
- mRankingHelper.setTopicImportance(pkg, uid, topic, importance);
+ mRankingHelper.setImportance(pkg, uid, topic, importance);
savePolicyFile();
}
@Override
- public int getTopicImportance(String pkg, int uid, Notification.Topic topic) {
+ public int getImportance(String pkg, int uid, Notification.Topic topic) {
checkCallerIsSystem();
- return mRankingHelper.getTopicImportance(pkg, uid, topic);
- }
-
- @Override
- public void setAppImportance(String pkg, int uid, int importance) {
- enforceSystemOrSystemUI("Caller not system or systemui");
- setNotificationsEnabledForPackageImpl(pkg, uid,
- importance != NotificationListenerService.Ranking.IMPORTANCE_NONE);
- mRankingHelper.setAppImportance(pkg, uid, importance);
- savePolicyFile();
+ return mRankingHelper.getImportance(pkg, uid, topic);
}
@Override
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 490e890..484b0e9 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -33,6 +33,7 @@
import android.service.notification.StatusBarNotification;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
import com.android.server.EventLogTags;
import java.io.PrintWriter;
@@ -106,6 +107,7 @@
mCreationTimeMs = sbn.getPostTime();
mUpdateTimeMs = mCreationTimeMs;
mContext = context;
+ stats = new NotificationUsageStats.SingleNotificationStats();
mImportance = defaultImportance();
}
@@ -133,27 +135,22 @@
importance = IMPORTANCE_MAX;
break;
}
+ stats.requestedImportance = importance;
boolean isNoisy = (n.defaults & Notification.DEFAULT_SOUND) != 0
|| (n.defaults & Notification.DEFAULT_VIBRATE) != 0
|| n.sound != null
|| n.vibrate != null;
+ stats.isNoisy = isNoisy;
if (!isNoisy && importance > IMPORTANCE_DEFAULT) {
importance = IMPORTANCE_DEFAULT;
}
- // maybe only do this for target API < N?
- if (isNoisy) {
- if (importance >= IMPORTANCE_HIGH) {
- importance = IMPORTANCE_MAX;
- } else {
- importance = IMPORTANCE_HIGH;
- }
- }
if (n.fullScreenIntent != null) {
importance = IMPORTANCE_MAX;
}
+ stats.naturalImportance = importance;
return importance;
}
diff --git a/services/core/java/com/android/server/notification/NotificationUsageStats.java b/services/core/java/com/android/server/notification/NotificationUsageStats.java
index 1cdc6db..e75324f 100644
--- a/services/core/java/com/android/server/notification/NotificationUsageStats.java
+++ b/services/core/java/com/android/server/notification/NotificationUsageStats.java
@@ -16,6 +16,8 @@
package com.android.server.notification;
+import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;
+
import android.app.Notification;
import android.content.ContentValues;
import android.content.Context;
@@ -101,7 +103,6 @@
* Called when a notification has been posted.
*/
public synchronized void registerPostedByApp(NotificationRecord notification) {
- notification.stats = new SingleNotificationStats();
notification.stats.posttimeElapsedMs = SystemClock.elapsedRealtime();
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
@@ -119,13 +120,16 @@
* Called when a notification has been updated.
*/
public void registerUpdatedByApp(NotificationRecord notification, NotificationRecord old) {
- notification.stats = old.stats;
+ notification.stats.updateFrom(old.stats);
AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
for (AggregatedStats stats : aggregatedStatsArray) {
stats.numUpdatedByApp++;
stats.countApiUse(notification);
}
releaseAggregatedStatsLocked(aggregatedStatsArray);
+ if (ENABLE_SQLITE_LOG) {
+ mSQLiteLog.logPosted(notification);
+ }
}
/**
@@ -297,10 +301,6 @@
public int numWithActions;
public int numPrivate;
public int numSecret;
- public int numPriorityMax;
- public int numPriorityHigh;
- public int numPriorityLow;
- public int numPriorityMin;
public int numWithBigText;
public int numWithBigPicture;
public int numForegroundService;
@@ -314,11 +314,17 @@
public int numWithSubText;
public int numWithInfoText;
public int numInterrupt;
+ public ImportanceHistogram noisyImportance;
+ public ImportanceHistogram quietImportance;
+ public ImportanceHistogram finalImportance;
public AggregatedStats(Context context, String key) {
this.key = key;
mContext = context;
mCreated = SystemClock.elapsedRealtime();
+ noisyImportance = new ImportanceHistogram(context, "note_imp_noisy_");
+ quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
+ finalImportance = new ImportanceHistogram(context, "note_importance_");
}
public void countApiUse(NotificationRecord record) {
@@ -354,20 +360,12 @@
break;
}
- switch (n.priority) {
- case Notification.PRIORITY_MAX:
- numPriorityMax++;
- break;
- case Notification.PRIORITY_HIGH:
- numPriorityHigh++;
- break;
- case Notification.PRIORITY_LOW:
- numPriorityLow++;
- break;
- case Notification.PRIORITY_MIN:
- numPriorityMin++;
- break;
+ if (record.stats.isNoisy) {
+ noisyImportance.increment(record.stats.requestedImportance);
+ } else {
+ quietImportance.increment(record.stats.requestedImportance);
}
+ finalImportance.increment(record.getImportance());
final Set<String> names = n.extras.keySet();
if (names.contains(Notification.EXTRA_BIG_TEXT)) {
@@ -419,10 +417,6 @@
maybeCount("note_with_actions", (numWithActions - mPrevious.numWithActions));
maybeCount("note_private", (numPrivate - mPrevious.numPrivate));
maybeCount("note_secret", (numSecret - mPrevious.numSecret));
- maybeCount("note_prio_max", (numPriorityMax - mPrevious.numPriorityMax));
- maybeCount("note_prio_high", (numPriorityHigh - mPrevious.numPriorityHigh));
- maybeCount("note_prio_low", (numPriorityLow - mPrevious.numPriorityLow));
- maybeCount("note_prio_min", (numPriorityMin - mPrevious.numPriorityMin));
maybeCount("note_interupt", (numInterrupt - mPrevious.numInterrupt));
maybeCount("note_big_text", (numWithBigText - mPrevious.numWithBigText));
maybeCount("note_big_pic", (numWithBigPicture - mPrevious.numWithBigPicture));
@@ -436,6 +430,9 @@
maybeCount("note_text", (numWithText - mPrevious.numWithText));
maybeCount("note_sub_text", (numWithSubText - mPrevious.numWithSubText));
maybeCount("note_info_text", (numWithInfoText - mPrevious.numWithInfoText));
+ noisyImportance.maybeCount(mPrevious.noisyImportance);
+ quietImportance.maybeCount(mPrevious.quietImportance);
+ finalImportance.maybeCount(mPrevious.finalImportance);
mPrevious.numPostedByApp = numPostedByApp;
mPrevious.numUpdatedByApp = numUpdatedByApp;
@@ -448,10 +445,6 @@
mPrevious.numWithActions = numWithActions;
mPrevious.numPrivate = numPrivate;
mPrevious.numSecret = numSecret;
- mPrevious.numPriorityMax = numPriorityMax;
- mPrevious.numPriorityHigh = numPriorityHigh;
- mPrevious.numPriorityLow = numPriorityLow;
- mPrevious.numPriorityMin = numPriorityMin;
mPrevious.numInterrupt = numInterrupt;
mPrevious.numWithBigText = numWithBigText;
mPrevious.numWithBigPicture = numWithBigPicture;
@@ -465,6 +458,9 @@
mPrevious.numWithText = numWithText;
mPrevious.numWithSubText = numWithSubText;
mPrevious.numWithInfoText = numWithInfoText;
+ noisyImportance.update(mPrevious.noisyImportance);
+ quietImportance.update(mPrevious.quietImportance);
+ finalImportance.update(mPrevious.finalImportance);
}
void maybeCount(String name, int value) {
@@ -483,17 +479,64 @@
}
private String toStringWithIndent(String indent) {
- return indent + "AggregatedStats{\n" +
- indent + " key='" + key + "',\n" +
- indent + " numPostedByApp=" + numPostedByApp + ",\n" +
- indent + " numUpdatedByApp=" + numUpdatedByApp + ",\n" +
- indent + " numRemovedByApp=" + numRemovedByApp + ",\n" +
- indent + " numPeopleCacheHit=" + numPeopleCacheHit + ",\n" +
- indent + " numWithStaredPeople=" + numWithStaredPeople + ",\n" +
- indent + " numWithValidPeople=" + numWithValidPeople + ",\n" +
- indent + " numPeopleCacheMiss=" + numPeopleCacheMiss + ",\n" +
- indent + " numBlocked=" + numBlocked + ",\n" +
- indent + "}";
+ StringBuilder output = new StringBuilder();
+ output.append(indent).append("AggregatedStats{\n");
+ String indentPlusTwo = indent + " ";
+ output.append(indentPlusTwo);
+ output.append("key='").append(key).append("',\n");
+ output.append(indentPlusTwo);
+ output.append("numPostedByApp=").append(numPostedByApp).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numUpdatedByApp=").append(numUpdatedByApp).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numRemovedByApp=").append(numRemovedByApp).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numPeopleCacheHit=").append(numPeopleCacheHit).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numWithStaredPeople=").append(numWithStaredPeople).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numWithValidPeople=").append(numWithValidPeople).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numPeopleCacheMiss=").append(numPeopleCacheMiss).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numBlocked=").append(numBlocked).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numWithActions=").append(numWithActions).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numPrivate=").append(numPrivate).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numSecret=").append(numSecret).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numInterrupt=").append(numInterrupt).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numWithBigText=").append(numWithBigText).append(",\n");
+ output.append(indentPlusTwo);
+ output.append("numWithBigPicture=").append(numWithBigPicture).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numForegroundService=").append(numForegroundService).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numOngoing=").append(numOngoing).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numAutoCancel=").append(numAutoCancel).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithLargeIcon=").append(numWithLargeIcon).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithInbox=").append(numWithInbox).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithMediaSession=").append(numWithMediaSession).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithTitle=").append(numWithTitle).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithText=").append(numWithText).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithSubText=").append(numWithSubText).append("\n");
+ output.append(indentPlusTwo);
+ output.append("numWithInfoText=").append(numWithInfoText).append("\n");
+ output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
+ output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
+ output.append(indentPlusTwo).append(finalImportance.toString()).append("\n");
+ output.append(indent).append("}");
+ return output.toString();
}
public JSONObject dumpJson() throws JSONException {
@@ -511,10 +554,6 @@
maybePut(dump, "numWithActions", numWithActions);
maybePut(dump, "numPrivate", numPrivate);
maybePut(dump, "numSecret", numSecret);
- maybePut(dump, "numPriorityMax", numPriorityMax);
- maybePut(dump, "numPriorityHigh", numPriorityHigh);
- maybePut(dump, "numPriorityLow", numPriorityLow);
- maybePut(dump, "numPriorityMin", numPriorityMin);
maybePut(dump, "numInterrupt", numInterrupt);
maybePut(dump, "numWithBigText", numWithBigText);
maybePut(dump, "numWithBigPicture", numWithBigPicture);
@@ -528,6 +567,10 @@
maybePut(dump, "numWithText", numWithText);
maybePut(dump, "numWithSubText", numWithSubText);
maybePut(dump, "numWithInfoText", numWithInfoText);
+ noisyImportance.maybePut(dump, mPrevious.noisyImportance);
+ quietImportance.maybePut(dump, mPrevious.quietImportance);
+ finalImportance.maybePut(dump, mPrevious.finalImportance);
+
return dump;
}
@@ -538,6 +581,65 @@
}
}
+ private static class ImportanceHistogram {
+ // TODO define these somewhere else
+ private static final int NUM_IMPORTANCES = 5;
+ private static final String[] IMPORTANCE_NAMES = {"none", "low", "default", "high", "max"};
+ private final Context mContext;
+ private final String[] mCounterNames;
+ private final String mPrefix;
+ private int[] mCount;
+
+ ImportanceHistogram(Context context, String prefix) {
+ mContext = context;
+ mCount = new int[NUM_IMPORTANCES];
+ mCounterNames = new String[NUM_IMPORTANCES];
+ mPrefix = prefix;
+ for (int i = 0; i < NUM_IMPORTANCES; i++) {
+ mCounterNames[i] = mPrefix + IMPORTANCE_NAMES[i];
+ }
+ }
+
+ void increment(int imp) {
+ imp = imp < 0 ? 0 : imp > NUM_IMPORTANCES ? NUM_IMPORTANCES : imp;
+ mCount[imp] ++;
+ }
+
+ void maybeCount(ImportanceHistogram prev) {
+ for (int i = 0; i < NUM_IMPORTANCES; i++) {
+ final int value = mCount[i] - prev.mCount[i];
+ if (value > 0) {
+ MetricsLogger.count(mContext, mCounterNames[i], value);
+ }
+ }
+ }
+
+ void update(ImportanceHistogram that) {
+ for (int i = 0; i < NUM_IMPORTANCES; i++) {
+ mCount[i] = that.mCount[i];
+ }
+ }
+
+ public void maybePut(JSONObject dump, ImportanceHistogram prev)
+ throws JSONException {
+ dump.put(mPrefix, new JSONArray(mCount));
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+ output.append(mPrefix).append(": [");
+ for (int i = 0; i < NUM_IMPORTANCES; i++) {
+ output.append(mCount[i]);
+ if (i < (NUM_IMPORTANCES-1)) {
+ output.append(", ");
+ }
+ }
+ output.append("]");
+ return output.toString();
+ }
+ }
+
/**
* Tracks usage of an individual notification that is currently active.
*/
@@ -575,6 +677,12 @@
public long airtimeExpandedMs = 0;
/** Number of times the notification has been expanded by the user. */
public long userExpansionCount = 0;
+ /** Importance directly requested by the app. */
+ public int requestedImportance;
+ /** Did the app include sound or vibration on the notificaiton. */
+ public boolean isNoisy;
+ /** Importance after initial filtering for noise and other features */
+ public int naturalImportance;
public long getCurrentPosttimeMs() {
if (posttimeElapsedMs < 0) {
@@ -686,17 +794,40 @@
@Override
public String toString() {
- return "SingleNotificationStats{" +
- "posttimeElapsedMs=" + posttimeElapsedMs +
- ", posttimeToFirstClickMs=" + posttimeToFirstClickMs +
- ", posttimeToDismissMs=" + posttimeToDismissMs +
- ", airtimeCount=" + airtimeCount +
- ", airtimeMs=" + airtimeMs +
- ", currentAirtimeStartElapsedMs=" + currentAirtimeStartElapsedMs +
- ", airtimeExpandedMs=" + airtimeExpandedMs +
- ", posttimeToFirstVisibleExpansionMs=" + posttimeToFirstVisibleExpansionMs +
- ", currentAirtimeExpandedSEMs=" + currentAirtimeExpandedStartElapsedMs +
- '}';
+ StringBuilder output = new StringBuilder();
+ output.append("SingleNotificationStats{");
+
+ output.append("posttimeElapsedMs=").append(posttimeElapsedMs).append(", ");
+ output.append("posttimeToFirstClickMs=").append(posttimeToFirstClickMs).append(", ");
+ output.append("posttimeToDismissMs=").append(posttimeToDismissMs).append(", ");
+ output.append("airtimeCount=").append(airtimeCount).append(", ");
+ output.append("airtimeMs=").append(airtimeMs).append(", ");
+ output.append("currentAirtimeStartElapsedMs=").append(currentAirtimeStartElapsedMs)
+ .append(", ");
+ output.append("airtimeExpandedMs=").append(airtimeExpandedMs).append(", ");
+ output.append("posttimeToFirstVisibleExpansionMs=")
+ .append(posttimeToFirstVisibleExpansionMs).append(", ");
+ output.append("currentAirtimeExpandedStartElapsedMs=")
+ .append(currentAirtimeExpandedStartElapsedMs).append(", ");
+ output.append("requestedImportance=").append(requestedImportance).append(", ");
+ output.append("naturalImportance=").append(naturalImportance).append(", ");
+ output.append("isNoisy=").append(isNoisy);
+ output.append('}');
+ return output.toString();
+ }
+
+ /** Copy useful information out of the stats from the pre-update notifications. */
+ public void updateFrom(SingleNotificationStats old) {
+ posttimeElapsedMs = old.posttimeElapsedMs;
+ posttimeToFirstClickMs = old.posttimeToFirstClickMs;
+ airtimeCount = old.airtimeCount;
+ posttimeToFirstAirtimeMs = old.posttimeToFirstAirtimeMs;
+ currentAirtimeStartElapsedMs = old.currentAirtimeStartElapsedMs;
+ airtimeMs = old.airtimeMs;
+ posttimeToFirstVisibleExpansionMs = old.posttimeToFirstVisibleExpansionMs;
+ currentAirtimeExpandedStartElapsedMs = old.currentAirtimeExpandedStartElapsedMs;
+ airtimeExpandedMs = old.airtimeExpandedMs;
+ userExpansionCount = old.userExpansionCount;
}
}
@@ -741,7 +872,7 @@
private static final int MSG_DISMISS = 4;
private static final String DB_NAME = "notification_log.db";
- private static final int DB_VERSION = 4;
+ private static final int DB_VERSION = 5;
/** Age in ms after which events are pruned from the DB. */
private static final long HORIZON_MS = 7 * 24 * 60 * 60 * 1000L; // 1 week
@@ -762,7 +893,11 @@
private static final String COL_WHEN_MS = "when_ms";
private static final String COL_DEFAULTS = "defaults";
private static final String COL_FLAGS = "flags";
- private static final String COL_PRIORITY = "priority";
+ private static final String COL_IMPORTANCE_REQ = "importance_request";
+ private static final String COL_IMPORTANCE_FINAL = "importance_final";
+ private static final String COL_NOISY = "noisy";
+ private static final String COL_MUTED = "muted";
+ private static final String COL_DEMOTED = "demoted";
private static final String COL_CATEGORY = "category";
private static final String COL_ACTION_COUNT = "action_count";
private static final String COL_POSTTIME_MS = "posttime_ms";
@@ -776,14 +911,28 @@
private static final int EVENT_TYPE_CLICK = 2;
private static final int EVENT_TYPE_REMOVE = 3;
private static final int EVENT_TYPE_DISMISS = 4;
-
private static long sLastPruneMs;
+
private static long sNumWrites;
-
private final SQLiteOpenHelper mHelper;
- private final Handler mWriteHandler;
+ private final Handler mWriteHandler;
private static final long DAY_MS = 24 * 60 * 60 * 1000;
+ private static final String STATS_QUERY = "SELECT " +
+ COL_EVENT_USER_ID + ", " +
+ COL_PKG + ", " +
+ // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
+ "CAST(((%d - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
+ "AS day, " +
+ "COUNT(*) AS cnt, " +
+ "SUM(" + COL_MUTED + ") as muted, " +
+ "SUM(" + COL_NOISY + ") as noisy, " +
+ "SUM(" + COL_DEMOTED + ") as demoted " +
+ "FROM " + TAB_LOG + " " +
+ "WHERE " +
+ COL_EVENT_TYPE + "=" + EVENT_TYPE_POST +
+ " AND " + COL_EVENT_TIME + " > %d " +
+ " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
public SQLiteLog(Context context) {
HandlerThread backgroundThread = new HandlerThread("notification-sqlite-log",
@@ -828,7 +977,11 @@
COL_WHEN_MS + " INT," +
COL_DEFAULTS + " INT," +
COL_FLAGS + " INT," +
- COL_PRIORITY + " INT," +
+ COL_IMPORTANCE_REQ + " INT," +
+ COL_IMPORTANCE_FINAL + " INT," +
+ COL_NOISY + " INT," +
+ COL_MUTED + " INT," +
+ COL_DEMOTED + " INT," +
COL_CATEGORY + " TEXT," +
COL_ACTION_COUNT + " INT," +
COL_POSTTIME_MS + " INT," +
@@ -841,8 +994,7 @@
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion <= 3) {
- // Version 3 creation left 'log' in a weird state. Just reset for now.
+ if (oldVersion != newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TAB_LOG);
onCreate(db);
}
@@ -866,22 +1018,11 @@
mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification));
}
- private JSONArray JsonPostFrequencies(DumpFilter filter) throws JSONException {
+ private JSONArray jsonPostFrequencies(DumpFilter filter) throws JSONException {
JSONArray frequencies = new JSONArray();
SQLiteDatabase db = mHelper.getReadableDatabase();
long midnight = getMidnightMs();
- String q = "SELECT " +
- COL_EVENT_USER_ID + ", " +
- COL_PKG + ", " +
- // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
- "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
- "AS day, " +
- "COUNT(*) AS cnt " +
- "FROM " + TAB_LOG + " " +
- "WHERE " +
- COL_EVENT_TYPE + "=" + EVENT_TYPE_POST +
- " AND " + COL_EVENT_TIME + " > " + filter.since +
- " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
+ String q = String.format(STATS_QUERY, midnight, filter.since);
Cursor cursor = db.rawQuery(q, null);
try {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -890,11 +1031,17 @@
if (filter != null && !filter.matches(pkg)) continue;
int day = cursor.getInt(2);
int count = cursor.getInt(3);
+ int muted = cursor.getInt(4);
+ int noisy = cursor.getInt(5);
+ int demoted = cursor.getInt(6);
JSONObject row = new JSONObject();
row.put("user_id", userId);
row.put("package", pkg);
row.put("day", day);
row.put("count", count);
+ row.put("noisy", noisy);
+ row.put("muted", muted);
+ row.put("demoted", demoted);
frequencies.put(row);
}
} finally {
@@ -906,17 +1053,7 @@
public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) {
SQLiteDatabase db = mHelper.getReadableDatabase();
long midnight = getMidnightMs();
- String q = "SELECT " +
- COL_EVENT_USER_ID + ", " +
- COL_PKG + ", " +
- // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
- "CAST(((" + midnight + " - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
- "AS day, " +
- "COUNT(*) AS cnt " +
- "FROM " + TAB_LOG + " " +
- "WHERE " +
- COL_EVENT_TYPE + "=" + EVENT_TYPE_POST + " " +
- "GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;
+ String q = String.format(STATS_QUERY, midnight, filter.since);
Cursor cursor = db.rawQuery(q, null);
try {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
@@ -925,8 +1062,12 @@
if (filter != null && !filter.matches(pkg)) continue;
int day = cursor.getInt(2);
int count = cursor.getInt(3);
+ int muted = cursor.getInt(4);
+ int noisy = cursor.getInt(5);
+ int demoted = cursor.getInt(6);
pw.println(indent + "post_frequency{user_id=" + userId + ",pkg=" + pkg +
- ",day=" + day + ",count=" + count + "}");
+ ",day=" + day + ",count=" + count + ",muted=" + muted + "/" + noisy +
+ ",demoted=" + demoted + "}");
}
} finally {
cursor.close();
@@ -985,7 +1126,18 @@
}
outCv.put(COL_WHEN_MS, r.sbn.getPostTime());
outCv.put(COL_FLAGS, r.getNotification().flags);
- outCv.put(COL_PRIORITY, r.getNotification().priority);
+ final int before = r.stats.requestedImportance;
+ final int after = r.getImportance();
+ final boolean noisy = r.stats.isNoisy;
+ outCv.put(COL_IMPORTANCE_REQ, before);
+ outCv.put(COL_IMPORTANCE_FINAL, after);
+ outCv.put(COL_DEMOTED, after < before ? 1 : 0);
+ outCv.put(COL_NOISY, noisy);
+ if (noisy && after < IMPORTANCE_HIGH) {
+ outCv.put(COL_MUTED, 1);
+ } else {
+ outCv.put(COL_MUTED, 0);
+ }
if (r.getNotification().category != null) {
outCv.put(COL_CATEGORY, r.getNotification().category);
}
@@ -1008,7 +1160,9 @@
public JSONObject dumpJson(DumpFilter filter) {
JSONObject dump = new JSONObject();
try {
- dump.put("post_frequency", JsonPostFrequencies(filter));
+ dump.put("post_frequency", jsonPostFrequencies(filter));
+ dump.put("since", filter.since);
+ dump.put("now", System.currentTimeMillis());
} catch (JSONException e) {
// pass
}
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 9b10ef2..7f85e1f 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -23,20 +23,18 @@
List<Notification.Topic> getTopics(String packageName, int uid);
- int getTopicPriority(String packageName, int uid, Notification.Topic topic);
+ int getPriority(String packageName, int uid, Notification.Topic topic);
- void setTopicPriority(String packageName, int uid, Notification.Topic topic, int priority);
+ void setPriority(String packageName, int uid, Notification.Topic topic, int priority);
- int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic);
+ int getVisibilityOverride(String packageName, int uid, Notification.Topic topic);
- void setTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic,
+ void setVisibilityOverride(String packageName, int uid, Notification.Topic topic,
int visibility);
- void setTopicImportance(String packageName, int uid, Notification.Topic topic, int importance);
+ void setImportance(String packageName, int uid, Notification.Topic topic, int importance);
- int getTopicImportance(String packageName, int uid, Notification.Topic topic);
-
- void setAppImportance(String packageName, int uid, int importance);
+ int getImportance(String packageName, int uid, Notification.Topic topic);
boolean doesAppUseTopics(String packageName, int uid);
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index ce4ecd3..827482f 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -164,6 +164,8 @@
r = getOrCreateRecord(name, uid);
}
r.importance = safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+ r.priority = priority;
+ r.visibility = vis;
// Migrate package level settings to the default topic.
// Might be overwritten by parseTopics.
@@ -245,7 +247,15 @@
}
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATT_NAME, r.pkg);
- out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+ if (r.importance != DEFAULT_IMPORTANCE) {
+ out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
+ }
+ if (r.priority != DEFAULT_PRIORITY) {
+ out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
+ }
+ if (r.visibility != DEFAULT_VISIBILITY) {
+ out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
+ }
if (!forBackup) {
out.attribute(null, ATT_UID, Integer.toString(r.uid));
@@ -373,66 +383,109 @@
public List<Notification.Topic> getTopics(String packageName, int uid) {
final Record r = getOrCreateRecord(packageName, uid);
List<Notification.Topic> topics = new ArrayList<>();
- for (Topic t : r.topics.values()) {
+ for (Topic t : r.topics.values()) {
topics.add(t.topic);
}
return topics;
}
+ /**
+ * Gets priority. If a topic is given, returns the priority of that topic. Otherwise, the
+ * priority of the app.
+ */
@Override
- public int getTopicPriority(String packageName, int uid, Notification.Topic topic) {
+ public int getPriority(String packageName, int uid, Notification.Topic topic) {
final Record r = getOrCreateRecord(packageName, uid);
+ if (topic == null) {
+ return r.priority;
+ }
return getOrCreateTopic(r, topic).priority;
}
+ /**
+ * Sets priority. If a topic is given, sets the priority of that topic. If not,
+ * sets the default priority for all new topics that appear in the future, and resets
+ * the priority of all current topics.
+ */
@Override
- public void setTopicPriority(String packageName, int uid, Notification.Topic topic,
+ public void setPriority(String packageName, int uid, Notification.Topic topic,
int priority) {
final Record r = getOrCreateRecord(packageName, uid);
- getOrCreateTopic(r, topic).priority = priority;
- updateConfig();
- }
-
- @Override
- public int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
- final Record r = getOrCreateRecord(packageName, uid);
- return getOrCreateTopic(r, topic).visibility;
- }
-
- @Override
- public void setTopicVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
- int visibility) {
- final Record r = getOrCreateRecord(pkgName, uid);
- getOrCreateTopic(r, topic).visibility = visibility;
- updateConfig();
- }
-
- @Override
- public int getTopicImportance(String packageName, int uid, Notification.Topic topic) {
- final Record r = getOrCreateRecord(packageName, uid);
- return getOrCreateTopic(r, topic).importance;
- }
-
- @Override
- public void setTopicImportance(String pkgName, int uid, Notification.Topic topic,
- int importance) {
- final Record r = getOrCreateRecord(pkgName, uid);
- getOrCreateTopic(r, topic).importance = importance;
+ if (topic == null) {
+ r.priority = priority;
+ for (Topic t : r.topics.values()) {
+ t.priority = priority;
+ }
+ } else {
+ getOrCreateTopic(r, topic).priority = priority;
+ }
updateConfig();
}
/**
- * Sets the default importance for all new topics that appear in the future, and resets
+ * Gets visual override. If a topic is given, returns the override of that topic. Otherwise, the
+ * override of the app.
+ */
+ @Override
+ public int getVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ if (topic == null) {
+ return r.visibility;
+ }
+ return getOrCreateTopic(r, topic).visibility;
+ }
+
+ /**
+ * Sets visibility override. If a topic is given, sets the override of that topic. If not,
+ * sets the default override for all new topics that appear in the future, and resets
+ * the override of all current topics.
+ */
+ @Override
+ public void setVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
+ int visibility) {
+ final Record r = getOrCreateRecord(pkgName, uid);
+ if (topic == null) {
+ r.visibility = visibility;
+ for (Topic t : r.topics.values()) {
+ t.visibility = visibility;
+ }
+ } else {
+ getOrCreateTopic(r, topic).visibility = visibility;
+ }
+ updateConfig();
+ }
+
+ /**
+ * Gets importance. If a topic is given, returns the importance of that topic. Otherwise, the
+ * importance of the app.
+ */
+ @Override
+ public int getImportance(String packageName, int uid, Notification.Topic topic) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ if (topic == null) {
+ return r.importance;
+ }
+ return getOrCreateTopic(r, topic).importance;
+ }
+
+ /**
+ * Sets importance. If a topic is given, sets the importance of that topic. If not, sets the
+ * default importance for all new topics that appear in the future, and resets
* the importance of all current topics (unless the app is being blocked).
*/
@Override
- public void setAppImportance(String pkgName, int uid, int importance) {
+ public void setImportance(String pkgName, int uid, Notification.Topic topic,
+ int importance) {
final Record r = getOrCreateRecord(pkgName, uid);
- r.importance = importance;
- if (Ranking.IMPORTANCE_NONE != importance) {
- for (Topic t : r.topics.values()) {
- t.importance = importance;
+ if (topic == null) {
+ r.importance = importance;
+ if (Ranking.IMPORTANCE_NONE != importance) {
+ for (Topic t : r.topics.values()) {
+ t.importance = importance;
+ }
}
+ } else {
+ getOrCreateTopic(r, topic).importance = importance;
}
updateConfig();
}
@@ -459,6 +512,8 @@
} else {
t = new Topic(topic);
t.importance = r.importance;
+ t.priority = r.priority;
+ t.visibility = r.visibility;
r.topics.put(topic.getId(), t);
return t;
}
@@ -503,8 +558,18 @@
pw.print(" (");
pw.print(r.uid == Record.UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid));
pw.print(')');
- pw.print(" importance=");
- pw.print(Ranking.importanceToString(r.importance));
+ if (r.importance != DEFAULT_IMPORTANCE) {
+ pw.print(" importance=");
+ pw.print(Ranking.importanceToString(r.importance));
+ }
+ if (r.priority != DEFAULT_PRIORITY) {
+ pw.print(" priority=");
+ pw.print(Ranking.importanceToString(r.priority));
+ }
+ if (r.visibility != DEFAULT_VISIBILITY) {
+ pw.print(" visibility=");
+ pw.print(Ranking.importanceToString(r.visibility));
+ }
pw.println();
for (Topic t : r.topics.values()) {
pw.print(prefix);
@@ -561,6 +626,8 @@
String pkg;
int uid = UNKNOWN_UID;
int importance = DEFAULT_IMPORTANCE;
+ int priority = DEFAULT_PRIORITY;
+ int visibility = DEFAULT_VISIBILITY;
Map<String, Topic> topics = new ArrayMap<>();
}
diff --git a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java b/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
index 01770d0..c6b3e0f 100644
--- a/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicImportanceExtractor.java
@@ -42,7 +42,7 @@
return null;
}
- final int topicImportance = mConfig.getTopicImportance(record.sbn.getPackageName(),
+ final int topicImportance = mConfig.getImportance(record.sbn.getPackageName(),
record.sbn.getUid(), record.sbn.getNotification().getTopic());
record.setTopicImportance(topicImportance);
diff --git a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
index 5bf989ae..1df5c2b 100644
--- a/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
@@ -42,7 +42,7 @@
return null;
}
- final int packagePriority = mConfig.getTopicPriority(record.sbn.getPackageName(),
+ final int packagePriority = mConfig.getPriority(record.sbn.getPackageName(),
record.sbn.getUid(), record.sbn.getNotification().getTopic());
record.setPackagePriority(packagePriority);
diff --git a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
index e053382..eaa3ed3 100644
--- a/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
@@ -42,7 +42,7 @@
return null;
}
- final int packageVisibility = mConfig.getTopicVisibilityOverride(
+ final int packageVisibility = mConfig.getVisibilityOverride(
record.sbn.getPackageName(), record.sbn.getUid(),
record.sbn.getNotification().getTopic());
record.setPackageVisibilityOverride(packageVisibility);
diff --git a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
index 2640889..31182fc 100644
--- a/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -155,16 +155,12 @@
@SmallTest
public void testTopicImportanceExtractor() throws Exception {
- mHelper.setTopicImportance("package", 0, new Notification.Topic("A", "a"),
- IMPORTANCE_MAX);
+ mHelper.setImportance("package", 0, new Notification.Topic("A", "a"), IMPORTANCE_MAX);
// There is no B. There never was a b. Moving on...
- mHelper.setTopicImportance("package", 0, new Notification.Topic("C", "c"),
- IMPORTANCE_HIGH);
- mHelper.setTopicImportance("package", 0, new Notification.Topic("D", "d"),
- IMPORTANCE_LOW);
+ mHelper.setImportance("package", 0, new Notification.Topic("C", "c"), IMPORTANCE_HIGH);
+ mHelper.setImportance("package", 0, new Notification.Topic("D", "d"), IMPORTANCE_LOW);
// watch out: different package.
- mHelper.setTopicImportance("package2", 0, new Notification.Topic("E", "e"),
- IMPORTANCE_NONE);
+ mHelper.setImportance("package2", 0, new Notification.Topic("E", "e"), IMPORTANCE_NONE);
TopicImportanceExtractor validator = mHelper.findExtractor(TopicImportanceExtractor.class);
validator.process(mRecordGroupGSortA);
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 16472c8..ae130d4 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -194,10 +194,12 @@
* {@more}
* Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
* READ_PRECISE_PHONE_STATE}
- *
* @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
+ *
+ * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
* @hide
*/
+ @Deprecated
public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000;
/**
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 76b69ce..907d76e 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -21,7 +21,6 @@
import android.net.NetworkCapabilities;
import android.os.Bundle;
import android.telephony.CellInfo;
-import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.CellInfo;
@@ -65,7 +64,6 @@
void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
String failCause);
void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
- void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo);
void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData);
void notifySubscriptionInfoChanged();