Merge "Use resolved calling user id"
diff --git a/Android.mk b/Android.mk
index 9d2ca0d..f545207 100644
--- a/Android.mk
+++ b/Android.mk
@@ -430,7 +430,7 @@
$(framework_res_source_path)/com/android/internal/R.java
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-libart conscrypt okhttp core-junit bouncycastle ext
+LOCAL_JAVA_LIBRARIES := core-oj core-libart conscrypt okhttp core-junit bouncycastle ext
LOCAL_MODULE := framework
@@ -719,6 +719,7 @@
$(framework_res_source_path)/com/android/internal/R.java
framework_docs_LOCAL_API_CHECK_JAVA_LIBRARIES := \
+ core-oj \
core-libart \
conscrypt \
bouncycastle \
@@ -1104,7 +1105,7 @@
LOCAL_SRC_FILES := $(ext_src_files)
LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_JAVA_LIBRARIES := core-libart
+LOCAL_JAVA_LIBRARIES := core-oj core-libart
LOCAL_STATIC_JAVA_LIBRARIES := libphonenumber-platform
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := ext
diff --git a/api/current.txt b/api/current.txt
index fd2e038..abb90fd 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4867,6 +4867,7 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
+ field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
field public static final int VISIBILITY_PRIVATE = 0; // 0x0
field public static final int VISIBILITY_PUBLIC = 1; // 0x1
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5865,6 +5866,7 @@
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_LOGO_URI = "android.app.extra.PROVISIONING_LOGO_URI";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -25795,6 +25797,7 @@
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
field public static final android.net.Uri CONTENT_VCARD_URI;
+ field public static final android.net.Uri CORP_CONTENT_FILTER_URI;
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -25915,12 +25918,15 @@
}
public static final class ContactsContract.Directory implements android.provider.BaseColumns {
+ method public static boolean isEnterpriseDirectoryId(long);
+ method public static boolean isRemoteDirectory(long);
method public static void notifyDirectoryChange(android.content.ContentResolver);
field public static final java.lang.String ACCOUNT_NAME = "accountName";
field public static final java.lang.String ACCOUNT_TYPE = "accountType";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_directory";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact_directories";
field public static final android.net.Uri CONTENT_URI;
+ field public static final android.net.Uri CORP_CONTENT_URI;
field public static final long DEFAULT = 0L; // 0x0L
field public static final java.lang.String DIRECTORY_AUTHORITY = "authority";
field public static final java.lang.String DISPLAY_NAME = "displayName";
@@ -26280,6 +26286,7 @@
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
field public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 512; // 0x200
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
+ field public static final int FLAG_VIRTUAL_DOCUMENT = 1024; // 0x400
field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 0d5cde4..7703082 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4985,6 +4985,7 @@
field public static final int PRIORITY_MAX = 2; // 0x2
field public static final int PRIORITY_MIN = -2; // 0xfffffffe
field public static final deprecated int STREAM_DEFAULT = -1; // 0xffffffff
+ field public static final java.lang.String TOPIC_DEFAULT = "system_default_topic";
field public static final int VISIBILITY_PRIVATE = 0; // 0x0
field public static final int VISIBILITY_PUBLIC = 1; // 0x1
field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
@@ -5999,6 +6000,7 @@
field public static final java.lang.String EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED = "android.app.extra.PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED";
field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.PROVISIONING_LOCALE";
field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.PROVISIONING_LOCAL_TIME";
+ field public static final java.lang.String EXTRA_PROVISIONING_LOGO_URI = "android.app.extra.PROVISIONING_LOGO_URI";
field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
@@ -27778,6 +27780,7 @@
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String CONTENT_VCARD_TYPE = "text/x-vcard";
field public static final android.net.Uri CONTENT_VCARD_URI;
+ field public static final android.net.Uri CORP_CONTENT_FILTER_URI;
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS";
field public static final java.lang.String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES";
@@ -27898,12 +27901,15 @@
}
public static final class ContactsContract.Directory implements android.provider.BaseColumns {
+ method public static boolean isEnterpriseDirectoryId(long);
+ method public static boolean isRemoteDirectory(long);
method public static void notifyDirectoryChange(android.content.ContentResolver);
field public static final java.lang.String ACCOUNT_NAME = "accountName";
field public static final java.lang.String ACCOUNT_TYPE = "accountType";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact_directory";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact_directories";
field public static final android.net.Uri CONTENT_URI;
+ field public static final android.net.Uri CORP_CONTENT_URI;
field public static final long DEFAULT = 0L; // 0x0L
field public static final java.lang.String DIRECTORY_AUTHORITY = "authority";
field public static final java.lang.String DISPLAY_NAME = "displayName";
@@ -28293,6 +28299,7 @@
field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
field public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 512; // 0x200
field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
+ field public static final int FLAG_VIRTUAL_DOCUMENT = 1024; // 0x400
field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 84ddd9f..c1d5b19 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -47,11 +47,11 @@
void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
boolean areNotificationsEnabledForPackage(String pkg, int uid);
- void setPackagePriority(String pkg, int uid, int priority);
- int getPackagePriority(String pkg, int uid);
-
- void setPackageVisibilityOverride(String pkg, int uid, int visibility);
- int getPackageVisibilityOverride(String pkg, int uid);
+ ParceledListSlice getTopics(String pkg, int uid);
+ void setTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic, int visibility);
+ int getTopicVisibilityOverride(String pkg, int uid, in Notification.Topic topic);
+ void setTopicPriority(String pkg, int uid, in Notification.Topic topic, int priority);
+ int getTopicPriority(String pkg, int uid, in Notification.Topic topic);
// TODO: Remove this when callers have been migrated to the equivalent
// INotificationListener method.
diff --git a/core/java/android/app/Notification.aidl b/core/java/android/app/Notification.aidl
index 9d8129c..3f1d113 100644
--- a/core/java/android/app/Notification.aidl
+++ b/core/java/android/app/Notification.aidl
@@ -17,3 +17,4 @@
package android.app;
parcelable Notification;
+parcelable Notification.Topic;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4e6548b..848b33f 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,6 +21,7 @@
import android.annotation.IntDef;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -1433,6 +1434,9 @@
};
}
+ @SystemApi
+ public static final String TOPIC_DEFAULT = "system_default_topic";
+
private Topic topic;
public Topic getTopic() {
@@ -3419,6 +3423,10 @@
mN.extras.putStringArray(EXTRA_PEOPLE,
mPersonList.toArray(new String[mPersonList.size()]));
}
+ if (mN.topic == null) {
+ mN.topic = new Topic(TOPIC_DEFAULT, mContext.getString(
+ R.string.default_notification_topic_label));
+ }
return mN;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index faed7a0..94b434c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -31,6 +31,7 @@
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.net.ProxyInfo;
+import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.Process;
@@ -130,6 +131,7 @@
* As of {@link android.os.Build.VERSION_CODES#M}, it should contain the extra
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME} instead, although specifying only
* {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} is still supported.
+ * This intent may also contain the extra {@link #EXTRA_PROVISIONING_LOGO_URI}.
*
* <p> When managed provisioning has completed, broadcasts are sent to the application specified
* in the provisioning intent. The
@@ -196,6 +198,7 @@
* <li>{@link #EXTRA_PROVISIONING_SKIP_ENCRYPTION}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_LEAVE_ALL_SYSTEM_APPS_ENABLED}, optional</li>
* <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional</li>
+ * <li>{@link #EXTRA_PROVISIONING_LOGO_URI}, optional</li>
* </ul>
*
* <p> When device owner provisioning has completed, an intent of the type
@@ -573,6 +576,28 @@
"android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
/**
+ * A {@link Uri} extra pointing to a logo image. This image will be shown during the
+ * provisioning. If this extra is not passed, a default image will be shown.
+ * <h5>The following URI schemes are accepted:</h5>
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+ * </ul>
+ *
+ * <p> It is the responsability of the caller to provide an image with a reasonable
+ * pixed density for the device.
+ *
+ * <p> If a content: URI is passed, the intent should have the flag
+ * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and the uri should be added to the
+ * {@link android.content.ClipData} of the intent too.
+ *
+ * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_PROFILE} or
+ * {@link #ACTION_PROVISION_MANAGED_DEVICE}
+ */
+ public static final String EXTRA_PROVISIONING_LOGO_URI =
+ "android.app.extra.PROVISIONING_LOGO_URI";
+
+ /**
* This MIME type is used for starting the Device Owner provisioning.
*
* <p>During device owner provisioning a device admin app is set as the owner of the device.
@@ -3763,12 +3788,18 @@
* {@link UserManager#getUserRestrictions()}.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @throws SecurityException if the {@code admin} is not an active admin.
*/
public Bundle getUserRestrictions(@NonNull ComponentName admin) {
+ return getUserRestrictions(admin, myUserId());
+ }
+
+ /** @hide per-user version */
+ public Bundle getUserRestrictions(@NonNull ComponentName admin, int userHandle) {
Bundle ret = null;
if (mService != null) {
try {
- ret = mService.getUserRestrictions(admin);
+ ret = mService.getUserRestrictions(admin, userHandle);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7601cf2..93a5503 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -149,7 +149,7 @@
ComponentName getRestrictionsProvider(int userHandle);
void setUserRestriction(in ComponentName who, in String key, boolean enable);
- Bundle getUserRestrictions(in ComponentName who);
+ Bundle getUserRestrictions(in ComponentName who, int userId);
void addCrossProfileIntentFilter(in ComponentName admin, in IntentFilter filter, int flags);
void clearCrossProfileIntentFilters(in ComponentName admin);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 9d941fd..4a7cbc7 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2956,8 +2956,8 @@
* multiple selection), then you can specify {@link #EXTRA_ALLOW_MULTIPLE}
* to indicate this.
* <p>
- * Callers must include {@link #CATEGORY_OPENABLE} in the Intent so that
- * returned URIs can be opened with
+ * Callers must include {@link #CATEGORY_OPENABLE} in the Intent to obtain
+ * URIs that can be opened with
* {@link ContentResolver#openFileDescriptor(Uri, String)}.
* <p>
* Output: The URI of the item that was picked, returned in
@@ -2992,8 +2992,8 @@
* Callers can provide an initial display name through {@link #EXTRA_TITLE},
* but the user may change this value before creating the file.
* <p>
- * Callers must include {@link #CATEGORY_OPENABLE} in the Intent so that
- * returned URIs can be opened with
+ * Callers must include {@link #CATEGORY_OPENABLE} in the Intent to obtain
+ * URIs that can be opened with
* {@link ContentResolver#openFileDescriptor(Uri, String)}.
* <p>
* Output: The URI of the item that was created. This must be a
diff --git a/core/java/android/content/pm/ManifestDigest.java b/core/java/android/content/pm/ManifestDigest.java
index 1fbef7a..e7dc764 100644
--- a/core/java/android/content/pm/ManifestDigest.java
+++ b/core/java/android/content/pm/ManifestDigest.java
@@ -16,6 +16,8 @@
package android.content.pm;
+import com.android.internal.util.HexDump;
+
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -118,7 +120,7 @@
final int N = mDigest.length;
for (int i = 0; i < N; i++) {
final byte b = mDigest[i];
- IntegralToString.appendByteAsHex(sb, b, false);
+ HexDump.appendByteAsHex(sb, b, false);
sb.append(',');
}
sb.append('}');
@@ -142,4 +144,4 @@
}
};
-}
\ No newline at end of file
+}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index 5b60c0d..2715af0 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -16,6 +16,8 @@
package android.net.http;
+import com.android.internal.util.HexDump;
+
import android.content.Context;
import android.os.Bundle;
import android.text.format.DateFormat;
@@ -285,7 +287,7 @@
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
- IntegralToString.appendByteAsHex(sb, b, true);
+ HexDump.appendByteAsHex(sb, b, true);
if (i+1 != bytes.length) {
sb.append(':');
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index e3694e8..b860bfb 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -394,6 +394,14 @@
Uri.withAppendedPath(AUTHORITY_URI, "directories");
/**
+ * The content:// style URI for enterprise Directory table. Requests to this URI can be
+ * performed on the UI thread because they are always unblocking.
+ *
+ */
+ public static final Uri CORP_CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI,
+ "directories_corp");
+
+ /**
* The MIME-type of {@link #CONTENT_URI} providing a directory of
* contact directories.
*/
@@ -417,6 +425,22 @@
public static final long LOCAL_INVISIBLE = 1;
/**
+ * _ID of the work profile default directory, which represents locally stored contacts.
+ *
+ * @hide
+ */
+ public static final long ENTERPRISE_DEFAULT = Directory.ENTERPRISE_DIRECTORY_ID_BASE
+ + DEFAULT;
+
+ /**
+ * _ID of the work profile directory that represents locally stored invisible contacts.
+ *
+ * @hide
+ */
+ public static final long ENTERPRISE_LOCAL_INVISIBLE = Directory.ENTERPRISE_DIRECTORY_ID_BASE
+ + LOCAL_INVISIBLE;
+
+ /**
* The name of the package that owns this directory. Contacts Provider
* fill it in with the name of the package containing the directory provider.
* If the package is later uninstalled, the directories it owns are
@@ -472,6 +496,15 @@
public static final String ACCOUNT_NAME = "accountName";
/**
+ * Mimimal ID for corp directory returned from
+ * {@link Directory#CORP_CONTENT_URI}.
+ *
+ * @hide
+ */
+ // slightly smaller than 2 ** 30
+ public static final long ENTERPRISE_DIRECTORY_ID_BASE = 1000000000;
+
+ /**
* One of {@link #EXPORT_SUPPORT_NONE}, {@link #EXPORT_SUPPORT_ANY_ACCOUNT},
* {@link #EXPORT_SUPPORT_SAME_ACCOUNT_ONLY}. This is the expectation the
* directory has for data exported from it. Clients must obey this setting.
@@ -555,6 +588,24 @@
public static final int PHOTO_SUPPORT_FULL = 3;
/**
+ * Return TRUE if it is a remote stored directory.
+ */
+ public static boolean isRemoteDirectory(long directoryId) {
+ return directoryId != Directory.DEFAULT
+ && directoryId != Directory.LOCAL_INVISIBLE
+ && directoryId != Directory.ENTERPRISE_DEFAULT
+ && directoryId != Directory.ENTERPRISE_LOCAL_INVISIBLE;
+ }
+
+ /**
+ * Return TRUE if a directory ID is from the contacts provider on the enterprise profile.
+ *
+ */
+ public static boolean isEnterpriseDirectoryId(long directoryId) {
+ return directoryId >= ENTERPRISE_DIRECTORY_ID_BASE;
+ }
+
+ /**
* Notifies the system of a change in the list of directories handled by
* a particular directory provider. The Contacts provider will turn around
* and send a query to the directory provider for the full list of directories,
@@ -1589,6 +1640,14 @@
CONTENT_URI, "filter");
/**
+ * It supports the same semantics as {@link #CONTENT_FILTER_URI} and returns the same
+ * columns. If there is a corp profile linked to the current profile, it will query corp
+ * profile, otherwise it will return null.
+ */
+ public static final Uri CORP_CONTENT_FILTER_URI = Uri.withAppendedPath(
+ CORP_CONTENT_URI, "filter");
+
+ /**
* The content:// style URI for this table joined with useful data from
* {@link ContactsContract.Data}, filtered to include only starred contacts
* and the most frequently contacted contacts.
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index af7f472..8ae899f 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -233,6 +233,7 @@
* @see #FLAG_SUPPORTS_TYPED_DOCUMENT
* @see #FLAG_DIR_PREFERS_GRID
* @see #FLAG_DIR_PREFERS_LAST_MODIFIED
+ * @see #FLAG_VIRTUAL_DOCUMENT
*/
public static final String COLUMN_FLAGS = "flags";
@@ -356,6 +357,17 @@
public static final int FLAG_SUPPORTS_TYPED_DOCUMENT = 1 << 9;
/**
+ * Flag indicating that a document is virtual, and doesn't have byte
+ * representation in the MIME type specified as {@link #COLUMN_MIME_TYPE}.
+ *
+ * @see #COLUMN_FLAGS
+ * @see #COLUMN_MIME_TYPE
+ * @see DocumentsProvider#openTypedDocument(String, String, Bundle,
+ * android.os.CancellationSignal)
+ */
+ public static final int FLAG_VIRTUAL_DOCUMENT = 1 << 10;
+
+ /**
* Flag indicating that document titles should be hidden when viewing
* this directory in a larger format grid. For example, a directory
* containing only images may want the image thumbnails to speak for
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9034cc9..f560f8a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7758,6 +7758,7 @@
AUTO_TIME_ZONE,
POWER_SOUNDS_ENABLED,
DOCK_SOUNDS_ENABLED,
+ CHARGING_SOUNDS_ENABLED,
USB_MASS_STORAGE_ENABLED,
ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED,
WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index b523b84..a24fb40 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -84,6 +84,8 @@
private final RadialTimePickerView mRadialTimePickerView;
private final TextView mSeparatorView;
+ private final Calendar mTempCalendar;
+
private boolean mIsEnabled = true;
private boolean mAllowAutoAdvance;
private int mInitialHourOfDay;
@@ -103,8 +105,6 @@
private CharSequence mLastAnnouncedText;
private boolean mLastAnnouncedIsHour;
- private Calendar mTempCalendar;
-
public TimePickerClockDelegate(TimePicker delegator, Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(delegator, context);
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 2ed230b..863d409 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -32,6 +32,7 @@
import com.android.internal.R;
import java.util.Calendar;
+import java.util.Locale;
import libcore.icu.LocaleData;
@@ -45,11 +46,6 @@
private static final boolean DEFAULT_ENABLED_STATE = true;
private static final int HOURS_IN_HALF_DAY = 12;
- // state
- private boolean mIs24HourView;
- private boolean mIsAm;
-
- // ui components
private final NumberPicker mHourSpinner;
private final NumberPicker mMinuteSpinner;
private final NumberPicker mAmPmSpinner;
@@ -66,11 +62,15 @@
private final String[] mAmPmStrings;
+ private final Calendar mTempCalendar;
+
private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
- private Calendar mTempCalendar;
private boolean mHourWithTwoDigit;
private char mHourFormat;
+ private boolean mIs24HourView;
+ private boolean mIsAm;
+
public TimePickerSpinnerDelegate(TimePicker delegator, Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(delegator, context);
@@ -202,6 +202,7 @@
updateAmPmControl();
// set to current time
+ mTempCalendar = Calendar.getInstance(mLocale);
setHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
setMinute(mTempCalendar.get(Calendar.MINUTE));
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 08c7935..c992c70 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -33,6 +33,7 @@
public static final int NOTIFICATION_ZEN_MODE_VISUAL_INTERRUPTIONS = 260;
public static final int ACTION_ZEN_ALLOW_PEEK = 261;
public static final int ACTION_ZEN_ALLOW_LIGHTS = 262;
+ public static final int NOTIFICATION_TOPIC_NOTIFICATION = 263;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f73df00..9391c60 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -105,7 +105,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 135 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 136 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -1975,8 +1975,14 @@
private int buildBatteryLevelInt(HistoryItem h) {
return ((((int)h.batteryLevel)<<25)&0xfe000000)
- | ((((int)h.batteryTemperature)<<14)&0x01ff8000)
- | ((((int)h.batteryVoltage)<<1)&0x00007fff);
+ | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
+ | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
+ }
+
+ private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
+ out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
+ out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
+ out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
}
private int buildStateInt(HistoryItem h) {
@@ -2117,9 +2123,7 @@
final int batteryLevelInt;
if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
batteryLevelInt = src.readInt();
- cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
- cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
- cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
+ readBatteryLevelInt(batteryLevelInt, cur);
cur.numReadInts += 1;
if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
+ Integer.toHexString(batteryLevelInt)
diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java
index 3c7b7ac..7be95d8 100644
--- a/core/java/com/android/internal/util/HexDump.java
+++ b/core/java/com/android/internal/util/HexDump.java
@@ -19,28 +19,29 @@
public class HexDump
{
private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
+ private final static char[] HEX_LOWER_CASE_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
+
public static String dumpHexString(byte[] array)
{
return dumpHexString(array, 0, array.length);
}
-
+
public static String dumpHexString(byte[] array, int offset, int length)
{
StringBuilder result = new StringBuilder();
-
+
byte[] line = new byte[16];
int lineIndex = 0;
-
+
result.append("\n0x");
result.append(toHexString(offset));
-
+
for (int i = offset ; i < offset + length ; i++)
{
if (lineIndex == 16)
{
result.append(" ");
-
+
for (int j = 0 ; j < 16 ; j++)
{
if (line[j] > ' ' && line[j] < '~')
@@ -52,20 +53,20 @@
result.append(".");
}
}
-
+
result.append("\n0x");
result.append(toHexString(i));
lineIndex = 0;
}
-
+
byte b = array[i];
result.append(" ");
result.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
result.append(HEX_DIGITS[b & 0x0F]);
-
+
line[lineIndex++] = b;
}
-
+
if (lineIndex != 16)
{
int count = (16 - lineIndex) * 3;
@@ -74,7 +75,7 @@
{
result.append(" ");
}
-
+
for (int i = 0 ; i < lineIndex ; i++)
{
if (line[i] > ' ' && line[i] < '~')
@@ -87,10 +88,10 @@
}
}
}
-
+
return result.toString();
}
-
+
public static String toHexString(byte b)
{
return toHexString(toByteArray(b));
@@ -98,48 +99,59 @@
public static String toHexString(byte[] array)
{
- return toHexString(array, 0, array.length);
+ return toHexString(array, 0, array.length, true);
}
-
+
+ public static String toHexString(byte[] array, boolean upperCase)
+ {
+ return toHexString(array, 0, array.length, upperCase);
+ }
+
public static String toHexString(byte[] array, int offset, int length)
{
+ return toHexString(array, offset, length, true);
+ }
+
+ public static String toHexString(byte[] array, int offset, int length, boolean upperCase)
+ {
+ char[] digits = upperCase ? HEX_DIGITS : HEX_LOWER_CASE_DIGITS;
char[] buf = new char[length * 2];
int bufIndex = 0;
- for (int i = offset ; i < offset + length; i++)
+ for (int i = offset ; i < offset + length; i++)
{
byte b = array[i];
- buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
- buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
+ buf[bufIndex++] = digits[(b >>> 4) & 0x0F];
+ buf[bufIndex++] = digits[b & 0x0F];
}
- return new String(buf);
+ return new String(buf);
}
-
+
public static String toHexString(int i)
{
return toHexString(toByteArray(i));
}
-
+
public static byte[] toByteArray(byte b)
{
byte[] array = new byte[1];
array[0] = b;
return array;
}
-
+
public static byte[] toByteArray(int i)
{
byte[] array = new byte[4];
-
+
array[3] = (byte)(i & 0xFF);
array[2] = (byte)((i >> 8) & 0xFF);
array[1] = (byte)((i >> 16) & 0xFF);
array[0] = (byte)((i >> 24) & 0xFF);
-
+
return array;
}
-
+
private static int toByte(char c)
{
if (c >= '0' && c <= '9') return (c - '0');
@@ -148,7 +160,7 @@
throw new RuntimeException ("Invalid hex char '" + c + "'");
}
-
+
public static byte[] hexStringToByteArray(String hexString)
{
int length = hexString.length();
@@ -158,7 +170,15 @@
{
buffer[i / 2] = (byte)((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i+1)));
}
-
+
return buffer;
- }
+ }
+
+ public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
+ char[] digits = upperCase ? HEX_DIGITS : HEX_LOWER_CASE_DIGITS;
+ sb.append(digits[(b >> 4) & 0xf]);
+ sb.append(digits[b & 0xf]);
+ return sb;
+ }
+
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index e674ecc..b505ea0 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -38,13 +38,17 @@
private View mAnchorView;
private MenuPopup mPopup;
- private int mDropDownGravity = Gravity.NO_GRAVITY;
+ private int mDropDownGravity = Gravity.START;
private boolean mForceShowIcon;
private boolean mShowTitle;
private Callback mPresenterCallback;
+
private int mInitXOffset;
private int mInitYOffset;
+ /** Whether the popup has anchor-relative offsets. */
+ private boolean mHasOffsets;
+
public MenuPopupHelper(Context context, MenuBuilder menu) {
this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0);
}
@@ -131,12 +135,31 @@
mInitXOffset = 0;
mInitYOffset = 0;
+ mHasOffsets = false;
mShowTitle = false;
showPopup();
return true;
}
+ /**
+ * Shows the popup menu and makes a best-effort to anchor it to the
+ * specified (x,y) coordinate relative to the anchor view.
+ * <p>
+ * If the popup's resolved gravity is {@link Gravity#LEFT}, this will
+ * display the popup with its top-left corner at (x,y) relative to the
+ * anchor view. If the resolved gravity is {@link Gravity#RIGHT}, the
+ * popup's top-right corner will be at (x,y).
+ * <p>
+ * If the popup cannot be displayed fully on-screen, this method will
+ * attempt to scroll the anchor view's ancestors and/or offset the popup
+ * such that it may be displayed fully on-screen.
+ *
+ * @param x x coordinate relative to the anchor view
+ * @param y y coordinate relative to the anchor view
+ * @return {@code true} if the popup was shown or was already showing prior
+ * to calling this method, {@code false} otherwise
+ */
public boolean tryShow(int x, int y) {
if (isShowing()) {
return true;
@@ -148,6 +171,7 @@
mInitXOffset = x;
mInitYOffset = y;
+ mHasOffsets = true;
mShowTitle = true;
showPopup();
@@ -160,9 +184,24 @@
mPopup.setCallback(mPresenterCallback);
mPopup.setForceShowIcon(mForceShowIcon);
mPopup.setGravity(mDropDownGravity);
- mPopup.setHorizontalOffset(mInitXOffset);
mPopup.setShowTitle(mShowTitle);
- mPopup.setVerticalOffset(mInitYOffset);
+
+ if (mHasOffsets) {
+ // If the resolved drop-down gravity is RIGHT, the popup's right
+ // edge will be aligned with the anchor view. Adjust by the anchor
+ // width such that the top-right corner is at the X offset.
+ final int hgrav = Gravity.getAbsoluteGravity(mDropDownGravity,
+ mAnchorView.getLayoutDirection()) & Gravity.HORIZONTAL_GRAVITY_MASK;
+ final int resolvedXOffset;
+ if (hgrav == Gravity.RIGHT) {
+ resolvedXOffset = mInitXOffset - mAnchorView.getWidth();
+ } else {
+ resolvedXOffset = mInitXOffset;
+ }
+
+ mPopup.setHorizontalOffset(resolvedXOffset);
+ mPopup.setVerticalOffset(mInitYOffset);
+ }
// In order for subclasses of MenuPopupHelper to satisfy the OnDismissedListener interface,
// we must set the listener to this outer Helper rather than to the inner MenuPopup.
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 7fd288a..9b774b3 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -63,6 +63,11 @@
layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint);
}
+bool MinikinUtils::hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs) {
+ const TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
+ return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs);
+}
+
float MinikinUtils::xOffsetForTextAlign(Paint* paint, const Layout& layout) {
switch (paint->getTextAlign()) {
case Paint::kCenter_Align:
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 1ee6245..5bf1eec 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -40,6 +40,8 @@
TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
size_t bufSize);
+ static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs);
+
static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index b50046f..9c11dd1 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -39,6 +39,7 @@
#include <minikin/GraphemeBreak.h>
#include <minikin/Measurement.h>
+#include <unicode/utf16.h>
#include "MinikinSkia.h"
#include "MinikinUtils.h"
#include "Paint.h"
@@ -852,45 +853,44 @@
return false;
}
- static jboolean hasGlyphVariation(const Paint* paint, TypefaceImpl* typeface, jint bidiFlags,
- const jchar* chars, size_t size) {
- // TODO: query font for whether character has variation selector; requires a corresponding
- // function in Minikin.
- return false;
- }
-
static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle,
jint bidiFlags, jstring string) {
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
ScopedStringChars str(env, string);
- /* start by rejecting variation selectors (not supported yet) */
+ /* Start by rejecting unsupported base code point and variation selector pairs. */
size_t nChars = 0;
+ const uint32_t kStartOfString = 0xFFFFFFFF;
+ uint32_t prevCp = kStartOfString;
for (size_t i = 0; i < str.size(); i++) {
- jchar c = str[i];
- if (0xDC00 <= c && c <= 0xDFFF) {
+ jchar cu = str[i];
+ uint32_t cp = cu;
+ if (U16_IS_TRAIL(cu)) {
// invalid UTF-16, unpaired trailing surrogate
return false;
- } else if (0xD800 <= c && c <= 0xDBFF) {
+ } else if (U16_IS_LEAD(cu)) {
if (i + 1 == str.size()) {
// invalid UTF-16, unpaired leading surrogate at end of string
return false;
}
i++;
- jchar c2 = str[i];
- if (!(0xDC00 <= c2 && c2 <= 0xDFFF)) {
+ jchar cu2 = str[i];
+ if (!U16_IS_TRAIL(cu2)) {
// invalid UTF-16, unpaired leading surrogate
return false;
}
- // UTF-16 encoding of range U+E0100..U+E01EF is DB40 DD00 .. DB40 DDEF
- if (c == 0xDB40 && 0xDD00 <= c2 && c2 <= 0xDDEF) {
- return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size());
- }
- } else if (0xFE00 <= c && c <= 0xFE0F) {
- return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size());
+ cp = U16_GET_SUPPLEMENTARY(cu, cu2);
+ }
+
+ if (prevCp != kStartOfString &&
+ ((0xFE00 <= cp && cp <= 0xFE0F) || (0xE0100 <= cp && cp <= 0xE01EF)) &&
+ !MinikinUtils::hasVariationSelector(typeface, prevCp, cp)) {
+ // No font has a glyph for the code point and variation selector pair.
+ return false;
}
nChars++;
+ prevCp = cp;
}
Layout layout;
MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(),
diff --git a/core/res/res/values-mcc208-mnc01/config.xml b/core/res/res/values-mcc208-mnc01/config.xml
index c56da24..5930e3a 100644
--- a/core/res/res/values-mcc208-mnc01/config.xml
+++ b/core/res/res/values-mcc208-mnc01/config.xml
@@ -28,9 +28,6 @@
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
<string-array translatable="false" name="config_tether_apndata">
<item>Orange Internet,orange.fr,,,orange,orange,,,,,208,01,1,DUN</item>
- <item>[ApnSettingV3]Carrefour WAP,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,33</item>
- <item>[ApnSettingV3]VM WAP,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,52</item>
- <item>[ApnSettingV3]NRJWEB,ofnew.fr,,,orange,orange,,,,,208,01,1,DUN,,,true,0,,,,,,,gid,4E</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc208-mnc10/config.xml b/core/res/res/values-mcc208-mnc10/config.xml
index a32f266..d3640e5 100644
--- a/core/res/res/values-mcc208-mnc10/config.xml
+++ b/core/res/res/values-mcc208-mnc10/config.xml
@@ -29,11 +29,6 @@
<string-array translatable="false" name="config_tether_apndata">
<item>SFR option modem,websfr,,,,,,,,,208,10,,DUN</item>
<item>[ApnSettingV3]INTERNET NRJ,internetnrj,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4E</item>
- <item>[ApnSettingV3]Auchan,wap65,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,A MOBILE</item>
- <item>[ApnSettingV3]LeclercMobile,wap66,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,spn,LeclercMobile</item>
- <item>[ApnSettingV3]Coriolis,fnetcoriolis,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,12</item>
- <item>[ApnSettingV3]WEB La Poste Mobile,wapdebitel,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,4C</item>
- <item>[ApnSettingV3]Darty Surf Mails,wap68,,,,,,,,,208,10,,DUN,,,true,0,,,,,,,gid,44</item>
</string-array>
<string-array translatable="false" name="config_operatorConsideredNonRoaming">
diff --git a/core/res/res/values-mcc214-mnc07/config.xml b/core/res/res/values-mcc214-mnc07/config.xml
index 91571a5..4b7cc7c 100644
--- a/core/res/res/values-mcc214-mnc07/config.xml
+++ b/core/res/res/values-mcc214-mnc07/config.xml
@@ -28,7 +28,6 @@
note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN" -->
<string-array translatable="false" name="config_tether_apndata">
<item>Conexión Compartida,movistar.es,,,MOVISTAR,MOVISTAR,,,,,214,07,1,DUN</item>
- <item>[ApnSettingV3]Jazztel Internet,jazzinternet,,,,,,,,,214,07,,DUN,,,true,0,,,,,,,spn,JAZZTEL</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc222-mnc10/config.xml b/core/res/res/values-mcc222-mnc10/config.xml
index 5a74462..cd6e8c6 100644
--- a/core/res/res/values-mcc222-mnc10/config.xml
+++ b/core/res/res/values-mcc222-mnc10/config.xml
@@ -20,16 +20,6 @@
<!-- These resources are around just to allow their values to be customized
for different hardware and product builds. Do not translate. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
<!-- String containing the apn value for tethering. May be overriden by secure settings
TETHER_DUN_APN. Value is a comma separated series of strings:
"name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
diff --git a/core/res/res/values-mcc234-mnc20/config.xml b/core/res/res/values-mcc234-mnc20/config.xml
index 814960a..27c91d2 100644
--- a/core/res/res/values-mcc234-mnc20/config.xml
+++ b/core/res/res/values-mcc234-mnc20/config.xml
@@ -21,16 +21,6 @@
for different hardware and product builds. -->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Array of ConnectivityManager.TYPE_xxxx values allowable for tethering -->
- <!-- Common options are [1, 4] for TYPE_WIFI and TYPE_MOBILE_DUN or
- <!== [0,1,5,7] for TYPE_MOBILE, TYPE_WIFI, TYPE_MOBILE_HIPRI and TYPE_BLUETOOTH -->
- <integer-array translatable="false" name="config_tether_upstream_types">
- <item>1</item>
- <item>4</item>
- <item>7</item>
- <item>9</item>
- </integer-array>
-
<!-- String containing the apn value for tethering. May be overriden by secure settings
TETHER_DUN_APN. Value is a comma separated series of strings:
"name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 057790a..539baa5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1946,9 +1946,9 @@
See {@link com.android.server.notification.NotificationSignalExtractor} -->
<string-array name="config_notificationSignalExtractors">
<item>com.android.server.notification.ValidateNotificationPeople</item>
- <item>com.android.server.notification.PackagePriorityExtractor</item>
+ <item>com.android.server.notification.TopicPriorityExtractor</item>
<item>com.android.server.notification.NotificationIntrusivenessExtractor</item>
- <item>com.android.server.notification.PackageVisibilityExtractor</item>
+ <item>com.android.server.notification.TopicVisibilityExtractor</item>
</string-array>
<!-- Flag indicating that this device does not rotate and will always remain in its default
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 00c0fe8..1964bec 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4072,4 +4072,6 @@
<item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> selected</item>
<item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item>
</plurals>
+
+ <string name="default_notification_topic_label">Miscellaneous</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1e325b1..931b3f2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2337,4 +2337,5 @@
<java-symbol type="string" name="config_iccHotswapPromptForRestartDialogComponent" />
<java-symbol type="string" name="config_packagedKeyboardName" />
+ <java-symbol type="string" name="default_notification_topic_label" />
</resources>
diff --git a/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttf b/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttf
new file mode 100644
index 0000000..add3f40
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttf
Binary files differ
diff --git a/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttx b/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttx
new file mode 100644
index 0000000..7038f46
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/hasGlyphTestFont.ttx
@@ -0,0 +1,365 @@
+<?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.
+-->
+<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
+
+ <GlyphOrder>
+ <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+ <GlyphID id="0" name=".notdef"/>
+ <GlyphID id="1" name="BaseChar1"/>
+ <GlyphID id="2" name="BaseChar1_VS1"/>
+ <GlyphID id="3" name="BaseChar1_VS17"/>
+ <GlyphID id="4" name="BaseChar1_VS18"/>
+ <GlyphID id="5" name="BaseChar2"/>
+ <GlyphID id="6" name="BaseChar2_VS2"/>
+ <GlyphID id="7" name="BaseChar2_VS18"/>
+ <GlyphID id="8" name="BaseChar2_VS19"/>
+ <GlyphID id="9" name="BaseChar3"/>
+ <GlyphID id="10" name="BaseChar4_VS3"/>
+ <GlyphID id="11" name="BaseChar4_VS19"/>
+ <GlyphID id="12" name="BaseChar4_VS20"/>
+ <GlyphID id="13" name="BaseChar5"/>
+ <GlyphID id="14" name="BaseChar5_VS1"/>
+ <GlyphID id="15" name="BaseChar5_VS17"/>
+ <GlyphID id="16" name="BaseChar5_VS18"/>
+ <GlyphID id="17" name="BaseChar6"/>
+ <GlyphID id="18" name="BaseChar6_VS2"/>
+ <GlyphID id="19" name="BaseChar6_VS18"/>
+ <GlyphID id="20" name="BaseChar6_VS19"/>
+ <GlyphID id="21" name="BaseChar7"/>
+ <GlyphID id="22" name="BaseChar8_VS3"/>
+ <GlyphID id="23" name="BaseChar8_VS19"/>
+ <GlyphID id="24" name="BaseChar8_VS20"/>
+ </GlyphOrder>
+
+ <head>
+ <!-- Most of this table will be recalculated by the compiler -->
+ <tableVersion value="1.0"/>
+ <fontRevision value="1.0"/>
+ <checkSumAdjustment value="0x640cdb2f"/>
+ <magicNumber value="0x5f0f3cf5"/>
+ <flags value="00000000 00000011"/>
+ <unitsPerEm value="1000"/>
+ <created value="Wed Sep 9 08:01:17 2015"/>
+ <modified value="Wed Sep 9 08:48:07 2015"/>
+ <xMin value="30"/>
+ <yMin value="-200"/>
+ <xMax value="629"/>
+ <yMax value="800"/>
+ <macStyle value="00000000 00000000"/>
+ <lowestRecPPEM value="7"/>
+ <fontDirectionHint value="2"/>
+ <indexToLocFormat value="0"/>
+ <glyphDataFormat value="0"/>
+ </head>
+
+ <hhea>
+ <tableVersion value="1.0"/>
+ <ascent value="1000"/>
+ <descent value="-200"/>
+ <lineGap value="0"/>
+ <advanceWidthMax value="659"/>
+ <minLeftSideBearing value="0"/>
+ <minRightSideBearing value="30"/>
+ <xMaxExtent value="629"/>
+ <caretSlopeRise value="1"/>
+ <caretSlopeRun value="0"/>
+ <caretOffset value="0"/>
+ <reserved0 value="0"/>
+ <reserved1 value="0"/>
+ <reserved2 value="0"/>
+ <reserved3 value="0"/>
+ <metricDataFormat value="0"/>
+ <numberOfHMetrics value="18"/>
+ </hhea>
+
+ <maxp>
+ <!-- Most of this table will be recalculated by the compiler -->
+ <tableVersion value="0x10000"/>
+ <numGlyphs value="54"/>
+ <maxPoints value="73"/>
+ <maxContours value="10"/>
+ <maxCompositePoints value="0"/>
+ <maxCompositeContours value="0"/>
+ <maxZones value="2"/>
+ <maxTwilightPoints value="12"/>
+ <maxStorage value="28"/>
+ <maxFunctionDefs value="119"/>
+ <maxInstructionDefs value="0"/>
+ <maxStackElements value="61"/>
+ <maxSizeOfInstructions value="2967"/>
+ <maxComponentElements value="0"/>
+ <maxComponentDepth value="0"/>
+ </maxp>
+
+ <OS_2>
+ <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+ will be recalculated by the compiler -->
+ <version value="3"/>
+ <xAvgCharWidth value="594"/>
+ <usWeightClass value="400"/>
+ <usWidthClass value="5"/>
+ <fsType value="00000000 00001000"/>
+ <ySubscriptXSize value="650"/>
+ <ySubscriptYSize value="600"/>
+ <ySubscriptXOffset value="0"/>
+ <ySubscriptYOffset value="75"/>
+ <ySuperscriptXSize value="650"/>
+ <ySuperscriptYSize value="600"/>
+ <ySuperscriptXOffset value="0"/>
+ <ySuperscriptYOffset value="350"/>
+ <yStrikeoutSize value="50"/>
+ <yStrikeoutPosition value="300"/>
+ <sFamilyClass value="0"/>
+ <panose>
+ <bFamilyType value="0"/>
+ <bSerifStyle value="0"/>
+ <bWeight value="5"/>
+ <bProportion value="0"/>
+ <bContrast value="0"/>
+ <bStrokeVariation value="0"/>
+ <bArmStyle value="0"/>
+ <bLetterForm value="0"/>
+ <bMidline value="0"/>
+ <bXHeight value="0"/>
+ </panose>
+ <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
+ <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+ <achVendID value="UKWN"/>
+ <fsSelection value="00000000 01000000"/>
+ <usFirstCharIndex value="32"/>
+ <usLastCharIndex value="122"/>
+ <sTypoAscender value="800"/>
+ <sTypoDescender value="-200"/>
+ <sTypoLineGap value="200"/>
+ <usWinAscent value="1000"/>
+ <usWinDescent value="200"/>
+ <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
+ <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+ <sxHeight value="500"/>
+ <sCapHeight value="700"/>
+ <usDefaultChar value="0"/>
+ <usBreakChar value="32"/>
+ <usMaxContext value="0"/>
+ </OS_2>
+
+ <hmtx>
+ <mtx name=".notdef" width="500" lsb="93"/>
+ <mtx name="BaseChar1" width="500" lsb="93"/>
+ <mtx name="BaseChar1_VS1" width="500" lsb="93"/>
+ <mtx name="BaseChar1_VS17" width="500" lsb="93"/>
+ <mtx name="BaseChar1_VS18" width="500" lsb="93"/>
+ <mtx name="BaseChar2" width="500" lsb="93"/>
+ <mtx name="BaseChar2_VS2" width="500" lsb="93"/>
+ <mtx name="BaseChar2_VS18" width="500" lsb="93"/>
+ <mtx name="BaseChar2_VS19" width="500" lsb="93"/>
+ <mtx name="BaseChar3" width="500" lsb="93"/>
+ <mtx name="BaseChar4_VS3" width="500" lsb="93"/>
+ <mtx name="BaseChar4_VS19" width="500" lsb="93"/>
+ <mtx name="BaseChar4_VS20" width="500" lsb="93"/>
+ <mtx name="BaseChar5" width="500" lsb="93"/>
+ <mtx name="BaseChar5_VS1" width="500" lsb="93"/>
+ <mtx name="BaseChar5_VS17" width="500" lsb="93"/>
+ <mtx name="BaseChar5_VS18" width="500" lsb="93"/>
+ <mtx name="BaseChar6" width="500" lsb="93"/>
+ <mtx name="BaseChar6_VS2" width="500" lsb="93"/>
+ <mtx name="BaseChar6_VS18" width="500" lsb="93"/>
+ <mtx name="BaseChar6_VS19" width="500" lsb="93"/>
+ <mtx name="BaseChar7" width="500" lsb="93"/>
+ <mtx name="BaseChar8_VS3" width="500" lsb="93"/>
+ <mtx name="BaseChar8_VS19" width="500" lsb="93"/>
+ <mtx name="BaseChar8_VS20" width="500" lsb="93"/>
+ </hmtx>
+
+ <cmap>
+ <tableVersion version="0"/>
+ <cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0">
+ <map code="0x0061" name="BaseChar1" />
+ <map code="0x0062" name="BaseChar2" />
+ <map code="0x0063" name="BaseChar3" />
+ <!-- No cmap4 entry for BaseChar4 -->
+ <map code="0x1F000" name="BaseChar5" />
+ <map code="0x1F001" name="BaseChar6" />
+ <map code="0x1F002" name="BaseChar7" />
+ <!-- No cmap4 entry for BaseChar8 -->
+ </cmap_format_12>
+ <cmap_format_14 format="14" platformID="0" platEncID="5" length="24" numVarSelectorRecords="3">
+ <map uvs="0xFE00" uv="0x0061" name="BaseChar1_VS1" />
+ <map uvs="0xE0100" uv="0x0061" name="BaseChar1_VS17" />
+ <map uvs="0xE0101" uv="0x0061" name="BaseChar1_VS18" />
+ <map uvs="0xE0102" uv="0x0061" name="None" />
+
+ <map uvs="0xFE01" uv="0x0062" name="BaseChar2_VS2" />
+ <map uvs="0xE0101" uv="0x0062" name="BaseChar2_VS18" />
+ <map uvs="0xE0102" uv="0x0062" name="BaseChar2_VS19" />
+ <map uvs="0xE0103" uv="0x0062" name="None" />
+
+ <map uvs="0xFE02" uv="0x0064" name="BaseChar4_VS3" />
+ <map uvs="0xE0102" uv="0x0064" name="BaseChar4_VS19" />
+ <map uvs="0xE0103" uv="0x0064" name="BaseChar4_VS20" />
+ <!-- There is no default glyph for U+0064 U+E0104 but there is a entry for
+ default UVS entry. hasGlyph should return false in this
+ case. -->
+ <map uvs="0xE0104" uv="0x0064" name="None" />
+
+ <map uvs="0xFE00" uv="0x1F000" name="BaseChar5_VS1" />
+ <map uvs="0xE0100" uv="0x1F000" name="BaseChar5_VS17" />
+ <map uvs="0xE0101" uv="0x1F000" name="BaseChar5_VS18" />
+ <map uvs="0xE0102" uv="0x1F000" name="None" />
+
+ <map uvs="0xFE01" uv="0x1F001" name="BaseChar6_VS2" />
+ <map uvs="0xE0101" uv="0x1F001" name="BaseChar6_VS18" />
+ <map uvs="0xE0102" uv="0x1F001" name="BaseChar6_VS19" />
+ <map uvs="0xE0103" uv="0x1F001" name="None" />
+
+ <map uvs="0xFE02" uv="0x1F003" name="BaseChar8_VS3" />
+ <map uvs="0xE0102" uv="0x1F003" name="BaseChar8_VS19" />
+ <map uvs="0xE0103" uv="0x1F003" name="BaseChar8_VS20" />
+ <!-- There is no default glyph for U+1F003 U+E0104 but there is a entry for
+ default UVS entry. hasGlyph should return false in this
+ case. -->
+ <map uvs="0xE0104" uv="0x1F003" name="None" />
+ </cmap_format_14>
+ </cmap>
+
+ <loca>
+ <!-- The 'loca' table will be calculated by the compiler -->
+ </loca>
+
+ <glyf>
+
+ <!-- The xMin, yMin, xMax and yMax values
+ will be recalculated by the compiler. -->
+
+ <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+
+ <TTGlyph name="BaseChar1" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar1_VS1" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar1_VS17" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar1_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar2" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar2_VS2" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar2_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar2_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar3" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar4_VS3" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar4_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar4_VS20" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar5" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar5_VS1" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar5_VS17" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar5_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar6" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar6_VS2" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar6_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar6_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar7" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar8_VS3" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar8_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ <TTGlyph name="BaseChar8_VS20" xMin="0" yMin="0" xMax="0" yMax="0">
+ <contour></contour><instructions><assembly></assembly></instructions>
+ </TTGlyph>
+ </glyf>
+
+ <name>
+ <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
+ Paint.hasGlyph Test
+ </namerecord>
+ <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
+ Regular
+ </namerecord>
+ <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
+ Paint.hasGlyph Test
+ </namerecord>
+ <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
+ hasGlyphTestFont-Regular
+ </namerecord>
+ <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+ Paint.hasGlyph Test
+ </namerecord>
+ <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+ Regular
+ </namerecord>
+ <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+ hasGlyphTestFont Test
+ </namerecord>
+ <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+ hasGlyphTestFont-Regular
+ </namerecord>
+ </name>
+
+ <post>
+ <formatType value="3.0"/>
+ <italicAngle value="0.0"/>
+ <underlinePosition value="-75"/>
+ <underlineThickness value="50"/>
+ <isFixedPitch value="0"/>
+ <minMemType42 value="0"/>
+ <maxMemType42 value="0"/>
+ <minMemType1 value="0"/>
+ <maxMemType1 value="0"/>
+ </post>
+
+</ttFont>
diff --git a/core/tests/coretests/src/android/graphics/PaintTest.java b/core/tests/coretests/src/android/graphics/PaintTest.java
index e97bb33..2a3d463 100644
--- a/core/tests/coretests/src/android/graphics/PaintTest.java
+++ b/core/tests/coretests/src/android/graphics/PaintTest.java
@@ -20,6 +20,9 @@
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import java.util.Arrays;
+import java.util.HashSet;
+
/**
* PaintTest tests {@link Paint}.
*/
@@ -94,4 +97,63 @@
testCase.mWidthWithHinting, widths);
}
}
+
+ private static class HasGlyphTestCase {
+ public final int mBaseCodepoint;
+ public final HashSet<Integer> mVariationSelectors;
+
+ public HasGlyphTestCase(int baseCodepoint, Integer[] variationSelectors) {
+ mBaseCodepoint = baseCodepoint;
+ mVariationSelectors = new HashSet<>(Arrays.asList(variationSelectors));
+ }
+ }
+
+ private static String codePointsToString(int[] codepoints) {
+ StringBuilder sb = new StringBuilder();
+ for (int codepoint : codepoints) {
+ sb.append(Character.toChars(codepoint));
+ }
+ return sb.toString();
+ }
+
+ public void testHasGlyph_variationSelectors() {
+ final Typeface fontTypeface = Typeface.createFromAsset(
+ getInstrumentation().getContext().getAssets(), "fonts/hasGlyphTestFont.ttf");
+ Paint p = new Paint();
+ p.setTypeface(fontTypeface);
+
+ // Usually latin letters U+0061..U+0064 and Mahjong Tiles U+1F000..U+1F003 don't have
+ // variation selectors. This test may fail if system pre-installed fonts have a variation
+ // selector support for U+0061..U+0064 and U+1F000..U+1F003.
+ HasGlyphTestCase[] HAS_GLYPH_TEST_CASES = {
+ new HasGlyphTestCase(0x0061, new Integer[] {0xFE00, 0xE0100, 0xE0101, 0xE0102}),
+ new HasGlyphTestCase(0x0062, new Integer[] {0xFE01, 0xE0101, 0xE0102, 0xE0103}),
+ new HasGlyphTestCase(0x0063, new Integer[] {}),
+ new HasGlyphTestCase(0x0064, new Integer[] {0xFE02, 0xE0102, 0xE0103}),
+
+ new HasGlyphTestCase(0x1F000, new Integer[] {0xFE00, 0xE0100, 0xE0101, 0xE0102}),
+ new HasGlyphTestCase(0x1F001, new Integer[] {0xFE01, 0xE0101, 0xE0102, 0xE0103}),
+ new HasGlyphTestCase(0x1F002, new Integer[] {}),
+ new HasGlyphTestCase(0x1F003, new Integer[] {0xFE02, 0xE0102, 0xE0103}),
+ };
+
+ for (HasGlyphTestCase testCase : HAS_GLYPH_TEST_CASES) {
+ for (int vs = 0xFE00; vs <= 0xE01EF; ++vs) {
+ // Move to variation selector supplements after variation selectors.
+ if (vs == 0xFF00) {
+ vs = 0xE0100;
+ }
+ final String signature =
+ "hasGlyph(U+" + Integer.toHexString(testCase.mBaseCodepoint) +
+ " U+" + Integer.toHexString(vs) + ")";
+ final String testString =
+ codePointsToString(new int[] {testCase.mBaseCodepoint, vs});
+ if (testCase.mVariationSelectors.contains(vs)) {
+ assertTrue(signature + " is expected to be true", p.hasGlyph(testString));
+ } else {
+ assertFalse(signature + " is expected to be false", p.hasGlyph(testString));
+ }
+ }
+ }
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
new file mode 100644
index 0000000..951e87a
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/HexDumpTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011 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 com.android.internal.util;
+
+import junit.framework.TestCase;
+
+public final class HexDumpTest extends TestCase {
+ public void testBytesToHexString() {
+ assertEquals("abcdef", HexDump.toHexString(
+ new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, false));
+ assertEquals("ABCDEF", HexDump.toHexString(
+ new byte[] { (byte) 0xab, (byte) 0xcd, (byte) 0xef }, true));
+ }
+}
diff --git a/data/keyboards/qwerty.kl b/data/keyboards/qwerty.kl
index 58bf654..4186007 100644
--- a/data/keyboards/qwerty.kl
+++ b/data/keyboards/qwerty.kl
@@ -81,7 +81,7 @@
key 39 SEMICOLON
key 40 APOSTROPHE
key 14 DEL
-
+
key 44 Z
key 45 X
key 46 C
@@ -93,7 +93,7 @@
key 52 PERIOD
key 53 SLASH
key 28 ENTER
-
+
key 56 ALT_LEFT
key 100 ALT_RIGHT
key 42 SHIFT_LEFT
@@ -101,7 +101,7 @@
key 15 TAB
key 57 SPACE
key 150 EXPLORER
-key 155 ENVELOPE
+key 155 ENVELOPE
key 12 MINUS
key 13 EQUALS
@@ -110,3 +110,16 @@
# On an AT keyboard: ESC, F10
key 1 BACK
key 68 MENU
+
+# App switch = Overview key
+key 580 APP_SWITCH
+
+# Media control keys
+key 160 MEDIA_CLOSE
+key 161 MEDIA_EJECT
+key 163 MEDIA_NEXT
+key 164 MEDIA_PLAY_PAUSE
+key 165 MEDIA_PREVIOUS
+key 166 MEDIA_STOP
+key 167 MEDIA_RECORD
+key 168 MEDIA_REWIND
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index d45345e..595928a 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -71,7 +71,7 @@
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<intent-filter>
- <action android:name="android.provider.action.BROWSE_DOCUMENT_ROOT" />
+ <action android:name="android.provider.action.BROWSE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.document/root" />
</intent-filter>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index e965050..4f4649c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -172,6 +172,11 @@
Intent.EXTRA_ALLOW_MULTIPLE, false);
}
+ if (state.action == ACTION_OPEN || state.action == ACTION_GET_CONTENT
+ || state.action == ACTION_CREATE) {
+ state.openableOnly = intent.hasCategory(Intent.CATEGORY_OPENABLE);
+ }
+
if (state.action == ACTION_PICK_COPY_DESTINATION) {
state.directoryCopy = intent.getBooleanExtra(
Shared.EXTRA_DIRECTORY_COPY, false);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java
index 49a1e66..c81d4fb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/State.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/State.java
@@ -52,6 +52,7 @@
public boolean stackTouched;
public boolean restored;
public boolean directoryCopy;
+ public boolean openableOnly;
/** Transfer mode for file copy/move operations. */
public int transferMode;
@@ -119,6 +120,7 @@
out.writeMap(dirState);
out.writeList(selectedDocumentsForCopy);
out.writeList(excludedAuthorities);
+ out.writeInt(openableOnly ? 1 : 0);
}
public static final Creator<State> CREATOR = new Creator<State>() {
@@ -142,6 +144,7 @@
in.readMap(state.dirState, null);
in.readList(state.selectedDocumentsForCopy, null);
in.readList(state.excludedAuthorities, null);
+ state.openableOnly = in.readInt() != 0;
return state;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index 8b3893f..b0421b0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -660,8 +660,7 @@
checkNotNull(cursor, "Cursor cannot be null.");
final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS);
- return mTuner.canSelectType(docMimeType)
- && mTuner.isDocumentEnabled(docMimeType, docFlags);
+ return mTuner.canSelectType(docMimeType, docFlags);
}
return true;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
index a0ff165..38d3805 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java
@@ -63,7 +63,7 @@
// Subtly different from isDocumentEnabled. The reason may be illuminated as follows.
// A folder is enabled such that it may be double clicked, even in settings
// when the folder itself cannot be selected. This may also be true of container types.
- public boolean canSelectType(String docMimeType) {
+ public boolean canSelectType(String docMimeType, int docFlags) {
return true;
}
@@ -85,31 +85,44 @@
}
@Override
- public boolean canSelectType(String docMimeType) {
- switch (mState.action) {
- case ACTION_OPEN:
- case ACTION_CREATE:
- case ACTION_GET_CONTENT:
- return !isDirectory(docMimeType);
- case ACTION_OPEN_TREE:
- // In this case nothing *ever* is selectable...the expected user behavior is
- // they navigate *into* a folder, then click a confirmation button indicating
- // that the current directory is the directory they are picking.
- return false;
+ public boolean canSelectType(String docMimeType, int docFlags) {
+ if (!isDocumentEnabled(docMimeType, docFlags)) {
+ return false;
}
+
+ if (isDirectory(docMimeType)) {
+ return false;
+ }
+
+ if (mState.action == ACTION_OPEN_TREE) {
+ // In this case nothing *ever* is selectable...the expected user behavior is
+ // they navigate *into* a folder, then click a confirmation button indicating
+ // that the current directory is the directory they are picking.
+ return false;
+ }
+
return true;
}
@Override
public boolean isDocumentEnabled(String docMimeType, int docFlags) {
- // Directories are always enabled
+ // Directories are always enabled.
if (isDirectory(docMimeType)) {
return true;
}
- // Read-only files are disabled when creating
- if (mState.action == ACTION_CREATE && (docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
- return false;
+ switch (mState.action) {
+ case ACTION_CREATE:
+ // Read-only files are disabled when creating.
+ if ((docFlags & Document.FLAG_SUPPORTS_WRITE) == 0) {
+ return false;
+ }
+ case ACTION_OPEN:
+ case ACTION_GET_CONTENT:
+ final boolean isVirtual = (docFlags & Document.FLAG_VIRTUAL_DOCUMENT) != 0;
+ if (isVirtual && mState.openableOnly) {
+ return false;
+ }
}
return MimePredicate.mimeMatches(mState.acceptMimes, docMimeType);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b9a9c24..2e96f18 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -159,6 +159,7 @@
String key_mgmt = "";
boolean certUsed = false;
boolean hasWepKey = false;
+ boolean isEap = false;
final ArrayList<String> rawLines = new ArrayList<String>();
public static Network readFromStream(BufferedReader in) {
@@ -189,6 +190,9 @@
ssid = line;
} else if (line.startsWith("key_mgmt=")) {
key_mgmt = line;
+ if (line.contains("EAP")) {
+ isEap = true;
+ }
} else if (line.startsWith("client_cert=")) {
certUsed = true;
} else if (line.startsWith("ca_cert=")) {
@@ -197,6 +201,8 @@
certUsed = true;
} else if (line.startsWith("wep_")) {
hasWepKey = true;
+ } else if (line.startsWith("eap=")) {
+ isEap = true;
}
}
@@ -325,6 +331,13 @@
continue;
}
}
+ // Don't propagate EAP network definitions
+ if (net.isEap) {
+ if (DEBUG_BACKUP) {
+ Log.v(TAG, "Skipping EAP network " + net.ssid + " / " + net.key_mgmt);
+ }
+ continue;
+ }
if (! mKnownNetworks.contains(net)) {
if (DEBUG_BACKUP) {
Log.v(TAG, "Adding " + net.ssid + " / " + net.key_mgmt);
@@ -353,6 +366,12 @@
continue;
}
+ if (net.isEap) {
+ // Similarly, omit EAP network definitions to avoid propagating
+ // controlled enterprise network definitions.
+ continue;
+ }
+
net.write(w);
}
}
diff --git a/preloaded-classes b/preloaded-classes
index e48255c..79c0957 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -3560,11 +3560,6 @@
org.apache.harmony.security.asn1.BerOutputStream
org.apache.harmony.security.asn1.DerInputStream
org.apache.harmony.security.asn1.DerOutputStream
-org.apache.harmony.security.fortress.Engine
-org.apache.harmony.security.fortress.Engine$ServiceCacheEntry
-org.apache.harmony.security.fortress.Engine$SpiAndProvider
-org.apache.harmony.security.fortress.SecurityAccess
-org.apache.harmony.security.fortress.Services
org.apache.harmony.security.provider.crypto.CryptoProvider
org.apache.harmony.security.utils.AlgNameMapper
org.apache.harmony.security.utils.AlgNameMapperSource
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b7ce3221..29173a5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15468,6 +15468,10 @@
pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
- totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- memInfo.getKernelUsedSizeKb()));
+ } else {
+ pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
+ - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
+ - memInfo.getKernelUsedSizeKb());
}
if (!brief) {
if (memInfo.getZramTotalSizeKb() != 0) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 3fc6846..02cf87a 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1277,7 +1277,7 @@
}
final Configuration serviceConfig = mService.mConfiguration;
- mOverrideConfig = new Configuration(serviceConfig);
+ mOverrideConfig = new Configuration(Configuration.EMPTY);
// TODO(multidisplay): Update Dp to that of display stack is on.
final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
mOverrideConfig.screenWidthDp =
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4424838..946fbb1 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1211,29 +1211,36 @@
}
@Override
- public void setPackagePriority(String pkg, int uid, int priority) {
+ public ParceledListSlice<Notification.Topic> getTopics(String pkg, int uid) {
checkCallerIsSystem();
- mRankingHelper.setPackagePriority(pkg, uid, priority);
+ return new ParceledListSlice<Notification.Topic>(mRankingHelper.getTopics(pkg, uid));
+ }
+
+ @Override
+ public void setTopicPriority(String pkg, int uid, Notification.Topic topic, int priority) {
+ checkCallerIsSystem();
+ mRankingHelper.setTopicPriority(pkg, uid, topic, priority);
savePolicyFile();
}
@Override
- public int getPackagePriority(String pkg, int uid) {
+ public int getTopicPriority(String pkg, int uid, Notification.Topic topic) {
checkCallerIsSystem();
- return mRankingHelper.getPackagePriority(pkg, uid);
+ return mRankingHelper.getTopicPriority(pkg, uid, topic);
}
@Override
- public void setPackageVisibilityOverride(String pkg, int uid, int visibility) {
+ public void setTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic,
+ int visibility) {
checkCallerIsSystem();
- mRankingHelper.setPackageVisibilityOverride(pkg, uid, visibility);
+ mRankingHelper.setTopicVisibilityOverride(pkg, uid, topic, visibility);
savePolicyFile();
}
@Override
- public int getPackageVisibilityOverride(String pkg, int uid) {
+ public int getTopicVisibilityOverride(String pkg, int uid, Notification.Topic topic) {
checkCallerIsSystem();
- return mRankingHelper.getPackageVisibilityOverride(pkg, uid);
+ return mRankingHelper.getTopicVisibilityOverride(pkg, uid, topic);
}
/**
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index aea137b..7ee29e4 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -15,12 +15,20 @@
*/
package com.android.server.notification;
+import android.app.Notification;
+
+import java.util.List;
+
public interface RankingConfig {
- int getPackagePriority(String packageName, int uid);
- void setPackagePriority(String packageName, int uid, int priority);
+ List<Notification.Topic> getTopics(String packageName, int uid);
- int getPackageVisibilityOverride(String packageName, int uid);
+ int getTopicPriority(String packageName, int uid, Notification.Topic topic);
- void setPackageVisibilityOverride(String packageName, int uid, int visibility);
+ void setTopicPriority(String packageName, int uid, Notification.Topic topic, int priority);
+
+ int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic);
+
+ void setTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic,
+ int visibility);
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index f8b661f..4d33248 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -27,6 +27,8 @@
import android.util.ArrayMap;
import android.util.Slog;
+import com.android.internal.R;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -35,6 +37,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
public class RankingHelper implements RankingConfig {
@@ -45,11 +49,14 @@
private static final String TAG_RANKING = "ranking";
private static final String TAG_PACKAGE = "package";
private static final String ATT_VERSION = "version";
+ private static final String TAG_TOPIC = "topic";
private static final String ATT_NAME = "name";
private static final String ATT_UID = "uid";
private static final String ATT_PRIORITY = "priority";
private static final String ATT_VISIBILITY = "visibility";
+ private static final String ATT_TOPIC_ID = "id";
+ private static final String ATT_TOPIC_LABEL = "label";
private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
private static final int DEFAULT_VISIBILITY =
@@ -161,12 +168,14 @@
} else {
r = getOrCreateRecord(name, uid);
}
- if (priority != DEFAULT_PRIORITY) {
- r.priority = priority;
- }
- if (vis != DEFAULT_VISIBILITY) {
- r.visibility = vis;
- }
+
+ // Migrate package level settings to the default topic.
+ // Might be overwritten by parseTopics.
+ Topic defaultTopic = r.topics.get(Notification.TOPIC_DEFAULT);
+ defaultTopic.priority = priority;
+ defaultTopic.visibility = vis;
+
+ parseTopics(r, parser);
}
}
}
@@ -174,6 +183,38 @@
throw new IllegalStateException("Failed to reach END_DOCUMENT");
}
+ public void parseTopics(Record r, XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ final int innerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (TAG_TOPIC.equals(tagName)) {
+ int priority = safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+ int vis = safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
+ String id = parser.getAttributeValue(null, ATT_TOPIC_ID);
+ CharSequence label = parser.getAttributeValue(null, ATT_TOPIC_LABEL);
+
+ if (!TextUtils.isEmpty(id)) {
+ Topic topic = new Topic(new Notification.Topic(id, label));
+
+ if (priority != DEFAULT_PRIORITY) {
+ topic.priority = priority;
+ }
+ if (vis != DEFAULT_VISIBILITY) {
+ topic.visibility = vis;
+ }
+ r.topics.put(id, topic);
+ }
+ }
+ }
+ }
+
private static String recordKey(String pkg, int uid) {
return pkg + "|" + uid;
}
@@ -185,21 +226,14 @@
r = new Record();
r.pkg = pkg;
r.uid = uid;
+ r.topics.put(Notification.TOPIC_DEFAULT,
+ new Topic(new Notification.Topic(Notification.TOPIC_DEFAULT,
+ mContext.getString(R.string.default_notification_topic_label))));
mRecords.put(key, r);
}
return r;
}
- private void removeDefaultRecords() {
- final int N = mRecords.size();
- for (int i = N - 1; i >= 0; i--) {
- final Record r = mRecords.valueAt(i);
- if (r.priority == DEFAULT_PRIORITY && r.visibility == DEFAULT_VISIBILITY) {
- mRecords.remove(i);
- }
- }
- }
-
public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
out.startTag(null, TAG_RANKING);
out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
@@ -213,20 +247,32 @@
}
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATT_NAME, r.pkg);
- if (r.priority != DEFAULT_PRIORITY) {
- out.attribute(null, ATT_PRIORITY, Integer.toString(r.priority));
- }
- if (r.visibility != DEFAULT_VISIBILITY) {
- out.attribute(null, ATT_VISIBILITY, Integer.toString(r.visibility));
- }
+
if (!forBackup) {
out.attribute(null, ATT_UID, Integer.toString(r.uid));
}
+
+ writeTopicsXml(out, r);
out.endTag(null, TAG_PACKAGE);
}
out.endTag(null, TAG_RANKING);
}
+ public void writeTopicsXml(XmlSerializer out, Record r) throws IOException {
+ for (Topic t : r.topics.values()) {
+ out.startTag(null, TAG_TOPIC);
+ out.attribute(null, ATT_TOPIC_ID, t.topic.getId());
+ out.attribute(null, ATT_TOPIC_LABEL, t.topic.getLabel().toString());
+ if (t.priority != DEFAULT_PRIORITY) {
+ out.attribute(null, ATT_PRIORITY, Integer.toString(t.priority));
+ }
+ if (t.visibility != DEFAULT_VISIBILITY) {
+ out.attribute(null, ATT_VISIBILITY, Integer.toString(t.visibility));
+ }
+ out.endTag(null, TAG_TOPIC);
+ }
+ }
+
private void updateConfig() {
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
@@ -322,37 +368,54 @@
}
@Override
- public int getPackagePriority(String packageName, int uid) {
- final Record r = mRecords.get(recordKey(packageName, uid));
- return r != null ? r.priority : DEFAULT_PRIORITY;
+ public List<Notification.Topic> getTopics(String packageName, int uid) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ List<Notification.Topic> topics = new ArrayList<>();
+ for (Topic t : r.topics.values()) {
+ topics.add(t.topic);
+ }
+ return topics;
}
@Override
- public void setPackagePriority(String packageName, int uid, int priority) {
- if (priority == getPackagePriority(packageName, uid)) {
- return;
- }
- getOrCreateRecord(packageName, uid).priority = priority;
- removeDefaultRecords();
+ public int getTopicPriority(String packageName, int uid, Notification.Topic topic) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ return getOrCreateTopic(r, topic).priority;
+ }
+
+ @Override
+ public void setTopicPriority(String packageName, int uid, Notification.Topic topic,
+ int priority) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ getOrCreateTopic(r, topic).priority = priority;
updateConfig();
}
@Override
- public int getPackageVisibilityOverride(String packageName, int uid) {
- final Record r = mRecords.get(recordKey(packageName, uid));
- return r != null ? r.visibility : DEFAULT_VISIBILITY;
+ public int getTopicVisibilityOverride(String packageName, int uid, Notification.Topic topic) {
+ final Record r = getOrCreateRecord(packageName, uid);
+ return getOrCreateTopic(r, topic).visibility;
}
@Override
- public void setPackageVisibilityOverride(String packageName, int uid, int visibility) {
- if (visibility == getPackageVisibilityOverride(packageName, uid)) {
- return;
- }
- getOrCreateRecord(packageName, uid).visibility = visibility;
- removeDefaultRecords();
+ public void setTopicVisibilityOverride(String pkgName, int uid, Notification.Topic topic,
+ int visibility) {
+ final Record r = getOrCreateRecord(pkgName, uid);
+ getOrCreateTopic(r, topic).visibility = visibility;
updateConfig();
}
+ private Topic getOrCreateTopic(Record r, Notification.Topic topic) {
+ Topic t = r.topics.get(topic.getId());
+ if (t != null) {
+ return t;
+ } else {
+ t = new Topic(topic);
+ r.topics.put(topic.getId(), t);
+ return t;
+ }
+ }
+
public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
if (filter == null) {
final int N = mSignalExtractors.length;
@@ -385,15 +448,22 @@
pw.print(" (");
pw.print(r.uid == Record.UNKNOWN_UID ? "UNKNOWN_UID" : Integer.toString(r.uid));
pw.print(')');
- if (r.priority != DEFAULT_PRIORITY) {
- pw.print(" priority=");
- pw.print(Notification.priorityToString(r.priority));
- }
- if (r.visibility != DEFAULT_VISIBILITY) {
- pw.print(" visibility=");
- pw.print(Notification.visibilityToString(r.visibility));
- }
pw.println();
+ for (Topic t : r.topics.values()) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print(" ");
+ pw.print(t.topic.getId());
+ if (t.priority != DEFAULT_PRIORITY) {
+ pw.print(" priority=");
+ pw.print(Notification.priorityToString(t.priority));
+ }
+ if (t.visibility != DEFAULT_VISIBILITY) {
+ pw.print(" visibility=");
+ pw.print(Notification.visibilityToString(t.visibility));
+ }
+ pw.println();
+ }
}
}
}
@@ -429,8 +499,16 @@
String pkg;
int uid = UNKNOWN_UID;
+ Map<String, Topic> topics = new ArrayMap<>();
+ }
+
+ private static class Topic {
+ Notification.Topic topic;
int priority = DEFAULT_PRIORITY;
int visibility = DEFAULT_VISIBILITY;
- }
+ public Topic(Notification.Topic topic) {
+ this.topic = topic;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/PackagePriorityExtractor.java b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
similarity index 79%
rename from services/core/java/com/android/server/notification/PackagePriorityExtractor.java
rename to services/core/java/com/android/server/notification/TopicPriorityExtractor.java
index 6beed9c..5bf989ae 100644
--- a/services/core/java/com/android/server/notification/PackagePriorityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicPriorityExtractor.java
@@ -18,8 +18,11 @@
import android.content.Context;
import android.util.Slog;
-public class PackagePriorityExtractor implements NotificationSignalExtractor {
- private static final String TAG = "ImportantPackageExtractor";
+/**
+ * Determines if the given notification can bypass Do Not Disturb.
+ */
+public class TopicPriorityExtractor implements NotificationSignalExtractor {
+ private static final String TAG = "ImportantTopicExtractor";
private static final boolean DBG = false;
private RankingConfig mConfig;
@@ -39,8 +42,8 @@
return null;
}
- final int packagePriority = mConfig.getPackagePriority(
- record.sbn.getPackageName(), record.sbn.getUid());
+ final int packagePriority = mConfig.getTopicPriority(record.sbn.getPackageName(),
+ record.sbn.getUid(), record.sbn.getNotification().getTopic());
record.setPackagePriority(packagePriority);
return null;
diff --git a/services/core/java/com/android/server/notification/PackageVisibilityExtractor.java b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
similarity index 80%
rename from services/core/java/com/android/server/notification/PackageVisibilityExtractor.java
rename to services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
index af99db7..e053382 100644
--- a/services/core/java/com/android/server/notification/PackageVisibilityExtractor.java
+++ b/services/core/java/com/android/server/notification/TopicVisibilityExtractor.java
@@ -18,8 +18,11 @@
import android.content.Context;
import android.util.Slog;
-public class PackageVisibilityExtractor implements NotificationSignalExtractor {
- private static final String TAG = "PackageVisibilityExtractor";
+/**
+ * Determines if the given notification can display sensitive content on the lockscreen.
+ */
+public class TopicVisibilityExtractor implements NotificationSignalExtractor {
+ private static final String TAG = "TopicVisibilityExtractor";
private static final boolean DBG = false;
private RankingConfig mConfig;
@@ -39,8 +42,9 @@
return null;
}
- final int packageVisibility = mConfig.getPackageVisibilityOverride(
- record.sbn.getPackageName(), record.sbn.getUid());
+ final int packageVisibility = mConfig.getTopicVisibilityOverride(
+ record.sbn.getPackageName(), record.sbn.getUid(),
+ record.sbn.getNotification().getTopic());
record.setPackageVisibilityOverride(packageVisibility);
return null;
diff --git a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index 8fc979c..cc25c8c 100644
--- a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -17,6 +17,7 @@
package com.android.server.updates;
import com.android.server.EventLogTags;
+import com.android.internal.util.HexDump;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -155,7 +156,7 @@
try {
MessageDigest dgst = MessageDigest.getInstance("SHA512");
byte[] fingerprint = dgst.digest(content);
- return IntegralToString.bytesToHexString(fingerprint, false);
+ return HexDump.toHexString(fingerprint, false);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 8085f13..04ab544 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -515,10 +515,11 @@
for (int i = 0; i < count; i++) {
final TaskStack otherStack = mService.mStackIdToStack.valueAt(i);
final int otherStackId = otherStack.mStackId;
- if (StackId.isResizeableByDockedStack(otherStackId)) {
+ if (StackId.isResizeableByDockedStack(otherStackId)
+ && !otherStack.mBounds.equals(bounds)) {
mService.mH.sendMessage(
mService.mH.obtainMessage(RESIZE_STACK, otherStackId,
- 1 /*allowResizeInDockedMode*/, bounds));
+ 1 /*allowResizeInDockedMode*/, fullscreen ? null : bounds));
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 253fdad..b6600266 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2863,7 +2863,11 @@
// notifying the client to render to with an offset from the surface's top-left.
if (win.isDragResizeChanged()) {
win.setDragResizing();
- if (win.mHasSurface) {
+ // We can only change top level windows to the full-screen surface when
+ // resizing (as we only have one full-screen surface). So there is no need
+ // to preserve and destroy windows which are attached to another, they
+ // will keep their surface and its size may change over time.
+ if (win.mHasSurface && win.mAttachedWindow == null) {
winAnimator.preserveSurfaceLocked();
result |= WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME;
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 6faf3a7..004307e 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -735,7 +735,12 @@
if (mSurfaceController != null) {
int i = mWin.mChildWindows.size();
- while (i > 0) {
+ // When destroying a surface we want to make sure child windows
+ // are hidden. If we are preserving the surface until redraw though
+ // we intend to swap it out with another surface for resizing. In this case
+ // the window always remains visible to the user and the child windows
+ // should likewise remain visable.
+ while (!mDestroyPreservedSurfaceUponRedraw && i > 0) {
i--;
WindowState c = mWin.mChildWindows.get(i);
c.mAttachedHidden = true;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e59c6f8..642def3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5718,11 +5718,18 @@
}
@Override
- public Bundle getUserRestrictions(ComponentName who) {
+ public Bundle getUserRestrictions(ComponentName who, int userHandle) {
Preconditions.checkNotNull(who, "ComponentName is null");
+ enforceCrossUserPermission(userHandle);
synchronized (this) {
- final ActiveAdmin activeAdmin =
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ ActiveAdmin activeAdmin = getActiveAdminUncheckedLocked(who, userHandle);
+ if (activeAdmin == null) {
+ throw new SecurityException("No active admin: " + activeAdmin);
+ }
+ if (activeAdmin.getUid() != mInjector.binderGetCallingUid()) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null);
+ }
return activeAdmin.userRestrictions;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java b/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java
index b6742a1..d798518 100644
--- a/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java
+++ b/services/tests/servicestests/src/com/android/server/updates/CertPinInstallReceiverTest.java
@@ -16,6 +16,8 @@
package com.android.server.updates;
+import com.android.internal.util.HexDump;
+
import android.content.Context;
import android.content.Intent;
import android.test.AndroidTestCase;
@@ -128,7 +130,7 @@
MessageDigest dgst = MessageDigest.getInstance("SHA512");
byte[] encoded = content.getBytes();
byte[] fingerprint = dgst.digest(encoded);
- return IntegralToString.bytesToHexString(fingerprint, false);
+ return HexDump.toHexString(fingerprint, false);
}
private static String getHashOfCurrentContent() throws Exception {
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index b12795c..68bde35 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -20,7 +20,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := core-libart core-junit framework
+LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit framework
LOCAL_STATIC_JAVA_LIBRARIES := junit-runner
LOCAL_MODULE:= android.test.runner
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 67b9d77..8eb30d2 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -160,6 +160,36 @@
}
},
+ new Test("with topic Hello") {
+ public void run() {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon1)
+ .setWhen(mActivityCreateTime)
+ .setContentTitle("hihi")
+ .setContentText("This is a notification!!!")
+ .setContentIntent(makeIntent2())
+ .setTopic(new Notification.Topic("hello", "Hello"))
+ .build();
+
+ mNM.notify(999, n);
+ }
+ },
+
+ new Test("with topic GoodBye") {
+ public void run() {
+ Notification n = new Notification.Builder(NotificationTestList.this)
+ .setSmallIcon(R.drawable.icon1)
+ .setWhen(mActivityCreateTime)
+ .setContentTitle("byebye")
+ .setContentText("This is a notification!!!")
+ .setContentIntent(makeIntent2())
+ .setTopic(new Notification.Topic("bye", "Goodbye"))
+ .build();
+
+ mNM.notify(9999, n);
+ }
+ },
+
new Test("Whens") {
public void run()
{
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index 61ddb04..53bfc15 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -30,6 +30,9 @@
built_framework_dep := $(call java-lib-deps,framework)
built_framework_classes := $(call java-lib-files,framework)
+built_oj_dep := $(call java-lib-deps,core-oj)
+built_oj_classes := $(call java-lib-files,core-oj)
+
built_core_dep := $(call java-lib-deps,core-libart)
built_core_classes := $(call java-lib-files,core-libart)
@@ -56,7 +59,8 @@
include $(BUILD_SYSTEM)/base_rules.mk
#######################################
-$(LOCAL_BUILT_MODULE): $(built_core_dep) \
+$(LOCAL_BUILT_MODULE): $(built_oj_dep) \
+ $(built_core_dep) \
$(built_framework_dep) \
$(built_ext_dep) \
$(built_ext_data) \
@@ -69,6 +73,7 @@
$(hide) ls -l $(built_framework_classes)
$(hide) java -ea -jar $(built_layoutlib_create_jar) \
$@ \
+ $(built_oj_classes) \
$(built_core_classes) \
$(built_framework_classes) \
$(built_ext_classes) \