Merge changes Iac20cc7b,I87ce6320
* changes:
Fixing potential issue with wrong task descriptions being loaded.
Refactoring to AnimatedEvent.
diff --git a/Android.mk b/Android.mk
index a098379..51dfa57 100644
--- a/Android.mk
+++ b/Android.mk
@@ -226,6 +226,7 @@
core/java/android/service/carrier/ICarrierMessagingService.aidl \
core/java/android/service/gatekeeper/IGateKeeperService.aidl \
core/java/android/service/notification/INotificationListener.aidl \
+ core/java/android/service/notification/INotificationAssistant.aidl \
core/java/android/service/notification/IStatusBarNotificationHolder.aidl \
core/java/android/service/notification/IConditionListener.aidl \
core/java/android/service/notification/IConditionProvider.aidl \
diff --git a/api/current.txt b/api/current.txt
index 5421f05..e4962d8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30919,6 +30919,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
@@ -33195,13 +33196,20 @@
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
}
+ public class NotificationAdjustment implements android.os.Parcelable {
+ ctor public NotificationAdjustment(int, java.lang.CharSequence, android.net.Uri);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.notification.NotificationAdjustment> CREATOR;
+ }
+
public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
ctor public NotificationAssistantService();
- method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAssistantService.Adjustment);
+ method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAdjustment);
method public final void clearAnnotation(java.lang.String);
method public void onNotificationActionClick(java.lang.String, long, int);
method public void onNotificationClick(java.lang.String, long);
- method public abstract android.service.notification.NotificationAssistantService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.NotificationAdjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
method public void onNotificationRemoved(java.lang.String, long, int);
method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
method public final void setAnnotation(java.lang.String, android.app.Notification);
@@ -33218,10 +33226,7 @@
field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
field public static final int REASON_USER_STOPPED = 6; // 0x6
- }
-
- public class NotificationAssistantService.Adjustment {
- ctor public NotificationAssistantService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
}
public abstract class NotificationListenerService extends android.app.Service {
diff --git a/api/system-current.txt b/api/system-current.txt
index 3071fd9..586ea06 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9656,7 +9656,6 @@
method public void setAppLabel(java.lang.CharSequence);
method public void setAppPackageName(java.lang.String);
method public void setGrantedRuntimePermissions(java.lang.String[]);
- method public void setInstallFlagsQuick();
method public void setInstallLocation(int);
method public void setOriginatingUid(int);
method public void setOriginatingUri(android.net.Uri);
@@ -33062,6 +33061,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
@@ -35339,13 +35339,20 @@
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
}
+ public class NotificationAdjustment implements android.os.Parcelable {
+ ctor public NotificationAdjustment(int, java.lang.CharSequence, android.net.Uri);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.notification.NotificationAdjustment> CREATOR;
+ }
+
public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
ctor public NotificationAssistantService();
- method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAssistantService.Adjustment);
+ method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAdjustment);
method public final void clearAnnotation(java.lang.String);
method public void onNotificationActionClick(java.lang.String, long, int);
method public void onNotificationClick(java.lang.String, long);
- method public abstract android.service.notification.NotificationAssistantService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.NotificationAdjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
method public void onNotificationRemoved(java.lang.String, long, int);
method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
method public final void setAnnotation(java.lang.String, android.app.Notification);
@@ -35362,10 +35369,7 @@
field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
field public static final int REASON_USER_STOPPED = 6; // 0x6
- }
-
- public class NotificationAssistantService.Adjustment {
- ctor public NotificationAssistantService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
}
public abstract class NotificationListenerService extends android.app.Service {
diff --git a/api/test-current.txt b/api/test-current.txt
index f418d36..eccd8b0 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -30921,6 +30921,7 @@
field public static final java.lang.String ACTION_LOCATION_SOURCE_SETTINGS = "android.settings.LOCATION_SOURCE_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS = "android.settings.MANAGE_ALL_APPLICATIONS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_APPLICATIONS_SETTINGS = "android.settings.MANAGE_APPLICATIONS_SETTINGS";
+ field public static final java.lang.String ACTION_MANAGE_DEFAULT_APPS_SETTINGS = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
field public static final java.lang.String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
field public static final java.lang.String ACTION_MANAGE_WRITE_SETTINGS = "android.settings.action.MANAGE_WRITE_SETTINGS";
field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS";
@@ -33197,13 +33198,20 @@
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
}
+ public class NotificationAdjustment implements android.os.Parcelable {
+ ctor public NotificationAdjustment(int, java.lang.CharSequence, android.net.Uri);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.notification.NotificationAdjustment> CREATOR;
+ }
+
public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
ctor public NotificationAssistantService();
- method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAssistantService.Adjustment);
+ method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAdjustment);
method public final void clearAnnotation(java.lang.String);
method public void onNotificationActionClick(java.lang.String, long, int);
method public void onNotificationClick(java.lang.String, long);
- method public abstract android.service.notification.NotificationAssistantService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
+ method public abstract android.service.notification.NotificationAdjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean);
method public void onNotificationRemoved(java.lang.String, long, int);
method public void onNotificationVisibilityChanged(java.lang.String, long, boolean);
method public final void setAnnotation(java.lang.String, android.app.Notification);
@@ -33220,10 +33228,7 @@
field public static final int REASON_PACKAGE_BANNED = 7; // 0x7
field public static final int REASON_PACKAGE_CHANGED = 5; // 0x5
field public static final int REASON_USER_STOPPED = 6; // 0x6
- }
-
- public class NotificationAssistantService.Adjustment {
- ctor public NotificationAssistantService.Adjustment(int, java.lang.CharSequence, android.net.Uri);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
}
public abstract class NotificationListenerService extends android.app.Service {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 571bc6e..4ed2fd7 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5300,8 +5300,7 @@
*/
public boolean isTaskRoot() {
try {
- return ActivityManagerNative.getDefault()
- .getTaskForActivity(mToken, true) >= 0;
+ return ActivityManagerNative.getDefault().getTaskForActivity(mToken, true) >= 0;
} catch (RemoteException e) {
return false;
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c39ee75..681ed5b 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -556,14 +556,6 @@
public static boolean isAlwaysOnTop(int stackId) {
return stackId == PINNED_STACK_ID;
}
-
- /**
- * Returns true if the application windows in this stack should be displayed above all
- * other application windows, including during the animation.
- */
- public static boolean shouldIncreaseApplicationWindowLayer(int stackId) {
- return stackId == PINNED_STACK_ID || stackId == DOCKED_STACK_ID;
- }
}
/**
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 136b810..bce5bf3 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -54,6 +54,7 @@
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);
// TODO: Remove this when callers have been migrated to the equivalent
// INotificationListener method.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 38a4475..67bdad5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -326,10 +326,30 @@
*/
public static final int BIND_NOT_VISIBLE = 0x40000000;
- /** Return an AssetManager instance for your application's package. */
+ /**
+ * Returns an AssetManager instance for the application's package.
+ * <p>
+ * <strong>Note:</strong> Implementations of this method should return
+ * an AssetManager instance that is consistent with the Resources instance
+ * returned by {@link #getResources()}. For example, they should share the
+ * same {@link Configuration} object.
+ *
+ * @return an AssetManager instance for the application's package
+ * @see #getResources()
+ */
public abstract AssetManager getAssets();
- /** Return a Resources instance for your application's package. */
+ /**
+ * Returns a Resources instance for the application's package.
+ * <p>
+ * <strong>Note:</strong> Implementations of this method should return
+ * a Resources instance that is consistent with the AssetManager instance
+ * returned by {@link #getAssets()}. For example, they should share the
+ * same {@link Configuration} object.
+ *
+ * @return a Resources instance for the application's package
+ * @see #getAssets()
+ */
public abstract Resources getResources();
/** Return PackageManager instance to find global package information. */
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 1a3d262..c99ddc8 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -82,8 +82,7 @@
}
@Override
- public Resources getResources()
- {
+ public Resources getResources() {
return mBase.getResources();
}
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index d6d395b..3283005 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1042,12 +1042,6 @@
}
/** {@hide} */
- @SystemApi
- public void setInstallFlagsQuick() {
- installFlags |= PackageManager.INSTALL_QUICK;
- }
-
- /** {@hide} */
public void dump(IndentingPrintWriter pw) {
pw.printPair("mode", mode);
pw.printHexPair("installFlags", installFlags);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3e7deb9..40bcc7e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -457,19 +457,11 @@
/**
* Flag parameter for {@link #installPackage} to indicate that this package is
- * to be installed quickly.
- *
- * @hide
- */
- public static final int INSTALL_QUICK = 0x00000800;
-
- /**
- * Flag parameter for {@link #installPackage} to indicate that this package is
* to be installed as a lightweight "ephemeral" app.
*
* @hide
*/
- public static final int INSTALL_EPHEMERAL = 0x00001000;
+ public static final int INSTALL_EPHEMERAL = 0x00000800;
/**
* Flag parameter for
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 019ed2b..f445cf8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -625,9 +625,7 @@
public final static int PARSE_COLLECT_CERTIFICATES = 1<<8;
public final static int PARSE_TRUSTED_OVERLAY = 1<<9;
public final static int PARSE_ENFORCE_CODE = 1<<10;
- // TODO: fix b/25118622; remove this entirely once signature processing is quick
- public final static int PARSE_SKIP_VERIFICATION = 1<<11;
- public final static int PARSE_IS_EPHEMERAL = 1<<12;
+ public final static int PARSE_IS_EPHEMERAL = 1<<11;
private static final Comparator<String> sSplitNameComparator = new SplitNameComparator();
@@ -1060,8 +1058,7 @@
/**
* Collect certificates from all the APKs described in the given package,
- * populating {@link Package#mSignatures}.
- * <p>Depending upon the parser flags, this may also asserts that all APK
+ * populating {@link Package#mSignatures}. Also asserts that all APK
* contents are signed correctly and consistently.
*/
public void collectCertificates(Package pkg, int parseFlags) throws PackageParserException {
@@ -1084,10 +1081,8 @@
final boolean hasCode = (apkFlags & ApplicationInfo.FLAG_HAS_CODE) != 0;
final boolean requireCode = ((parseFlags & PARSE_ENFORCE_CODE) != 0) && hasCode;
final String apkPath = apkFile.getAbsolutePath();
- final boolean skipVerification = Build.IS_DEBUGGABLE
- && ((parseFlags & PARSE_SKIP_VERIFICATION) != 0);
- boolean codeFound = skipVerification;
+ boolean codeFound = false;
StrictJarFile jarFile = null;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "strictJarFileCtor");
@@ -1106,7 +1101,7 @@
toVerify.add(manifestEntry);
// If we're parsing an untrusted package, verify all contents
- if (!skipVerification && (parseFlags & PARSE_IS_SYSTEM) == 0) {
+ if ((parseFlags & PARSE_IS_SYSTEM) == 0) {
final Iterator<ZipEntry> i = jarFile.iterator();
while (i.hasNext()) {
final ZipEntry entry = i.next();
@@ -1150,9 +1145,6 @@
for (int i=0; i < entryCerts.length; i++) {
pkg.mSigningKeys.add(entryCerts[i][0].getPublicKey());
}
- if (skipVerification) {
- break;
- }
} else {
if (!Signature.areExactMatch(pkg.mSignatures, entrySignatures)) {
throw new PackageParserException(
@@ -1218,9 +1210,7 @@
if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) {
// TODO: factor signature related items out of Package object
final Package tempPkg = new Package(null);
- // TODO: fix b/25118622; pass in '0' for parse flags
- collectCertificates(tempPkg, apkFile, 0 /*apkFlags*/,
- flags & PARSE_SKIP_VERIFICATION);
+ collectCertificates(tempPkg, apkFile, 0 /*apkFlags*/, 0 /*flags*/);
signatures = tempPkg.mSignatures;
} else {
signatures = null;
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index cd483b1..ee7bd9a 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -32,7 +32,9 @@
private static final String TAG = "Bundle";
static final boolean DEBUG = false;
+ // Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
static final int BUNDLE_MAGIC = 0x4C444E42; // 'B' 'N' 'D' 'L'
+
static final Parcel EMPTY_PARCEL;
static {
@@ -1308,6 +1310,8 @@
* @param parcel The parcel to copy this bundle to.
*/
void writeToParcelInner(Parcel parcel, int flags) {
+ // Keep implementation in sync with writeToParcel() in
+ // frameworks/native/libs/binder/PersistableBundle.cpp.
if (mParcelledData != null) {
if (mParcelledData == EMPTY_PARCEL) {
parcel.writeInt(0);
@@ -1345,6 +1349,8 @@
* @param parcel The parcel to overwrite this bundle from.
*/
void readFromParcelInner(Parcel parcel) {
+ // Keep implementation in sync with readFromParcel() in
+ // frameworks/native/libs/binder/PersistableBundle.cpp.
int length = parcel.readInt();
readFromParcelInner(parcel, length);
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 9b68f90..2631247 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -204,6 +204,7 @@
private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE];
private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE];
+ // Keep in sync with frameworks/native/libs/binder/PersistableBundle.cpp.
private static final int VAL_NULL = -1;
private static final int VAL_STRING = 0;
private static final int VAL_INTEGER = 1;
@@ -704,6 +705,8 @@
writeInt(-1);
return;
}
+ // Keep the format of this Parcel in sync with writeToParcelInner() in
+ // frameworks/native/libs/binder/PersistableBundle.cpp.
final int N = val.size();
writeInt(N);
if (DEBUG_ARRAY_MAP) {
@@ -1370,7 +1373,13 @@
// Must be before Parcelable
writeInt(VAL_BUNDLE);
writeBundle((Bundle) v);
+ } else if (v instanceof PersistableBundle) {
+ writeInt(VAL_PERSISTABLEBUNDLE);
+ writePersistableBundle((PersistableBundle) v);
} else if (v instanceof Parcelable) {
+ // IMPOTANT: cases for classes that implement Parcelable must
+ // come before the Parcelable case, so that their specific VAL_*
+ // types will be written.
writeInt(VAL_PARCELABLE);
writeParcelable((Parcelable) v, 0);
} else if (v instanceof Short) {
@@ -1426,9 +1435,6 @@
} else if (v instanceof Byte) {
writeInt(VAL_BYTE);
writeInt((Byte) v);
- } else if (v instanceof PersistableBundle) {
- writeInt(VAL_PERSISTABLEBUNDLE);
- writePersistableBundle((PersistableBundle) v);
} else if (v instanceof Size) {
writeInt(VAL_SIZE);
writeSize((Size) v);
diff --git a/core/java/android/os/PersistableBundle.aidl b/core/java/android/os/PersistableBundle.aidl
index 5b05873..94e8607 100644
--- a/core/java/android/os/PersistableBundle.aidl
+++ b/core/java/android/os/PersistableBundle.aidl
@@ -2,19 +2,19 @@
**
** Copyright 2014, The Android Open Source Project
**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
package android.os;
-parcelable PersistableBundle;
+parcelable PersistableBundle cpp_header "binder/PersistableBundle.h";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a1e5510..9508077 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1092,6 +1092,22 @@
public static final String ACTION_HOME_SETTINGS
= "android.settings.HOME_SETTINGS";
+
+
+ /**
+ * Activity Action: Show Default apps settings.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you
+ * safeguard against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_DEFAULT_APPS_SETTINGS
+ = "android.settings.MANAGE_DEFAULT_APPS_SETTINGS";
+
/**
* Activity Action: Show notification settings.
*
@@ -5617,6 +5633,15 @@
public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
/**
+ * Names of the service component that the current user has explicitly allowed to
+ * see and change the importance of all of the user's notifications.
+ *
+ * @hide
+ */
+ public static final String ENABLED_NOTIFICATION_ASSISTANT
+ = "enabled_notification_assistant";
+
+ /**
* Names of the service components that the current user has explicitly allowed to
* see all of the user's notifications, separated by ':'.
*
diff --git a/core/java/android/service/notification/INotificationAssistant.aidl b/core/java/android/service/notification/INotificationAssistant.aidl
new file mode 100644
index 0000000..5c5f358
--- /dev/null
+++ b/core/java/android/service/notification/INotificationAssistant.aidl
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.notification;
+
+import android.service.notification.NotificationAdjustment;
+import android.service.notification.IStatusBarNotificationHolder;
+import android.service.notification.NotificationRankingUpdate;
+
+/** @hide */
+interface INotificationAssistant
+{
+ void onListenerConnected(in NotificationRankingUpdate update);
+ void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder,
+ in NotificationRankingUpdate update);
+ void onNotificationRankingUpdate(in NotificationRankingUpdate update);
+ void onListenerHintsChanged(int hints);
+ void onInterruptionFilterChanged(int interruptionFilter);
+ NotificationAdjustment onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder, int importance, boolean user);
+ void onNotificationVisibilityChanged(String key, long time, boolean visible);
+ void onNotificationClick(String key, long time);
+ void onNotificationActionClick(String key, long time, int actionIndex);
+ void onNotificationRemoved(String key, long time, int reason);
+}
\ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationAdjustment.aidl b/core/java/android/service/notification/NotificationAdjustment.aidl
new file mode 100644
index 0000000..805fe2c
--- /dev/null
+++ b/core/java/android/service/notification/NotificationAdjustment.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.notification;
+
+parcelable NotificationAdjustment;
\ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationAdjustment.java b/core/java/android/service/notification/NotificationAdjustment.java
new file mode 100644
index 0000000..c5f0db9
--- /dev/null
+++ b/core/java/android/service/notification/NotificationAdjustment.java
@@ -0,0 +1,57 @@
+package android.service.notification;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class NotificationAdjustment implements Parcelable {
+ int mImportance;
+ CharSequence mExplanation;
+ Uri mReference;
+
+ /**
+ * Create a notification importance adjustment.
+ *
+ * @param importance The final importance of the notification.
+ * @param explanation A human-readable justification for the adjustment.
+ * @param reference A reference to an external object that augments the
+ * explanation, such as a
+ * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI},
+ * or null.
+ */
+ public NotificationAdjustment(int importance, CharSequence explanation, Uri reference) {
+ mImportance = importance;
+ mExplanation = explanation;
+ mReference = reference;
+ }
+
+ private NotificationAdjustment(Parcel source) {
+ this(source.readInt(), source.readCharSequence(),
+ (Uri) source.readParcelable(NotificationAdjustment.class.getClassLoader()));
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mImportance);
+ dest.writeCharSequence(mExplanation);
+ dest.writeParcelable(mReference, 0);
+ }
+
+ public static final Parcelable.Creator<NotificationAdjustment> CREATOR
+ = new Parcelable.Creator<NotificationAdjustment>() {
+ @Override
+ public NotificationAdjustment createFromParcel(Parcel source) {
+ return new NotificationAdjustment(source);
+ }
+
+ @Override
+ public NotificationAdjustment[] newArray(int size) {
+ return new NotificationAdjustment[size];
+ }
+ };
+}
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 5d1317c..7ce5e1f 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -16,8 +16,12 @@
package android.service.notification;
+import android.annotation.SdkConstant;
import android.app.Notification;
+import android.content.Intent;
import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
/**
* A service that helps the user manage notifications by modifying the
@@ -35,6 +39,13 @@
* </service></pre>
*/
public abstract class NotificationAssistantService extends NotificationListenerService {
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE
+ = "android.service.notification.NotificationAssistantService";
+
/** Notification was canceled by the status bar reporting a click. */
public static final int REASON_DELEGATE_CLICK = 1;
@@ -74,28 +85,6 @@
/** Notification was canceled because it was an invisible member of a group. */
public static final int REASON_GROUP_OPTIMIZATION = 13;
- public class Adjustment {
- int mImportance;
- CharSequence mExplanation;
- Uri mReference;
-
- /**
- * Create a notification importance adjustment.
- *
- * @param importance The final importance of the notification.
- * @param explanation A human-readable justification for the adjustment.
- * @param reference A reference to an external object that augments the
- * explanation, such as a
- * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI},
- * or null.
- */
- public Adjustment(int importance, CharSequence explanation, Uri reference) {
- mImportance = importance;
- mExplanation = explanation;
- mReference = reference;
- }
- }
-
/**
* A notification was posted by an app. Called before alert.
*
@@ -104,7 +93,7 @@
* @param user true if the initial importance reflects an explicit user preference.
* @return an adjustment or null to take no action, within 100ms.
*/
- abstract public Adjustment onNotificationEnqueued(StatusBarNotification sbn,
+ abstract public NotificationAdjustment onNotificationEnqueued(StatusBarNotification sbn,
int importance, boolean user);
/**
@@ -161,7 +150,7 @@
* @param key the notification key
* @param adjustment the new importance with an explanation
*/
- public final void adjustImportance(String key, Adjustment adjustment)
+ public final void adjustImportance(String key, NotificationAdjustment adjustment)
{
// TODO: pack up the adjustment and send it to the NotificationManager.
}
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index fd2d5b0..d8787b4 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -77,6 +77,15 @@
private Tile mTile;
private IBinder mToken;
+ @Override
+ public void onDestroy() {
+ if (mListening) {
+ onStopListening();
+ mListening = false;
+ }
+ super.onDestroy();
+ }
+
/**
* Called when the user adds this tile to Quick Settings.
* <p/>
@@ -197,10 +206,10 @@
mTile = (Tile) msg.obj;
break;
case MSG_TILE_ADDED:
- TileService.this.onTileRemoved();
+ TileService.this.onTileAdded();
break;
case MSG_TILE_REMOVED:
- TileService.this.onTileAdded();
+ TileService.this.onTileRemoved();
break;
case MSG_STOP_LISTENING:
if (mListening) {
diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java
index c2a6a7a..051de8a 100644
--- a/core/java/android/util/StateSet.java
+++ b/core/java/android/util/StateSet.java
@@ -260,6 +260,12 @@
case R.attr.state_enabled:
sb.append("E ");
break;
+ case R.attr.state_checked:
+ sb.append("C ");
+ break;
+ case R.attr.state_activated:
+ sb.append("A ");
+ break;
}
}
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index ea0873d..4888877 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -104,11 +104,15 @@
@Override
public AssetManager getAssets() {
// Ensure we're returning assets with the correct configuration.
- return getResources().getAssets();
+ return getResourcesInternal().getAssets();
}
@Override
public Resources getResources() {
+ return getResourcesInternal();
+ }
+
+ private Resources getResourcesInternal() {
if (mResources == null) {
if (mOverrideConfiguration == null) {
mResources = super.getResources();
@@ -117,7 +121,6 @@
mResources = resContext.getResources();
}
}
-
return mResources;
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 01d1566..6aa5e2f 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -134,6 +134,25 @@
private static String TAG_SIGNATURE = "signature";
/**
+ * Reads all signatures at the current depth (within the current provider) from the XML parser.
+ */
+ private static String[] readSignatures(XmlResourceParser parser) throws IOException,
+ XmlPullParserException {
+ List<String> signatures = new ArrayList<String>();
+ int outerDepth = parser.getDepth();
+ while(XmlUtils.nextElementWithin(parser, outerDepth)) {
+ if (parser.getName().equals(TAG_SIGNATURE)) {
+ // Parse the value within the signature tag
+ String signature = parser.nextText();
+ signatures.add(signature);
+ } else {
+ Log.e(LOGTAG, "Found an element in a webview provider that is not a signature");
+ }
+ }
+ return signatures.toArray(new String[signatures.size()]);
+ }
+
+ /**
* Returns all packages declared in the framework resources as potential WebView providers.
* @hide
* */
@@ -161,9 +180,9 @@
throw new MissingWebViewPackageException(
"WebView provider in framework resources missing description");
}
- String signature = parser.getAttributeValue(null, TAG_SIGNATURE);
webViewProviders.add(
- new WebViewProviderInfo(packageName, description, signature));
+ new WebViewProviderInfo(packageName, description,
+ readSignatures(parser)));
}
else {
Log.e(LOGTAG, "Found an element that is not a webview provider");
diff --git a/core/java/android/webkit/WebViewProviderInfo.java b/core/java/android/webkit/WebViewProviderInfo.java
index d5e3a230..7bad652 100644
--- a/core/java/android/webkit/WebViewProviderInfo.java
+++ b/core/java/android/webkit/WebViewProviderInfo.java
@@ -40,10 +40,10 @@
public WebViewPackageNotFoundException(Exception e) { super(e); }
}
- public WebViewProviderInfo(String packageName, String description, String signature) {
+ public WebViewProviderInfo(String packageName, String description, String[] signatures) {
this.packageName = packageName;
this.description = description;
- this.signature = signature;
+ this.signatures = signatures;
}
private boolean hasValidSignature() {
@@ -53,7 +53,7 @@
try {
// If no signature is declared, instead check whether the package is included in the
// system.
- if (signature == null)
+ if (signatures == null || signatures.length == 0)
return getPackageInfo().applicationInfo.isSystemApp();
packageSignatures = getPackageInfo().signatures;
@@ -62,8 +62,15 @@
}
if (packageSignatures.length != 1)
return false;
- final byte[] releaseSignature = Base64.decode(signature, Base64.DEFAULT);
- return Arrays.equals(releaseSignature, packageSignatures[0].toByteArray());
+
+ final byte[] packageSignature = packageSignatures[0].toByteArray();
+ // Return whether the package signature matches any of the valid signatures
+ for (String signature : signatures) {
+ final byte[] validSignature = Base64.decode(signature, Base64.DEFAULT);
+ if (Arrays.equals(packageSignature, validSignature))
+ return true;
+ }
+ return false;
}
/**
@@ -109,7 +116,7 @@
private WebViewProviderInfo(Parcel in) {
packageName = in.readString();
description = in.readString();
- signature = in.readString();
+ signatures = in.createStringArray();
packageInfo = null;
}
@@ -122,14 +129,14 @@
public void writeToParcel(Parcel out, int flags) {
out.writeString(packageName);
out.writeString(description);
- out.writeString(signature);
+ out.writeStringArray(signatures);
}
// fields read from framework resource
public String packageName;
public String description;
- private String signature;
+ private String[] signatures;
private PackageInfo packageInfo;
// flags declaring we want extra info from the package manager
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ad939be..f6e6186 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -359,7 +359,6 @@
final int count = getVirtualChildCount();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -388,7 +387,7 @@
*/
private View getLastNonGoneChild() {
for (int i = getVirtualChildCount() - 1; i >= 0; i--) {
- View child = getVirtualChildAt(i);
+ final View child = getVirtualChildAt(i);
if (child != null && child.getVisibility() != GONE) {
return child;
}
@@ -401,7 +400,6 @@
final boolean isLayoutRtl = isLayoutRtl();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -588,8 +586,9 @@
* for an example.</p>
*
* @param index the child's index
- * @return the child at the specified index
+ * @return the child at the specified index, may be {@code null}
*/
+ @Nullable
View getVirtualChildAt(int index) {
return getChildAt(index);
}
@@ -670,7 +669,7 @@
*/
private boolean allViewsAreGoneBefore(int childIndex) {
for (int i = childIndex - 1; i >= 0; i--) {
- View child = getVirtualChildAt(i);
+ final View child = getVirtualChildAt(i);
if (child != null && child.getVisibility() != GONE) {
return false;
}
@@ -715,7 +714,6 @@
// See how tall everyone is. Also remember max width.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -837,7 +835,6 @@
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -943,7 +940,6 @@
if (useLargestChild && heightMode != MeasureSpec.EXACTLY) {
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
@@ -986,7 +982,7 @@
MeasureSpec.EXACTLY);
for (int i = 0; i< count; ++i) {
final View child = getVirtualChildAt(i);
- if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
LinearLayout.LayoutParams lp = ((LinearLayout.LayoutParams)child.getLayoutParams());
if (lp.width == LayoutParams.MATCH_PARENT) {
@@ -1053,7 +1049,6 @@
// See how wide everyone is. Also remember max height.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -1211,7 +1206,6 @@
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -1357,7 +1351,6 @@
if (useLargestChild && widthMode != MeasureSpec.EXACTLY) {
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
@@ -1402,7 +1395,7 @@
MeasureSpec.EXACTLY);
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
- if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
if (lp.height == LayoutParams.MATCH_PARENT) {
@@ -1662,9 +1655,8 @@
}
for (int i = 0; i < count; i++) {
- int childIndex = start + dir * i;
+ final int childIndex = start + dir * i;
final View child = getVirtualChildAt(childIndex);
-
if (child == null) {
childLeft += measureNullChild(childIndex);
} else if (child.getVisibility() != GONE) {
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index f7f9c91..22931fc 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -98,7 +98,7 @@
* {@hide}
*/
void setColumnCollapsed(int columnIndex, boolean collapsed) {
- View child = getVirtualChildAt(columnIndex);
+ final View child = getVirtualChildAt(columnIndex);
if (child != null) {
child.setVisibility(collapsed ? GONE : VISIBLE);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 89888f0..d46c6f9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -394,7 +394,17 @@
mOverride = false;
}
- public void resolveWithLayoutDirection(int layoutDirection) {
+ /**
+ * Updates the list of displayed drawables to account for the current
+ * layout direction.
+ *
+ * @param layoutDirection the current layout direction
+ * @return {@code true} if the displayed drawables changed
+ */
+ public boolean resolveWithLayoutDirection(int layoutDirection) {
+ final Drawable previousLeft = mShowing[Drawables.LEFT];
+ final Drawable previousRight = mShowing[Drawables.RIGHT];
+
// First reset "left" and "right" drawables to their initial values
mShowing[Drawables.LEFT] = mDrawableLeftInitial;
mShowing[Drawables.RIGHT] = mDrawableRightInitial;
@@ -442,16 +452,11 @@
break;
}
}
- applyErrorDrawableIfNeeded(layoutDirection);
- updateDrawablesLayoutDirection(layoutDirection);
- }
- private void updateDrawablesLayoutDirection(int layoutDirection) {
- for (Drawable dr : mShowing) {
- if (dr != null) {
- dr.setLayoutDirection(layoutDirection);
- }
- }
+ applyErrorDrawableIfNeeded(layoutDirection);
+
+ return mShowing[Drawables.LEFT] != previousLeft
+ || mShowing[Drawables.RIGHT] != previousRight;
}
public void setErrorDrawable(Drawable dr, TextView tv) {
@@ -9846,7 +9851,30 @@
// Resolve drawables
if (mDrawables != null) {
- mDrawables.resolveWithLayoutDirection(layoutDirection);
+ if (mDrawables.resolveWithLayoutDirection(layoutDirection)) {
+ prepareDrawableForDisplay(mDrawables.mShowing[Drawables.LEFT]);
+ prepareDrawableForDisplay(mDrawables.mShowing[Drawables.RIGHT]);
+ applyCompoundDrawableTint();
+ }
+ }
+ }
+
+ /**
+ * Prepares a drawable for display by propagating layout direction and
+ * drawable state.
+ *
+ * @param dr the drawable to prepare
+ */
+ private void prepareDrawableForDisplay(@Nullable Drawable dr) {
+ if (dr == null) {
+ return;
+ }
+
+ dr.setLayoutDirection(getLayoutDirection());
+
+ if (dr.isStateful()) {
+ dr.setState(getDrawableState());
+ dr.jumpToCurrentState();
}
}
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 9b41eb3..d2c99fd 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -27,7 +27,13 @@
#include <SkBitmap.h>
#include <SkRegion.h>
+#if HWUI_NEW_OPS
+#include <RecordingCanvas.h>
+typedef android::uirenderer::RecordingCanvas canvas_t;
+#else
#include <DisplayListCanvas.h>
+typedef android::uirenderer::DisplayListCanvas canvas_t;
+#endif
#include <Rect.h>
#include <RenderNode.h>
#include <CanvasProperty.h>
@@ -46,7 +52,7 @@
static void android_view_DisplayListCanvas_insertReorderBarrier(JNIEnv* env, jobject clazz,
jlong canvasPtr, jboolean reorderEnable) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
canvas->insertReorderBarrier(reorderEnable);
}
@@ -56,7 +62,7 @@
static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong functorPtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
Functor* functor = reinterpret_cast<Functor*>(functorPtr);
canvas->callDrawGLFunction(functor);
}
@@ -80,7 +86,7 @@
static void android_view_DisplayListCanvas_drawRoundRectProps(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong leftPropPtr, jlong topPropPtr, jlong rightPropPtr,
jlong bottomPropPtr, jlong rxPropPtr, jlong ryPropPtr, jlong paintPropPtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
CanvasPropertyPrimitive* leftProp = reinterpret_cast<CanvasPropertyPrimitive*>(leftPropPtr);
CanvasPropertyPrimitive* topProp = reinterpret_cast<CanvasPropertyPrimitive*>(topPropPtr);
CanvasPropertyPrimitive* rightProp = reinterpret_cast<CanvasPropertyPrimitive*>(rightPropPtr);
@@ -93,7 +99,7 @@
static void android_view_DisplayListCanvas_drawCircleProps(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong xPropPtr, jlong yPropPtr, jlong radiusPropPtr, jlong paintPropPtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
@@ -107,25 +113,25 @@
static jlong android_view_DisplayListCanvas_finishRecording(JNIEnv* env,
jobject clazz, jlong canvasPtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
return reinterpret_cast<jlong>(canvas->finishRecording());
}
static jlong android_view_DisplayListCanvas_createDisplayListCanvas(JNIEnv* env, jobject clazz,
jint width, jint height) {
- return reinterpret_cast<jlong>(new DisplayListCanvas(width, height));
+ return reinterpret_cast<jlong>(new canvas_t(width, height));
}
static void android_view_DisplayListCanvas_resetDisplayListCanvas(JNIEnv* env, jobject clazz,
jlong canvasPtr, jint width, jint height) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
canvas->reset(width, height);
}
static void android_view_DisplayListCanvas_drawRenderNode(JNIEnv* env,
jobject clazz, jlong canvasPtr, jlong renderNodePtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
canvas->drawRenderNode(renderNode);
}
@@ -136,7 +142,7 @@
static void android_view_DisplayListCanvas_drawLayer(JNIEnv* env, jobject clazz,
jlong canvasPtr, jlong layerPtr) {
- DisplayListCanvas* canvas = reinterpret_cast<DisplayListCanvas*>(canvasPtr);
+ canvas_t* canvas = reinterpret_cast<canvas_t*>(canvasPtr);
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
canvas->drawLayer(layer);
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f726860..4843879 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3078,6 +3078,9 @@
<string name="notification_listener_binding_label">Notification listener</string>
<!-- Label to show for a service that is running because it is providing conditions. -->
<string name="condition_provider_service_binding_label">Condition provider</string>
+ <!-- Label to show for a service that is running because it is observing and modifying the
+ importance of the user's notifications. -->
+ <string name="notification_assistant_binding_label">Notification assistant</string>
<!-- Do Not Translate: Alternate eri.xml -->
<string name="alternate_eri_file">/data/eri.xml</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 9a4016b..937d83d 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1235,7 +1235,7 @@
<item name="subtitleTextAppearance">@style/TextAppearance.Widget.Toolbar.Subtitle</item>
<item name="minHeight">?attr/actionBarSize</item>
<item name="titleMargin">4dp</item>
- <item name="maxButtonHeight">56dp</item>
+ <item name="maxButtonHeight">@dimen/action_bar_default_height_material</item>
<item name="buttonGravity">top</item>
<item name="navigationButtonStyle">@style/Widget.Toolbar.Button.Navigation</item>
<item name="collapseIcon">?attr/homeAsUpIndicator</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 640f90b..f257f14 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1810,6 +1810,7 @@
<java-symbol type="string" name="low_internal_storage_view_title" />
<java-symbol type="string" name="notification_listener_binding_label" />
<java-symbol type="string" name="condition_provider_service_binding_label" />
+ <java-symbol type="string" name="notification_assistant_binding_label" />
<java-symbol type="string" name="report" />
<java-symbol type="string" name="select_input_method" />
<java-symbol type="string" name="select_keyboard_layout_notification_title" />
diff --git a/core/res/res/xml/config_webview_packages.xml b/core/res/res/xml/config_webview_packages.xml
index 6f9c58d..fd443c1 100644
--- a/core/res/res/xml/config_webview_packages.xml
+++ b/core/res/res/xml/config_webview_packages.xml
@@ -16,5 +16,6 @@
<webviewproviders>
<!-- The default WebView implementation -->
- <webviewprovider description="Android WebView" packageName="com.android.webview" />
+ <webviewprovider description="Android WebView" packageName="com.android.webview">
+ </webviewprovider>
</webviewproviders>
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 48cc91a..470f9ec 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -39,7 +39,7 @@
class DeferredLayerUpdater;
struct RecordedOp;
-class RecordingCanvas: public Canvas, public CanvasStateClient {
+class ANDROID_API RecordingCanvas: public Canvas, public CanvasStateClient {
enum class DeferredBarrierType {
None,
InOrder,
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 8cc79a4c..5e634a4 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -40,7 +40,7 @@
<activity
android:name=".DownloadsActivity"
- android:theme="@style/DocumentsFullScreenTheme"
+ android:theme="@style/DocumentsTheme"
android:label="@string/downloads_label"
android:icon="@drawable/ic_doc_text">
<intent-filter>
@@ -64,7 +64,7 @@
<activity
android:name=".FilesActivity"
- android:theme="@style/DocumentsFullScreenTheme"
+ android:theme="@style/DocumentsTheme"
android:icon="@drawable/ic_files_app"
android:label="@string/files_label"
android:documentLaunchMode="intoExisting">
diff --git a/packages/DocumentsUI/res/values-sw720dp/dimens.xml b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
index f393d88..83ceb55 100644
--- a/packages/DocumentsUI/res/values-sw720dp/dimens.xml
+++ b/packages/DocumentsUI/res/values-sw720dp/dimens.xml
@@ -15,10 +15,6 @@
-->
<resources>
- <bool name="show_as_dialog">true</bool>
-
- <item type="dimen" name="dialog_width">85%</item>
-
<dimen name="grid_padding_horiz">16dp</dimen>
<dimen name="grid_padding_vert">16dp</dimen>
diff --git a/packages/DocumentsUI/res/values-sw720dp/layouts.xml b/packages/DocumentsUI/res/values-sw720dp/layouts.xml
deleted file mode 100644
index 7d28f9c..0000000
--- a/packages/DocumentsUI/res/values-sw720dp/layouts.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item name="docs_activity" type="layout">@layout/fixed_layout</item>
-</resources>
diff --git a/packages/DocumentsUI/res/values-sw720dp/styles.xml b/packages/DocumentsUI/res/values-sw720dp/styles.xml
deleted file mode 100644
index a8dcbb0..0000000
--- a/packages/DocumentsUI/res/values-sw720dp/styles.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
-
- <style name="DocumentsBaseTheme" parent="@style/Theme.AppCompat.Light.Dialog">
- <!-- We do not specify width of window here because the max size of
- floating window specified by windowFixedWidthis is limited. -->
- <item name="*android:windowFixedHeightMajor">80%</item>
- <item name="*android:windowFixedHeightMinor">90%</item>
- </style>
-
-</resources>
diff --git a/packages/DocumentsUI/res/values/attrs.xml b/packages/DocumentsUI/res/values/attrs.xml
index 0afc3a2..9e13001 100644
--- a/packages/DocumentsUI/res/values/attrs.xml
+++ b/packages/DocumentsUI/res/values/attrs.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<resources>
- <declare-styleable name="DocumentsBaseTheme">
+ <declare-styleable name="DocumentsTheme">
<attr name="colorActionMode" format="color"/>
</declare-styleable>
</resources>
diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml
index f94a00e..060871d 100644
--- a/packages/DocumentsUI/res/values/dimens.xml
+++ b/packages/DocumentsUI/res/values/dimens.xml
@@ -35,7 +35,6 @@
<dimen name="list_divider_inset">72dp</dimen>
<bool name="list_divider_inset_left">true</bool>
- <bool name="show_as_dialog">false</bool>
<bool name="always_show_summary">false</bool>
<dimen name="dir_elevation">8dp</dimen>
diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml
index 6712e2d..d14631d 100644
--- a/packages/DocumentsUI/res/values/styles.xml
+++ b/packages/DocumentsUI/res/values/styles.xml
@@ -16,31 +16,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
- <style name="DocumentsBaseTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar" />
<style name="ActionBarTheme" parent="@*android:style/ThemeOverlay.Material.Dark.ActionBar" />
<style name="ActionBarPopupTheme" parent="@*android:style/ThemeOverlay.Material.Light" />
- <style name="DocumentsTheme" parent="@style/DocumentsBaseTheme">
- <item name="actionBarWidgetTheme">@null</item>
- <item name="actionBarTheme">@style/ActionBarTheme</item>
- <item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
-
- <item name="android:windowBackground">@color/window_background</item>
- <item name="android:colorPrimaryDark">@color/primary_dark</item>
- <item name="android:colorPrimary">@color/primary</item>
- <item name="android:colorAccent">@color/accent</item>
- <item name="colorActionMode">@color/action_mode</item>
-
- <item name="android:listDivider">@*android:drawable/list_divider_material</item>
-
- <item name="android:windowActionBar">false</item>
- <item name="android:windowActionModeOverlay">true</item>
- <item name="android:windowNoTitle">true</item>
-
- <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
- </style>
-
- <style name="DocumentsFullScreenTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
+ <style name="DocumentsTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ActionBarTheme</item>
<item name="actionBarPopupTheme">@style/ActionBarPopupTheme</item>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 313d303..8ca2cfb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -34,7 +34,6 @@
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
-import android.graphics.Point;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -45,7 +44,6 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.Spinner;
import android.widget.Toolbar;
@@ -64,8 +62,6 @@
private static final int CODE_FORWARD = 42;
private static final String TAG = "DocumentsActivity";
- private boolean mShowAsDialog;
-
private Toolbar mToolbar;
private Spinner mToolbarStack;
@@ -83,29 +79,8 @@
super.onCreate(icicle);
final Resources res = getResources();
- mShowAsDialog = res.getBoolean(R.bool.show_as_dialog);
- if (!mShowAsDialog) {
- setTheme(R.style.DocumentsFullScreenTheme);
- }
-
- if (mShowAsDialog) {
- mDrawer = DrawerController.createDummy();
-
- // Strongly define our horizontal dimension; we leave vertical as
- // WRAP_CONTENT so that system resizes us when IME is showing.
- final WindowManager.LayoutParams a = getWindow().getAttributes();
-
- final Point size = new Point();
- getWindowManager().getDefaultDisplay().getSize(size);
- a.width = (int) res.getFraction(R.dimen.dialog_width, size.x, size.x);
-
- getWindow().setAttributes(a);
-
- } else {
- mDrawer = DrawerController.create(this);
- }
-
+ mDrawer = DrawerController.create(this);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mStackAdapter = new StackAdapter();
@@ -267,15 +242,16 @@
}
}
- if (!mShowAsDialog && mDrawer.isUnlocked()) {
+ if (mDrawer.isUnlocked()) {
mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
mToolbar.setNavigationContentDescription(R.string.drawer_open);
- mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- setRootsDrawerOpen(true);
- }
- });
+ mToolbar.setNavigationOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setRootsDrawerOpen(true);
+ }
+ });
} else {
mToolbar.setNavigationIcon(null);
mToolbar.setNavigationContentDescription(R.string.drawer_open);
@@ -306,10 +282,7 @@
public boolean onCreateOptionsMenu(Menu menu) {
boolean showMenu = super.onCreateOptionsMenu(menu);
- // Most actions are visible when showing as dialog
- if (mShowAsDialog) {
- expandMenus(menu);
- }
+ expandMenus(menu);
return showMenu;
}
diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml
index c9dbc79..f15c97e 100644
--- a/packages/SystemUI/res/layout/notification_guts.xml
+++ b/packages/SystemUI/res/layout/notification_guts.xml
@@ -24,35 +24,23 @@
android:clickable="true"
android:gravity="top|start"
android:orientation="vertical"
- android:paddingEnd="8dp"
+ android:paddingStart="@*android:dimen/notification_content_margin_start"
+ android:paddingEnd="@*android:dimen/notification_content_margin_end"
android:background="@color/notification_guts_text_color" >
<!-- header -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="@*android:dimen/notification_content_margin_start"
- android:paddingTop="8dp"
- android:paddingBottom="16dp" >
+ android:paddingBottom="8dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/notification_guts_header"
- android:orientation="vertical"
+ android:orientation="horizontal"
android:layout_gravity="center_vertical|start"
android:layout_marginEnd="52dp">
-
- <LinearLayout
- android:id="@+id/notification_guts_app_details"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:layout_gravity="start|top"
- android:gravity="center_vertical"
- >
-
<ImageView
android:id="@android:id/icon"
android:layout_width="18dp"
@@ -76,22 +64,12 @@
android:layout_gravity="bottom|start"
android:visibility="gone"
android:textColor="#ffffff" />
- </LinearLayout>
-
- <TextView
- android:id="@+id/topic_details"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
- android:textColor="@color/notification_guts_text_color"
- android:layout_alignParentBottom="true"
- android:layout_alignParentStart="true" />
- </LinearLayout>
+ </LinearLayout>
<ImageButton style="@android:style/Widget.Material.Light.Button.Borderless.Small"
android:id="@+id/notification_inspect_item"
android:layout_width="52dp"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center"
android:layout_gravity="center_vertical|end"
@@ -103,7 +81,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
- android:paddingStart="@*android:dimen/notification_content_margin_start"
android:orientation="vertical"
android:clickable="false"
android:focusable="false"
@@ -116,8 +93,7 @@
android:textAppearance="@android:style/TextAppearance.Material.Subhead"
android:textColor="@color/notification_guts_text_color"
android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:text="@*android:string/notification_importance_title"/>
+ android:fadingEdge="horizontal"/>
<TextView
android:id="@+id/summary"
@@ -133,7 +109,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="6dp" >
+ android:paddingTop="8dp" >
<ImageView
android:id="@+id/low_importance"
@@ -162,5 +138,21 @@
android:layout_height="24dp"/>
</FrameLayout>
+
+ <RadioGroup android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp">
+ <RadioButton android:id="@+id/apply_to_topic"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/notification_guts_text_color"
+ android:visibility="gone"/>
+ <RadioButton android:id="@+id/apply_to_app"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/apply_to_app"
+ android:textColor="@color/notification_guts_text_color"
+ android:visibility="gone"/>
+ </RadioGroup>
</LinearLayout>
</com.android.systemui.statusbar.NotificationGuts>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f71a71a..50e0661 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1201,4 +1201,34 @@
<!-- Bluetooth enablement ok text [CHAR LIMIT=40] -->
<string name="enable_bluetooth_confirmation_ok">Turn on</string>
+ <!-- Apply notification importance setting to a topic [CHAR LIMIT=NONE] -->
+ <string name="apply_to_topic">Apply to <xliff:g id="topic_name" example="Friend Request">%1$s</xliff:g> notifications</string>
+ <!-- Apply notification importance setting to an app [CHAR LIMIT=NONE] -->
+ <string name="apply_to_app">Apply to all notifications from this app</string>
+ <!-- Notification importance title, blocked status-->
+ <string name="blocked_importance">Blocked</string>
+ <!-- Notification importance title, low status-->
+ <string name="low_importance">Low importance</string>
+ <!-- Notification importance title, normal status-->
+ <string name="default_importance">Normal importance</string>
+ <!-- Notification importance title, high status-->
+ <string name="high_importance">High importance</string>
+ <!-- Notification importance title, max status-->
+ <string name="max_importance">Urgent importance</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: blocked importance level description -->
+ <string name="notification_importance_blocked">Never show these notifications</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: low importance level description -->
+ <string name="notification_importance_low">Silently show at the bottom of the notification list</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: normal importance level description -->
+ <string name="notification_importance_default">Silently show these notifications</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: high importance level description -->
+ <string name="notification_importance_high">Show at the top of the notifications list and make sound</string>
+
+ <!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
+ <string name="notification_importance_max">Peek onto the screen and make sound</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 6d4dc872..b891c21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -947,7 +947,7 @@
final StatusBarNotification sbn = row.getStatusBarNotification();
PackageManager pmUser = getPackageManagerForUser(mContext, sbn.getUser().getIdentifier());
row.setTag(sbn.getPackageName());
- final View guts = row.getGuts();
+ final NotificationGuts guts = row.getGuts();
final String pkg = sbn.getPackageName();
String appname = pkg;
Drawable pkgicon = null;
@@ -969,8 +969,6 @@
((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(pkgicon);
((TextView) row.findViewById(R.id.pkgname)).setText(appname);
- bindTopicImportance(sbn, row);
-
final View settingsButton = guts.findViewById(R.id.notification_inspect_item);
if (appUid >= 0) {
final int appUidF = appUid;
@@ -983,69 +981,8 @@
} else {
settingsButton.setVisibility(View.GONE);
}
- }
- private void bindTopicImportance(final StatusBarNotification sbn,
- ExpandableNotificationRow row) {
- final INotificationManager sINM = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- final Notification.Topic topic = sbn.getNotification().getTopic() == null
- ? new Notification.Topic(Notification.TOPIC_DEFAULT, mContext.getString(
- com.android.internal.R.string.default_notification_topic_label))
- : sbn.getNotification().getTopic();
-
- ((TextView) row.findViewById(R.id.topic_details)).setText(topic.getLabel());
- final TextView topicSummary = ((TextView) row.findViewById(R.id.summary));
- int importance = mNotificationData.getImportance(sbn.getKey());
- SeekBar seekBar = (SeekBar) row.findViewById(R.id.seekbar);
- seekBar.setMax(4);
- seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- topicSummary.setText(getProgressSummary(progress));
- if (fromUser) {
- try {
- sINM.setTopicImportance(sbn.getPackageName(), sbn.getUid(), topic,
- progress);
- } catch (RemoteException e) {
- // :(
- }
- }
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- // no-op
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- // no-op
- }
-
- private String getProgressSummary(int progress) {
- switch (progress) {
- case NotificationListenerService.Ranking.IMPORTANCE_NONE:
- return mContext.getString(
- com.android.internal.R.string.notification_importance_blocked);
- case NotificationListenerService.Ranking.IMPORTANCE_LOW:
- return mContext.getString(
- com.android.internal.R.string.notification_importance_low);
- case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
- return mContext.getString(
- com.android.internal.R.string.notification_importance_default);
- case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
- return mContext.getString(
- com.android.internal.R.string.notification_importance_high);
- case NotificationListenerService.Ranking.IMPORTANCE_MAX:
- return mContext.getString(
- com.android.internal.R.string.notification_importance_max);
- default:
- return "";
- }
- }
- });
- seekBar.setProgress(importance);
+ guts.bindImportance(sbn, row, mNotificationData.getImportance(sbn.getKey()));
}
protected SwipeHelper.LongPressListener getNotificationLongClicker() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 0081496..57db80a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -16,12 +16,22 @@
package com.android.systemui.statusbar;
+import android.app.INotificationManager;
+import android.app.Notification;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.SeekBar;
+import android.widget.TextView;
import com.android.systemui.R;
@@ -83,6 +93,88 @@
}
}
+ void bindImportance(final StatusBarNotification sbn, final ExpandableNotificationRow row,
+ final int importance) {
+ final INotificationManager sINM = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ final Notification.Topic topic = sbn.getNotification().getTopic() == null
+ ? new Notification.Topic(Notification.TOPIC_DEFAULT, mContext.getString(
+ com.android.internal.R.string.default_notification_topic_label))
+ : sbn.getNotification().getTopic();
+
+ final RadioButton applyToTopic = (RadioButton) row.findViewById(R.id.apply_to_topic);
+ if (sbn.getNotification().getTopic() != null) {
+ applyToTopic.setVisibility(View.VISIBLE);
+ applyToTopic.setChecked(true);
+ applyToTopic.setText(mContext.getString(R.string.apply_to_topic, topic.getLabel()));
+ row.findViewById(R.id.apply_to_app).setVisibility(View.VISIBLE);
+ }
+
+ final TextView topicSummary = ((TextView) row.findViewById(R.id.summary));
+ final TextView topicTitle = ((TextView) row.findViewById(R.id.title));
+ SeekBar seekBar = (SeekBar) row.findViewById(R.id.seekbar);
+ seekBar.setMax(4);
+ seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ updateTitleAndSummary(progress);
+ if (fromUser) {
+ try {
+ if (applyToTopic.isChecked()) {
+ sINM.setTopicImportance(sbn.getPackageName(), sbn.getUid(), topic,
+ progress);
+ } else {
+ sINM.setAppImportance(sbn.getPackageName(), sbn.getUid(), progress);
+ }
+ } catch (RemoteException e) {
+ // :(
+ }
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // no-op
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // no-op
+ }
+
+ private void updateTitleAndSummary(int progress) {
+ switch (progress) {
+ case NotificationListenerService.Ranking.IMPORTANCE_NONE:
+ topicSummary.setText(mContext.getString(
+ R.string.notification_importance_blocked));
+ topicTitle.setText(mContext.getString(R.string.blocked_importance));
+ break;
+ case NotificationListenerService.Ranking.IMPORTANCE_LOW:
+ topicSummary.setText(mContext.getString(
+ R.string.notification_importance_low));
+ topicTitle.setText(mContext.getString(R.string.low_importance));
+ break;
+ case NotificationListenerService.Ranking.IMPORTANCE_DEFAULT:
+ topicSummary.setText(mContext.getString(
+ R.string.notification_importance_default));
+ topicTitle.setText(mContext.getString(R.string.default_importance));
+ break;
+ case NotificationListenerService.Ranking.IMPORTANCE_HIGH:
+ topicSummary.setText(mContext.getString(
+ R.string.notification_importance_high));
+ topicTitle.setText(mContext.getString(R.string.high_importance));
+ break;
+ case NotificationListenerService.Ranking.IMPORTANCE_MAX:
+ topicSummary.setText(mContext.getString(
+ R.string.notification_importance_max));
+ topicTitle.setText(mContext.getString(R.string.max_importance));
+ break;
+ }
+ }
+ });
+ seekBar.setProgress(importance);
+ }
+
public void setActualHeight(int actualHeight) {
mActualHeight = actualHeight;
invalidate();
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index df18d3e..946b233 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -16,6 +16,7 @@
package com.android.server.appwidget;
+import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppGlobals;
import android.app.AppOpsManager;
@@ -76,6 +77,7 @@
import android.view.WindowManager;
import android.widget.RemoteViews;
+import com.android.internal.R;
import com.android.internal.appwidget.IAppWidgetHost;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
@@ -83,7 +85,6 @@
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
-import com.android.internal.R;
import com.android.server.LocalServices;
import com.android.server.WidgetBackupProvider;
@@ -139,8 +140,10 @@
private static final int CURRENT_VERSION = 1;
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
+ final String action = intent.getAction();
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
if (DEBUG) {
Slog.i(TAG, "Received broadcast: " + action);
@@ -148,23 +151,16 @@
if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
onConfigurationChanged();
- } else if (Intent.ACTION_USER_STARTED.equals(action)) {
- onUserStarted(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL));
+ } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+ onUserUnlocked(userId);
} else if (Intent.ACTION_USER_STOPPED.equals(action)) {
- onUserStopped(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL));
+ onUserStopped(userId);
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- refreshProfileWidgetsMaskedState(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- UserHandle.USER_NULL));
+ refreshProfileWidgetsMaskedState(userId);
} else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
- UserHandle profile = (UserHandle)intent.getParcelableExtra(Intent.EXTRA_USER);
- if (profile != null) {
- refreshWidgetMaskedState(profile.getIdentifier());
- }
+ refreshWidgetMaskedState(userId);
} else {
- onPackageBroadcastReceived(intent, intent.getIntExtra(
- Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL));
+ onPackageBroadcastReceived(intent, userId);
}
}
};
@@ -263,7 +259,7 @@
sdFilter, null, null);
IntentFilter userFilter = new IntentFilter();
- userFilter.addAction(Intent.ACTION_USER_STARTED);
+ userFilter.addAction(Intent.ACTION_USER_UNLOCKED);
userFilter.addAction(Intent.ACTION_USER_STOPPED);
userFilter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
@@ -340,6 +336,8 @@
}
private void onPackageBroadcastReceived(Intent intent, int userId) {
+ if (!isUserRunningAndUnlocked(userId)) return;
+
final String action = intent.getAction();
boolean added = false;
boolean changed = false;
@@ -419,9 +417,7 @@
* Refresh the masked state for all profiles under the given user.
*/
private void refreshProfileWidgetsMaskedState(int userId) {
- if (userId == UserHandle.USER_NULL) {
- return;
- }
+ if (!isUserRunningAndUnlocked(userId)) return;
List<UserInfo> profiles = mUserManager.getEnabledProfiles(userId);
if (profiles != null) {
for (int i = 0; i < profiles.size(); i++) {
@@ -435,6 +431,7 @@
* Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
*/
private void refreshWidgetMaskedState(int profileId) {
+ if (!isUserRunningAndUnlocked(profileId)) return;
final long identity = Binder.clearCallingIdentity();
try {
UserInfo user = mUserManager.getUserInfo(profileId);
@@ -484,6 +481,11 @@
}
private void ensureGroupStateLoadedLocked(int userId) {
+ if (!isUserRunningAndUnlocked(userId)) {
+ throw new IllegalStateException(
+ "User " + userId + " must be unlocked for widgets to be available");
+ }
+
final int[] profileIds = mSecurityPolicy.getEnabledGroupProfileIds(userId);
// Careful lad, we may have already loaded the state for some
@@ -2321,7 +2323,7 @@
}
}
- private void onUserStarted(int userId) {
+ private void onUserUnlocked(int userId) {
synchronized (mLock) {
ensureGroupStateLoadedLocked(userId);
@@ -2510,6 +2512,15 @@
mWidgetPackages.clear();
}
+ private boolean isUserRunningAndUnlocked(int userId) {
+ if (userId == UserHandle.USER_NULL) {
+ return false;
+ } else {
+ return mContext.getSystemService(ActivityManager.class)
+ .isUserRunningAndUnlocked(userId);
+ }
+ }
+
@Override
public boolean isBoundWidgetPackage(String packageName, int userId) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b805c10..1d555c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17061,6 +17061,8 @@
}
}
+ // Verify that protected broadcasts are only being sent by system code,
+ // and that system code is only sending protected broadcasts.
final String action = intent.getAction();
final boolean isProtectedBroadcast;
try {
@@ -17070,35 +17072,47 @@
return ActivityManager.BROADCAST_SUCCESS;
}
- /*
- * Prevent non-system code (defined here to be non-persistent
- * processes) from sending protected broadcasts.
- */
- int callingAppId = UserHandle.getAppId(callingUid);
- if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
- || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
- || callingAppId == Process.NFC_UID || callingUid == 0) {
- // Always okay.
+ final boolean isCallerSystem;
+ switch (UserHandle.getAppId(callingUid)) {
+ case Process.ROOT_UID:
+ case Process.SYSTEM_UID:
+ case Process.PHONE_UID:
+ case Process.SHELL_UID:
+ case Process.BLUETOOTH_UID:
+ case Process.NFC_UID:
+ isCallerSystem = true;
+ break;
+ default:
+ isCallerSystem = (callerApp != null) && callerApp.persistent;
+ break;
+ }
- // Yell if the system is trying to send a non-protected broadcast.
- // The vast majority of broadcasts sent from system callers should
- // be protected to avoid security holes, so exceptions here should
- // be incredibly rare.
- if (!isProtectedBroadcast
- && !Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- // TODO: eventually switch over to hard throw
+ if (isCallerSystem) {
+ if (isProtectedBroadcast
+ || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
+ || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
+ || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
+ || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
+ // Broadcast is either protected, or it's a public action that
+ // we've relaxed, so it's fine for system internals to send.
+ } else {
+ // The vast majority of broadcasts sent from system internals
+ // should be protected to avoid security holes, so yell loudly
+ // to ensure we examine these cases.
Log.wtf(TAG, "Sending non-protected broadcast " + action
+ " from system", new Throwable());
}
- } else if (callerApp == null || !callerApp.persistent) {
+ } else {
if (isProtectedBroadcast) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from pid="
+ callingPid + ", uid=" + callingUid;
Slog.w(TAG, msg);
throw new SecurityException(msg);
- } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)) {
+
+ } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
+ || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
// Special case for compatibility: we don't want apps to send this,
// but historically it has not been protected and apps may be using it
// to poke their own app widget. So, instead of making it protected,
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index d215fc6..3da0f8d 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -16,22 +16,21 @@
package com.android.server.am;
-import static com.android.server.am.ActivityManagerDebugConfig.*;
+import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_THUMBNAILS;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_THUMBNAILS;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
import android.app.ActivityManager.TaskDescription;
-import android.app.PendingIntent;
-import android.os.PersistableBundle;
-import android.os.Trace;
-
-import com.android.internal.app.ResolverActivity;
-import com.android.internal.content.ReferrerIntent;
-import com.android.internal.util.XmlUtils;
-import com.android.server.AttributeCache;
-import com.android.server.am.ActivityStack.ActivityState;
-import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
-
import android.app.ActivityOptions;
+import android.app.PendingIntent;
import android.app.ResultInfo;
import android.content.ComponentName;
import android.content.Intent;
@@ -45,9 +44,11 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
+import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.util.EventLog;
import android.util.Log;
@@ -57,9 +58,12 @@
import android.view.IApplicationToken;
import android.view.WindowManager;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
+import com.android.internal.app.ResolverActivity;
+import com.android.internal.content.ReferrerIntent;
+import com.android.internal.util.XmlUtils;
+import com.android.server.AttributeCache;
+import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import java.io.File;
import java.io.IOException;
@@ -69,6 +73,10 @@
import java.util.HashSet;
import java.util.Objects;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
/**
* An entry in the history stack, representing an activity.
*/
@@ -398,6 +406,11 @@
}
}
+ boolean isFreeform() {
+ return task != null && task.stack != null
+ && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+ }
+
static class Token extends IApplicationToken.Stub {
private final WeakReference<ActivityRecord> weakActivity;
private final ActivityManagerService mService;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bfd17b2..ada71f67 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -813,10 +813,9 @@
if (hasVisibleBehindActivity()) {
// Stop visible behind activity before going to sleep.
- final ActivityRecord r = mActivityContainer.mActivityDisplay.mVisibleBehindActivity;
+ final ActivityRecord r = getVisibleBehindActivity();
mStackSupervisor.mStoppingActivities.add(r);
- if (DEBUG_STATES) Slog.v(TAG_STATES,
- "Sleep still waiting to stop visible behind " + r);
+ if (DEBUG_STATES) Slog.v(TAG_STATES, "Sleep still waiting to stop visible behind " + r);
return true;
}
@@ -1053,7 +1052,7 @@
mHandler.removeMessages(STOP_TIMEOUT_MSG, r);
r.stopped = true;
r.state = ActivityState.STOPPED;
- if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == r) {
+ if (getVisibleBehindActivity() == r) {
mStackSupervisor.requestVisibleBehindLocked(r, false);
}
if (r.finishing) {
@@ -1214,9 +1213,9 @@
next.returningOptions = null;
- if (mActivityContainer.mActivityDisplay.mVisibleBehindActivity == next) {
+ if (getVisibleBehindActivity() == next) {
// When resuming an activity, require it to call requestVisibleBehind() again.
- mActivityContainer.mActivityDisplay.setVisibleBehindActivity(null);
+ setVisibleBehindActivity(null);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 80d531e..483293f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2260,7 +2260,8 @@
// Also put noDisplay activities in the source task. These by itself can
// be placed in any task/stack, however it could launch other activities
// like ResolverActivity, and we want those to stay in the original task.
- if (r.isResolverActivity() || r.noDisplay) {
+ if ((r.isResolverActivity() || r.noDisplay) && sourceRecord != null
+ && sourceRecord.isFreeform()) {
addingToTask = true;
}
}
@@ -5170,7 +5171,7 @@
/** All of the stacks on this display. Order matters, topmost stack is in front of all other
* stacks, bottommost behind. Accessed directly by ActivityManager package classes */
- final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
+ final ArrayList<ActivityStack> mStacks = new ArrayList<>();
ActivityRecord mVisibleBehindActivity;
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 62e78a4..e49bc3c 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -245,6 +245,7 @@
mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0));
final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED);
+ unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
unlockedIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mService.broadcastIntentLocked(null, null, unlockedIntent, null, null, 0, null,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bb07e9d..0bfbd7f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1248,6 +1248,13 @@
return mRankingHelper.getTopicImportance(pkg, uid, topic);
}
+ @Override
+ public void setAppImportance(String pkg, int uid, int importance) {
+ enforceSystemOrSystemUI("Caller not system or systemui");
+ mRankingHelper.setAppImportance(pkg, uid, importance);
+ savePolicyFile();
+ }
+
/**
* System-only API for getting a list of current (i.e. not cleared) notifications.
*
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index acdd90a..a6c9b0d 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -35,4 +35,6 @@
void setTopicImportance(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);
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 5a31c6a..32c0ce2 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -251,6 +251,7 @@
}
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATT_NAME, r.pkg);
+ out.attribute(null, ATT_IMPORTANCE, Integer.toString(r.importance));
if (!forBackup) {
out.attribute(null, ATT_UID, Integer.toString(r.uid));
@@ -426,6 +427,20 @@
updateConfig();
}
+ /**
+ * Sets the default importance for all new topics that appear in the future, and resets
+ * the importance of all current topics.
+ */
+ @Override
+ public void setAppImportance(String pkgName, int uid, int importance) {
+ final Record r = getOrCreateRecord(pkgName, uid);
+ r.importance = importance;
+ for (Topic t : r.topics.values()) {
+ t.importance = importance;
+ }
+ updateConfig();
+ }
+
private Topic getOrCreateTopic(Record r, Notification.Topic topic) {
if (topic == null) {
topic = createDefaultTopic();
@@ -435,6 +450,7 @@
return t;
} else {
t = new Topic(topic);
+ t.importance = r.importance;
r.topics.put(topic.getId(), t);
return t;
}
@@ -477,6 +493,8 @@
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));
pw.println();
for (Topic t : r.topics.values()) {
pw.print(prefix);
@@ -532,6 +550,7 @@
String pkg;
int uid = UNKNOWN_UID;
+ int importance = DEFAULT_IMPORTANCE;
Map<String, Topic> topics = new ArrayMap<>();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index fa0aa37..66d10b5 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -482,7 +482,6 @@
throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
"Failed to resolve stage location", e);
}
- final boolean quickInstall = (params.installFlags & PackageManager.INSTALL_QUICK) != 0;
// Verify that stage looks sane with respect to existing application.
// This currently only ensures packageName, versionCode, and certificate
@@ -490,10 +489,7 @@
validateInstallLocked();
Preconditions.checkNotNull(mPackageName);
- // TODO: fix b/25118622; don't bypass signature check
- if (!quickInstall) {
- Preconditions.checkNotNull(mSignatures);
- }
+ Preconditions.checkNotNull(mSignatures);
Preconditions.checkNotNull(mResolvedBaseFile);
if (!mPermissionsAccepted) {
@@ -603,7 +599,6 @@
* {@link PackageManagerService}.
*/
private void validateInstallLocked() throws PackageManagerException {
- final boolean quickInstall = (params.installFlags & PackageManager.INSTALL_QUICK) != 0;
mPackageName = null;
mVersionCode = -1;
mSignatures = null;
@@ -627,9 +622,7 @@
final ApkLite apk;
try {
- // TODO: fix b/25118622; always use PARSE_COLLECT_CERTIFICATES
- final int parseFlags = quickInstall ? 0 : PackageParser.PARSE_COLLECT_CERTIFICATES;
- apk = PackageParser.parseApkLite(file, parseFlags);
+ apk = PackageParser.parseApkLite(file, PackageParser.PARSE_COLLECT_CERTIFICATES);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
}
@@ -750,7 +743,6 @@
}
private void assertApkConsistent(String tag, ApkLite apk) throws PackageManagerException {
- final boolean quickInstall = (params.installFlags & PackageManager.INSTALL_QUICK) != 0;
if (!mPackageName.equals(apk.packageName)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package "
+ apk.packageName + " inconsistent with " + mPackageName);
@@ -760,8 +752,7 @@
+ " version code " + apk.versionCode + " inconsistent with "
+ mVersionCode);
}
- // TODO: fix b/25118622; don't bypass signature check
- if (!quickInstall && !Signature.areExactMatch(mSignatures, apk.signatures)) {
+ if (!Signature.areExactMatch(mSignatures, apk.signatures)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
tag + " signatures are inconsistent");
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 42e8b01..dfb01eb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -10426,10 +10426,6 @@
if (!DEFAULT_VERIFY_ENABLE) {
return false;
}
- // TODO: fix b/25118622; don't bypass verification
- if (Build.IS_DEBUGGABLE && (installFlags & PackageManager.INSTALL_QUICK) != 0) {
- return false;
- }
// Ephemeral apps don't get the full verification treatment
if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
if (DEBUG_EPHEMERAL) {
@@ -12792,7 +12788,6 @@
final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
|| (args.volumeUuid != null));
- final boolean quickInstall = ((installFlags & PackageManager.INSTALL_QUICK) != 0);
final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
boolean replace = false;
int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
@@ -12818,7 +12813,6 @@
| PackageParser.PARSE_ENFORCE_CODE
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
- | (quickInstall ? PackageParser.PARSE_SKIP_VERIFICATION : 0)
| (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0);
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f5da103..13f4826 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -526,6 +526,7 @@
if (parentHandle != null) {
intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED);
intent.putExtra(Intent.EXTRA_USER, profileHandle);
+ intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtras(extras);
mContext.sendBroadcastAsUser(intent, parentHandle);
@@ -2073,6 +2074,7 @@
managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
Intent.FLAG_RECEIVER_FOREGROUND);
managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
+ managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
mContext.sendBroadcastAsUser(managedProfileIntent, new UserHandle(parentUserId), null);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index ab47f07..8292997 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -223,7 +223,7 @@
}
if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
- mService.setInputMethodAnimLayerAdjustment(adj);
+ mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
}
wallpaperController.setAnimLayerAdjustment(w, adj);
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 6a5183f..62d4f36 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -782,7 +782,7 @@
SurfaceControl.openTransaction();
try {
for (int i = mService.mDisplayContents.size() - 1; i >= 0; i--) {
- DisplayContent display = mService.mDisplayContents.get(i);
+ DisplayContent display = mService.mDisplayContents.valueAt(i);
final WindowList windows = mService.getWindowListLocked(display.getDisplayId());
for (int j = windows.size() - 1; j >= 0; j--) {
windows.get(j).maybeRemoveReplacedWindow();
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
new file mode 100644
index 0000000..4a77b22
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -0,0 +1,202 @@
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.WINDOW_LAYER_MULTIPLIER;
+
+import android.app.ActivityManager.StackId;
+import android.util.Slog;
+import android.view.Display;
+
+import java.io.PrintWriter;
+
+/**
+ * Controller for assigning layers to windows on the display.
+ *
+ * This class encapsulates general algorithm for assigning layers and special rules that we need to
+ * apply on top. The general algorithm goes through windows from bottom to the top and the higher
+ * the window is, the higher layer is assigned. The final layer is equal to base layer +
+ * adjustment from the order. This means that the window list is assumed to be ordered roughly by
+ * the base layer (there are exceptions, e.g. due to keyguard and wallpaper and they need to be
+ * handled with care, because they break the algorithm).
+ *
+ * On top of the general algorithm we add special rules, that govern such amazing things as:
+ * <li>IME (which has higher base layer, but will be positioned above application windows)</li>
+ * <li>docked/pinned windows (that need to be lifted above other application windows, including
+ * animations)
+ * <li>dock divider (which needs to live above applications, but below IME)</li>
+ * <li>replaced windows, which need to live above their normal level, because they anticipate
+ * an animation</li>.
+ */
+public class WindowLayersController {
+ private final WindowManagerService mService;
+
+ private int mInputMethodAnimLayerAdjustment;
+
+ public WindowLayersController(WindowManagerService service) {
+ mService = service;
+ }
+
+ private int mHighestApplicationLayer = 0;
+ private WindowState mPinnedWindow = null;
+ private WindowState mDockedWindow = null;
+ private WindowState mDockDivider = null;
+ private WindowState mImeWindow = null;
+ private WindowState mReplacingWindow = null;
+
+ final void assignLayersLocked(WindowList windows) {
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows,
+ new RuntimeException("here").fillInStackTrace());
+
+ clear();
+ int curBaseLayer = 0;
+ int curLayer = 0;
+ boolean anyLayerChanged = false;
+ for (int i = 0, windowCount = windows.size(); i < windowCount; i++) {
+ final WindowState w = windows.get(i);
+ boolean layerChanged = false;
+
+ int oldLayer = w.mLayer;
+ if (w.mBaseLayer == curBaseLayer || w.mIsImWindow || (i > 0 && w.mIsWallpaper)) {
+ curLayer += WINDOW_LAYER_MULTIPLIER;
+ w.mLayer = curLayer;
+ } else {
+ curBaseLayer = curLayer = w.mBaseLayer;
+ w.mLayer = curLayer;
+ }
+ if (w.mLayer != oldLayer) {
+ layerChanged = true;
+ anyLayerChanged = true;
+ }
+
+ final WindowStateAnimator winAnimator = w.mWinAnimator;
+ oldLayer = winAnimator.mAnimLayer;
+ winAnimator.mAnimLayer = w.mLayer + w.getAnimLayerAdjustment() +
+ getSpecialWindowAnimLayerAdjustment(w);
+ if (winAnimator.mAnimLayer != oldLayer) {
+ layerChanged = true;
+ anyLayerChanged = true;
+ }
+
+ if (w.mAppToken != null) {
+ mHighestApplicationLayer = Math.max(mHighestApplicationLayer,
+ winAnimator.mAnimLayer);
+ }
+ collectSpecialWindows(w);
+
+ if (layerChanged) {
+ w.scheduleAnimationIfDimming();
+ }
+ }
+
+ adjustSpecialWindows();
+
+ //TODO (multidisplay): Magnification is supported only for the default display.
+ if (mService.mAccessibilityController != null && anyLayerChanged
+ && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
+ mService.mAccessibilityController.onWindowLayersChangedLocked();
+ }
+
+ if (DEBUG_LAYERS) logDebugLayers(windows);
+ }
+
+ void setInputMethodAnimLayerAdjustment(int adj) {
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
+ mInputMethodAnimLayerAdjustment = adj;
+ final WindowState imw = mService.mInputMethodWindow;
+ if (imw != null) {
+ imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
+ + " anim layer: " + imw.mWinAnimator.mAnimLayer);
+ for (int i = imw.mChildWindows.size() - 1; i >= 0; i--) {
+ final WindowState childWindow = imw.mChildWindows.get(i);
+ childWindow.mWinAnimator.mAnimLayer = childWindow.mLayer + adj;
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + childWindow
+ + " anim layer: " + childWindow.mWinAnimator.mAnimLayer);
+ }
+ }
+ for (int i = mService.mInputMethodDialogs.size() - 1; i >= 0; i--) {
+ final WindowState dialog = mService.mInputMethodDialogs.get(i);
+ dialog.mWinAnimator.mAnimLayer = dialog.mLayer + adj;
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
+ + " anim layer: " + dialog.mWinAnimator.mAnimLayer);
+ }
+ }
+
+ int getSpecialWindowAnimLayerAdjustment(WindowState win) {
+ if (win.mIsImWindow) {
+ return mInputMethodAnimLayerAdjustment;
+ } else if (win.mIsWallpaper) {
+ return mService.mWallpaperControllerLocked.getAnimLayerAdjustment();
+ }
+ return 0;
+ }
+
+ private void logDebugLayers(WindowList windows) {
+ for (int i = 0, n = windows.size(); i < n; i++) {
+ final WindowState w = windows.get(i);
+ final WindowStateAnimator winAnimator = w.mWinAnimator;
+ Slog.v(TAG_WM, "Assign layer " + w + ": " + "mBase=" + w.mBaseLayer
+ + " mLayer=" + w.mLayer + (w.mAppToken == null
+ ? "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
+ + " =mAnimLayer=" + winAnimator.mAnimLayer);
+ }
+ }
+
+ private void clear() {
+ mHighestApplicationLayer = 0;
+ mImeWindow = null;
+ mPinnedWindow = null;
+ mDockedWindow = null;
+ mDockDivider = null;
+ }
+
+ private void collectSpecialWindows(WindowState w) {
+ if (w.mIsImWindow) {
+ mImeWindow = w;
+ } else if (w.mAttrs.type == TYPE_DOCK_DIVIDER) {
+ mDockDivider = w;
+ } else {
+ final TaskStack stack = w.getStack();
+ if (stack.mStackId == StackId.PINNED_STACK_ID) {
+ mPinnedWindow = w;
+ } else if (stack.mStackId == StackId.DOCKED_STACK_ID) {
+ mDockedWindow = w;
+ }
+ }
+ }
+
+ private void adjustSpecialWindows() {
+ int layer = mHighestApplicationLayer + 1;
+ // For pinned and docked stack window, we want to make them above other windows
+ // also when these windows are animating.
+ layer = assignAndIncreaseLayerIfNeeded(mDockedWindow, layer);
+ layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
+ // We know that we will be animating a relaunching window in the near future,
+ // which will receive a z-order increase. We want the replaced window to
+ // immediately receive the same treatment, e.g. to be above the dock divider.
+ layer = assignAndIncreaseLayerIfNeeded(mReplacingWindow, layer);
+ layer = assignAndIncreaseLayerIfNeeded(mPinnedWindow, layer);
+ layer = assignAndIncreaseLayerIfNeeded(mImeWindow, layer);
+ }
+
+ private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) {
+ if (win != null) {
+ win.mLayer = layer;
+ win.mWinAnimator.mAnimLayer = layer;
+ layer++;
+ }
+ return layer;
+ }
+
+ void dump(PrintWriter pw, String s) {
+ if (mInputMethodAnimLayerAdjustment != 0 ||
+ mService.mWallpaperControllerLocked.getAnimLayerAdjustment() != 0) {
+ pw.print(" mInputMethodAnimLayerAdjustment=");
+ pw.print(mInputMethodAnimLayerAdjustment);
+ pw.print(" mWallpaperAnimLayerAdjustment=");
+ pw.println(mService.mWallpaperControllerLocked.getAnimLayerAdjustment());
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4ea0cf5..6385caa 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -66,7 +66,6 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
@@ -92,7 +91,6 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityManager.StackId;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.IActivityManager;
@@ -566,7 +564,6 @@
/** If true hold off on modifying the animation layer of mInputMethodTarget */
boolean mInputMethodTargetWaitingAnim;
- int mInputMethodAnimLayerAdjustment;
WindowState mInputMethodWindow = null;
final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
@@ -608,6 +605,8 @@
WallpaperController mWallpaperControllerLocked;
+ final WindowLayersController mLayersController;
+
boolean mAnimateWallpaperWithTarget;
AppWindowToken mFocusedApp = null;
@@ -880,6 +879,7 @@
mWallpaperControllerLocked = new WallpaperController(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);
+ mLayersController = new WindowLayersController(this);
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
@@ -1509,9 +1509,10 @@
mInputMethodTarget = w;
mInputMethodTargetWaitingAnim = false;
if (w.mAppToken != null) {
- setInputMethodAnimLayerAdjustment(w.mAppToken.mAppAnimator.animLayerAdjustment);
+ mLayersController.setInputMethodAnimLayerAdjustment(
+ w.mAppToken.mAppAnimator.animLayerAdjustment);
} else {
- setInputMethodAnimLayerAdjustment(0);
+ mLayersController.setInputMethodAnimLayerAdjustment(0);
}
}
return i+1;
@@ -1520,7 +1521,7 @@
if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to null."
+ (HIDE_STACK_CRAWLS ? "" : " Callers=" + Debug.getCallers(4)));
mInputMethodTarget = null;
- setInputMethodAnimLayerAdjustment(0);
+ mLayersController.setInputMethodAnimLayerAdjustment(0);
}
return -1;
}
@@ -1542,33 +1543,6 @@
moveInputMethodDialogsLocked(pos);
}
- void setInputMethodAnimLayerAdjustment(int adj) {
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
- mInputMethodAnimLayerAdjustment = adj;
- WindowState imw = mInputMethodWindow;
- if (imw != null) {
- imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
- + " anim layer: " + imw.mWinAnimator.mAnimLayer);
- int wi = imw.mChildWindows.size();
- while (wi > 0) {
- wi--;
- WindowState cw = imw.mChildWindows.get(wi);
- cw.mWinAnimator.mAnimLayer = cw.mLayer + adj;
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + cw
- + " anim layer: " + cw.mWinAnimator.mAnimLayer);
- }
- }
- int di = mInputMethodDialogs.size();
- while (di > 0) {
- di --;
- imw = mInputMethodDialogs.get(di);
- imw.mWinAnimator.mAnimLayer = imw.mLayer + adj;
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "IM win " + imw
- + " anim layer: " + imw.mWinAnimator.mAnimLayer);
- }
- }
-
private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
WindowList windows = win.getWindowList();
int wpos = windows.indexOf(win);
@@ -1767,7 +1741,7 @@
}
if (needAssignLayers) {
- assignLayersLocked(windows);
+ mLayersController.assignLayersLocked(windows);
}
return true;
@@ -2059,7 +2033,7 @@
moveInputMethodWindowsIfNeededLocked(false);
}
- assignLayersLocked(displayContent.getWindowList());
+ mLayersController.assignLayersLocked(displayContent.getWindowList());
// Don't do layout here, the window must call
// relayout to be displayed, so we'll do it there.
@@ -2386,7 +2360,7 @@
if (windows != null) {
windows.remove(win);
if (!mWindowPlacerLocked.isInLayout()) {
- assignLayersLocked(windows);
+ mLayersController.assignLayersLocked(windows);
win.setDisplayLayoutNeeded();
mWindowPlacerLocked.performSurfacePlacement();
if (win.mAppToken != null) {
@@ -2741,7 +2715,7 @@
// its layer recomputed. However, if the IME was hidden
// and isn't actually moved in the list, its layer may be
// out of data so we make sure to recompute it.
- assignLayersLocked(win.getWindowList());
+ mLayersController.assignLayersLocked(win.getWindowList());
}
if (wallpaperMayMove) {
@@ -4584,7 +4558,7 @@
if (!updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
false /*updateInputWindows*/)) {
- assignLayersLocked(displayContent.getWindowList());
+ mLayersController.assignLayersLocked(displayContent.getWindowList());
}
mInputMonitor.setUpdateInputWindowsNeededLw();
@@ -8660,102 +8634,6 @@
Arrays.fill(mRebuildTmp, null);
}
- final void assignLayersLocked(WindowList windows) {
- int N = windows.size();
- int curBaseLayer = 0;
- int curLayer = 0;
- int i;
-
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows,
- new RuntimeException("here").fillInStackTrace());
-
- boolean anyLayerChanged = false;
-
- for (i=0; i<N; i++) {
- final WindowState w = windows.get(i);
- final WindowStateAnimator winAnimator = w.mWinAnimator;
- boolean layerChanged = false;
- int oldLayer = w.mLayer;
- if (w.mBaseLayer == curBaseLayer || w.mIsImWindow || (i > 0 && w.mIsWallpaper)) {
- curLayer += WINDOW_LAYER_MULTIPLIER;
- w.mLayer = curLayer;
- } else {
- curBaseLayer = curLayer = w.mBaseLayer;
- w.mLayer = curLayer;
- }
- if (w.mLayer != oldLayer) {
- layerChanged = true;
- anyLayerChanged = true;
- }
- final AppWindowToken wtoken = w.mAppToken;
- oldLayer = winAnimator.mAnimLayer;
- if (w.mTargetAppToken != null) {
- winAnimator.mAnimLayer =
- w.mLayer + w.mTargetAppToken.mAppAnimator.animLayerAdjustment;
- } else if (wtoken != null) {
- winAnimator.mAnimLayer =
- w.mLayer + wtoken.mAppAnimator.animLayerAdjustment;
- forceHigherLayerIfNeeded(w, winAnimator, wtoken);
- } else {
- winAnimator.mAnimLayer = w.mLayer;
- }
- if (w.mIsImWindow) {
- winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
- } else if (w.mIsWallpaper) {
- winAnimator.mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
- }
- if (winAnimator.mAnimLayer != oldLayer) {
- layerChanged = true;
- anyLayerChanged = true;
- }
- final DimLayer.DimLayerUser dimLayerUser = w.getDimLayerUser();
- final DisplayContent displayContent = w.getDisplayContent();
- if (layerChanged && dimLayerUser != null && displayContent != null &&
- displayContent.mDimLayerController.isDimming(dimLayerUser, winAnimator)) {
- // Force an animation pass just to update the mDimLayer layer.
- scheduleAnimationLocked();
- }
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assign layer " + w + ": "
- + "mBase=" + w.mBaseLayer
- + " mLayer=" + w.mLayer
- + (wtoken == null ?
- "" : " mAppLayer=" + wtoken.mAppAnimator.animLayerAdjustment)
- + " =mAnimLayer=" + winAnimator.mAnimLayer);
- //System.out.println(
- // "Assigned layer " + curLayer + " to " + w.mClient.asBinder());
- }
-
- //TODO (multidisplay): Magnification is supported only for the default display.
- if (mAccessibilityController != null && anyLayerChanged
- && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
- mAccessibilityController.onWindowLayersChangedLocked();
- }
- }
-
- private void forceHigherLayerIfNeeded(WindowState w, WindowStateAnimator winAnimator,
- AppWindowToken wtoken) {
- boolean force = false;
-
- if (w.mWillReplaceWindow) {
- // We know that we will be animating a relaunching window in the near future,
- // which will receive a z-order increase. We want the replaced window to
- // immediately receive the same treatment, e.g. to be above the dock divider.
- force = true;
- }
- if (!force) {
- final TaskStack stack = w.getStack();
- if (stack != null && (StackId.shouldIncreaseApplicationWindowLayer(stack.mStackId))) {
- // For pinned and docked stack window, we want to make them above other windows
- // also when these windows are animating.
- force = true;
- }
- }
- if (force) {
- w.mLayer += TYPE_LAYER_OFFSET;
- winAnimator.mAnimLayer += TYPE_LAYER_OFFSET;
- }
- }
-
void makeWindowFreezingScreenIfNeededLocked(WindowState w) {
// If the screen is currently frozen or off, then keep
// it frozen/off until this window draws at its new
@@ -9126,7 +9004,7 @@
} else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
// Client will do the layout, but we need to assign layers
// for handleNewWindowLocked() below.
- assignLayersLocked(displayContent.getWindowList());
+ mLayersController.assignLayersLocked(displayContent.getWindowList());
}
}
@@ -9814,13 +9692,7 @@
}
mWindowPlacerLocked.dump(pw, " ");
mWallpaperControllerLocked.dump(pw, " ");
- if (mInputMethodAnimLayerAdjustment != 0 ||
- mWallpaperControllerLocked.getAnimLayerAdjustment() != 0) {
- pw.print(" mInputMethodAnimLayerAdjustment=");
- pw.print(mInputMethodAnimLayerAdjustment);
- pw.print(" mWallpaperAnimLayerAdjustment=");
- pw.println(mWallpaperControllerLocked.getAnimLayerAdjustment());
- }
+ mLayersController.dump(pw, " ");
pw.print(" mSystemBooted="); pw.print(mSystemBooted);
pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
if (needsLayout()) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index e4a6806..9a24942 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1273,6 +1273,29 @@
mHasSurface = hasSurface;
}
+ int getAnimLayerAdjustment() {
+ if (mTargetAppToken != null) {
+ return mTargetAppToken.mAppAnimator.animLayerAdjustment;
+ } else if (mAppToken != null) {
+ return mAppToken.mAppAnimator.animLayerAdjustment;
+ } else {
+ // Nothing is animating, so there is no animation adjustment.
+ return 0;
+ }
+ }
+
+ void scheduleAnimationIfDimming() {
+ if (mDisplayContent == null) {
+ return;
+ }
+ final DimLayer.DimLayerUser dimLayerUser = getDimLayerUser();
+ if (dimLayerUser != null && mDisplayContent.mDimLayerController.isDimming(
+ dimLayerUser, mWinAnimator)) {
+ // Force an animation pass just to update the mDimLayer layer.
+ mService.scheduleAnimationLocked();
+ }
+ }
+
private final class DeadWindowEventReceiver extends InputEventReceiver {
DeadWindowEventReceiver(InputChannel inputChannel) {
super(inputChannel, mService.mH.getLooper());
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d4001cd..7605af0 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -384,12 +384,8 @@
if (mAnimator.mWindowDetachedWallpaper == mWin) {
mAnimator.mWindowDetachedWallpaper = null;
}
- mAnimLayer = mWin.mLayer;
- if (mWin.mIsImWindow) {
- mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
- } else if (mIsWallpaper) {
- mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
- }
+ mAnimLayer = mWin.mLayer
+ + mService.mLayersController.getSpecialWindowAnimLayerAdjustment(mWin);
if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this + " anim layer: " + mAnimLayer);
mHasTransformation = false;
mHasLocalTransformation = false;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 160c97f..cbfb201 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -524,7 +524,7 @@
}
for (DisplayContent displayContent : displayList) {
- mService.assignLayersLocked(displayContent.getWindowList());
+ mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
displayContent.layoutNeeded = true;
}
}
@@ -599,7 +599,7 @@
if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
mWallpaperControllerLocked.adjustWallpaperWindows()) {
- mService.assignLayersLocked(windows);
+ mService.mLayersController.assignLayersLocked(windows);
displayContent.layoutNeeded = true;
}
@@ -1134,7 +1134,7 @@
// TODO(multidisplay): IMEs are only supported on the default display.
if (windows == mService.getDefaultWindowListLocked()
&& !mService.moveInputMethodWindowsIfNeededLocked(true)) {
- mService.assignLayersLocked(windows);
+ mService.mLayersController.assignLayersLocked(windows);
}
mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
true /*updateInputWindows*/);
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index cf1a4aa..fecfdf9 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -23,6 +23,7 @@
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Vibrator;
@@ -180,6 +181,9 @@
new Test("with topic GoodBye") {
public void run() {
+ Notification.BigPictureStyle picture = new Notification.BigPictureStyle();
+ picture.bigPicture(BitmapFactory.decodeResource(getResources(),
+ R.id.large_icon_pineapple2));
Notification n = new Notification.Builder(NotificationTestList.this)
.setSmallIcon(R.drawable.icon1)
.setWhen(mActivityCreateTime)
@@ -187,11 +191,29 @@
.setContentText("This is a notification!!!")
.setContentIntent(makeIntent2())
.setTopic(new Notification.Topic("bye", "Goodbye"))
+ .setStyle(picture)
.build();
mNM.notify(9999, n);
}
},
+ new Test("with topic Bananas") {
+ public void run() {
+ Notification.BigTextStyle bigText = new Notification.BigTextStyle();
+ bigText.bigText("bananas are great\nso tasty\nyum\nyum\nyum\n");
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon1)
+ .setStyle(bigText)
+ .setWhen(mActivityCreateTime)
+ .setContentTitle("bananananana")
+ .setContentText("This is a banana!!!")
+ .setContentIntent(makeIntent2())
+ .setTopic(new Notification.Topic("bananas", "Bananas"))
+ .build();
+
+ mNM.notify(999, n);
+ }
+ },
new Test("Whens") {
public void run()