Merge "docs: Camera class JavaDoc FixIts for ICS"
diff --git a/Android.mk b/Android.mk
index be8c25b..c8b2555 100644
--- a/Android.mk
+++ b/Android.mk
@@ -400,6 +400,8 @@
resources/samples/AccessibilityService "Accessibility Service" \
-samplecode $(sample_dir)/AccelerometerPlay \
resources/samples/AccelerometerPlay "Accelerometer Play" \
+ -samplecode $(sample_dir)/AndroidBeam \
+ resources/samples/AndroidBeam "Android Beam" \
-samplecode $(sample_dir)/ApiDemos \
resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/Support4Demos \
diff --git a/api/14.txt b/api/14.txt
index 9f2a6df..e26311f 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -16583,10 +16583,6 @@
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String DISPLAY_NAME = "display_name";
field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO = "photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final java.lang.String PHOTO_URI = "photo_uri";
- field public static final java.lang.String SORT_INDEX = "sort_index";
- field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final android.net.Uri CONTENT_LIMIT_URI;
- field public static final android.net.Uri CONTENT_PHOTO_URI;
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemsColumns {
- field public static final java.lang.String ACCOUNT_NAME = "account_name";
- field public static final java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final java.lang.String COMMENTS = "comments";
- field public static final java.lang.String CONTACT_ID = "contact_id";
- field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final java.lang.String DATA_SET = "data_set";
- field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final java.lang.String RES_ICON = "icon";
- field public static final java.lang.String RES_LABEL = "label";
- field public static final java.lang.String RES_PACKAGE = "res_package";
- field public static final java.lang.String SYNC1 = "stream_item_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_sync4";
- field public static final java.lang.String TEXT = "text";
- field public static final java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/api/current.txt b/api/current.txt
index 9f2a6df..e26311f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16583,10 +16583,6 @@
field public static final java.lang.String PHOTO_FILE_ID = "data14";
}
- public static final class ContactsContract.Contacts.StreamItems implements android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.ContactsColumns {
field public static final java.lang.String DISPLAY_NAME = "display_name";
field public static final java.lang.String HAS_PHONE_NUMBER = "has_phone_number";
@@ -16844,10 +16840,6 @@
field public static final java.lang.String DATA_ID = "data_id";
}
- public static final class ContactsContract.RawContacts.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "stream_items";
- }
-
protected static abstract interface ContactsContract.RawContactsColumns {
field public static final java.lang.String AGGREGATION_MODE = "aggregation_mode";
field public static final java.lang.String CONTACT_ID = "contact_id";
@@ -16911,56 +16903,6 @@
field public static final android.net.Uri PROFILE_CONTENT_URI;
}
- public static final class ContactsContract.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO = "photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String PHOTO_FILE_ID = "photo_file_id";
- field public static final java.lang.String PHOTO_URI = "photo_uri";
- field public static final java.lang.String SORT_INDEX = "sort_index";
- field public static final java.lang.String STREAM_ITEM_ID = "stream_item_id";
- field public static final java.lang.String SYNC1 = "stream_item_photo_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_photo_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_photo_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_photo_sync4";
- }
-
- public static final class ContactsContract.StreamItems implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemsColumns {
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item";
- field public static final android.net.Uri CONTENT_LIMIT_URI;
- field public static final android.net.Uri CONTENT_PHOTO_URI;
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item";
- field public static final android.net.Uri CONTENT_URI;
- field public static final java.lang.String MAX_ITEMS = "max_items";
- }
-
- public static final class ContactsContract.StreamItems.StreamItemPhotos implements android.provider.BaseColumns android.provider.ContactsContract.StreamItemPhotosColumns {
- field public static final java.lang.String CONTENT_DIRECTORY = "photo";
- field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/stream_item_photo";
- field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/stream_item_photo";
- }
-
- protected static abstract interface ContactsContract.StreamItemsColumns {
- field public static final java.lang.String ACCOUNT_NAME = "account_name";
- field public static final java.lang.String ACCOUNT_TYPE = "account_type";
- field public static final java.lang.String COMMENTS = "comments";
- field public static final java.lang.String CONTACT_ID = "contact_id";
- field public static final java.lang.String CONTACT_LOOKUP_KEY = "contact_lookup";
- field public static final java.lang.String DATA_SET = "data_set";
- field public static final java.lang.String RAW_CONTACT_ID = "raw_contact_id";
- field public static final java.lang.String RAW_CONTACT_SOURCE_ID = "raw_contact_source_id";
- field public static final java.lang.String RES_ICON = "icon";
- field public static final java.lang.String RES_LABEL = "label";
- field public static final java.lang.String RES_PACKAGE = "res_package";
- field public static final java.lang.String SYNC1 = "stream_item_sync1";
- field public static final java.lang.String SYNC2 = "stream_item_sync2";
- field public static final java.lang.String SYNC3 = "stream_item_sync3";
- field public static final java.lang.String SYNC4 = "stream_item_sync4";
- field public static final java.lang.String TEXT = "text";
- field public static final java.lang.String TIMESTAMP = "timestamp";
- }
-
protected static abstract interface ContactsContract.SyncColumns implements android.provider.ContactsContract.BaseSyncColumns {
field public static final java.lang.String ACCOUNT_NAME = "account_name";
field public static final java.lang.String ACCOUNT_TYPE = "account_type";
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 4c4bf98..046ccca 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -66,6 +66,7 @@
boolean saveApks = false;
boolean saveShared = false;
boolean doEverything = false;
+ boolean allIncludesSystem = true;
String arg;
while ((arg = nextArg()) != null) {
@@ -78,6 +79,10 @@
saveShared = true;
} else if ("-noshared".equals(arg)) {
saveShared = false;
+ } else if ("-system".equals(arg)) {
+ allIncludesSystem = true;
+ } else if ("-nosystem".equals(arg)) {
+ allIncludesSystem = false;
} else if ("-all".equals(arg)) {
doEverything = true;
} else {
@@ -102,7 +107,7 @@
try {
ParcelFileDescriptor fd = ParcelFileDescriptor.adoptFd(socketFd);
String[] packArray = new String[packages.size()];
- mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything,
+ mBackupManager.fullBackup(fd, saveApks, saveShared, doEverything, allIncludesSystem,
packages.toArray(packArray));
} catch (RemoteException e) {
Log.e(TAG, "Unable to invoke backup manager for backup");
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index c154296..acdd0b5 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -157,11 +157,15 @@
* @param allApps If <code>true</code>, the resulting tar stream will include all
* installed applications' data, not just those named in the <code>packageNames</code>
* parameter.
+ * @param allIncludesSystem If {@code true}, then {@code allApps} will be interpreted
+ * as including packages pre-installed as part of the system. If {@code false},
+ * then setting {@code allApps} to {@code true} will mean only that all 3rd-party
+ * applications will be included in the dataset.
* @param packageNames The package names of the apps whose data (and optionally .apk files)
* are to be backed up. The <code>allApps</code> parameter supersedes this.
*/
void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
- boolean allApps, in String[] packageNames);
+ boolean allApps, boolean allIncludesSystem, in String[] packageNames);
/**
* Restore device content from the data stream passed through the given socket. The
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 1119c1e..5343e2a 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -248,6 +248,8 @@
private AccessibilityManager mAccessibilityManager;
/** The audio manager for accessibility support */
private AudioManager mAudioManager;
+ /** Whether the requirement of a headset to hear passwords if accessibility is enabled is announced. */
+ private boolean mHeadsetRequiredToHearPasswordsAnnounced;
Handler mHandler = new Handler() {
@Override
@@ -852,13 +854,15 @@
Key oldKey = keys[oldKeyIndex];
oldKey.onReleased(mCurrentKeyIndex == NOT_A_KEY);
invalidateKey(oldKeyIndex);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT, oldKey.codes[0]);
+ sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT,
+ oldKey.codes[0]);
}
if (mCurrentKeyIndex != NOT_A_KEY && keys.length > mCurrentKeyIndex) {
Key newKey = keys[mCurrentKeyIndex];
newKey.onPressed();
invalidateKey(mCurrentKeyIndex);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER, newKey.codes[0]);
+ sendAccessibilityEventForUnicodeCharacter(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER,
+ newKey.codes[0]);
}
}
// If key changed and preview is on ...
@@ -958,13 +962,13 @@
mPreviewText.setVisibility(VISIBLE);
}
- private void sendAccessibilityEvent(int eventType, int code) {
+ private void sendAccessibilityEventForUnicodeCharacter(int eventType, int code) {
if (mAccessibilityManager.isEnabled()) {
AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
onInitializeAccessibilityEvent(event);
+ String text = null;
// Add text only if headset is used to avoid leaking passwords.
if (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isWiredHeadsetOn()) {
- String text = null;
switch (code) {
case Keyboard.KEYCODE_ALT:
text = mContext.getString(R.string.keyboardview_keycode_alt);
@@ -990,11 +994,17 @@
default:
text = String.valueOf((char) code);
}
- event.getText().add(text);
+ } else if (!mHeadsetRequiredToHearPasswordsAnnounced) {
+ // We want the waring for required head set to be send with both the
+ // hover enter and hover exit event, so set the flag after the exit.
+ if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
+ mHeadsetRequiredToHearPasswordsAnnounced = true;
+ }
+ text = mContext.getString(R.string.keyboard_headset_required_to_hear_password);
} else {
- event.getText().add(mContext.getString(
- R.string.keyboard_headset_required_to_hear_password));
+ text = mContext.getString(R.string.keyboard_password_character_no_headset);
}
+ event.getText().add(text);
mAccessibilityManager.sendAccessibilityEvent(event);
}
}
@@ -1134,15 +1144,13 @@
}
@Override
- protected boolean dispatchHoverEvent(MotionEvent event) {
+ public boolean onHoverEvent(MotionEvent event) {
// If touch exploring is enabled we ignore touch events and transform
// the stream of hover events as touch events. This allows one consistent
// event stream to drive the keyboard since during touch exploring the
// first touch generates only hover events and tapping on the same
// location generates hover and touch events.
- if (mAccessibilityManager.isEnabled()
- && mAccessibilityManager.isTouchExplorationEnabled()
- && event.getPointerCount() == 1) {
+ if (mAccessibilityManager.isTouchExplorationEnabled() && event.getPointerCount() == 1) {
final int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
@@ -1156,9 +1164,9 @@
break;
}
onTouchEventInternal(event);
- return true;
+ event.setAction(action);
}
- return super.dispatchHoverEvent(event);
+ return super.onHoverEvent(event);
}
@Override
@@ -1168,8 +1176,7 @@
// event stream to drive the keyboard since during touch exploring the
// first touch generates only hover events and tapping on the same
// location generates hover and touch events.
- if (mAccessibilityManager.isEnabled()
- && mAccessibilityManager.isTouchExplorationEnabled()) {
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
return true;
}
return onTouchEventInternal(event);
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
index 08c6692..68a1dc3 100644
--- a/core/java/android/net/http/SslError.java
+++ b/core/java/android/net/http/SslError.java
@@ -19,7 +19,8 @@
import java.security.cert.X509Certificate;
/**
- * One or more individual SSL errors and the associated SSL certificate
+ * This class represents a set of one or more SSL errors and the associated SSL
+ * certificate.
*/
public class SslError {
@@ -48,16 +49,17 @@
*/
public static final int SSL_DATE_INVALID = 4;
/**
- * The certificate is invalid
+ * A generic error occurred
*/
public static final int SSL_INVALID = 5;
/**
- * The number of different SSL errors (update if you add a new SSL error!!!)
+ * The number of different SSL errors.
* @deprecated This constant is not necessary for using the SslError API and
* can change from release to release.
*/
+ // Update if you add a new SSL error!!!
@Deprecated
public static final int SSL_MAX_ERROR = 6;
@@ -78,56 +80,56 @@
final String mUrl;
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error and certificate.
+ * The URL will be set to the empty string.
* @param error The SSL error
* @param certificate The associated SSL certificate
* @deprecated Use {@link #SslError(int, SslCertificate, String)}
*/
@Deprecated
public SslError(int error, SslCertificate certificate) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = certificate;
- mUrl = "";
+ this(error, certificate, "");
}
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error and certificate.
+ * The URL will be set to the empty string.
* @param error The SSL error
* @param certificate The associated SSL certificate
* @deprecated Use {@link #SslError(int, X509Certificate, String)}
*/
@Deprecated
public SslError(int error, X509Certificate certificate) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = new SslCertificate(certificate);
- mUrl = "";
+ this(error, certificate, "");
}
/**
- * Creates a new SSL error set object
+ * Creates a new SslError object using the supplied error, certificate and
+ * URL.
* @param error The SSL error
* @param certificate The associated SSL certificate
- * @param url The associated URL.
+ * @param url The associated URL
*/
public SslError(int error, SslCertificate certificate, String url) {
+ assert certificate != null;
+ assert url != null;
addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
mCertificate = certificate;
- if (url == null) {
- throw new NullPointerException("url is null.");
- }
mUrl = url;
}
/**
+ * Creates a new SslError object using the supplied error, certificate and
+ * URL.
+ * @param error The SSL error
+ * @param certificate The associated SSL certificate
+ * @param url The associated URL
+ */
+ public SslError(int error, X509Certificate certificate, String url) {
+ this(error, new SslCertificate(certificate), url);
+ }
+
+ /**
* Creates an SslError object from a chromium error code.
* @param error The chromium error code
* @param certificate The associated SSL certificate
@@ -138,56 +140,42 @@
int error, SslCertificate cert, String url) {
// The chromium error codes are in:
// external/chromium/net/base/net_error_list.h
- if (error > -200 || error < -299) {
- throw new NullPointerException("Not a valid chromium SSL error code.");
- }
+ assert (error >= -299 && error <= -200);
if (error == -200)
return new SslError(SSL_IDMISMATCH, cert, url);
if (error == -201)
return new SslError(SSL_DATE_INVALID, cert, url);
if (error == -202)
return new SslError(SSL_UNTRUSTED, cert, url);
- // Map all other errors to SSL_INVALID
+ // Map all other codes to SSL_INVALID.
return new SslError(SSL_INVALID, cert, url);
}
/**
- * Creates a new SSL error set object
- * @param error The SSL error
- * @param certificate The associated SSL certificate
- * @param url The associated URL.
- */
- public SslError(int error, X509Certificate certificate, String url) {
- addError(error);
- if (certificate == null) {
- throw new NullPointerException("certificate is null.");
- }
- mCertificate = new SslCertificate(certificate);
- if (url == null) {
- throw new NullPointerException("url is null.");
- }
- mUrl = url;
- }
-
- /**
- * @return The SSL certificate associated with the error set, non-null.
+ * Gets the SSL certificate associated with this object.
+ * @return The SSL certificate, non-null.
*/
public SslCertificate getCertificate() {
return mCertificate;
}
/**
- * @return The URL associated with the error set, non-null.
- * "" if one of the deprecated constructors is used.
+ * Gets the URL associated with this object.
+ * @return The URL, non-null.
*/
+ // TODO: When the WebView constructs an instance of this object, we
+ // actually provide only the hostname, not the full URL. We should consider
+ // deprecating this method, adding a new getHost() method and updating the
+ // constructor arguments. See http://b/5410252.
public String getUrl() {
return mUrl;
}
/**
- * Adds the SSL error to the error set
+ * Adds the supplied SSL error to the set.
* @param error The SSL error to add
- * @return True iff the error being added is a known SSL error
+ * @return True if the error being added is a known SSL error, otherwise
+ * false.
*/
public boolean addError(int error) {
boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -199,8 +187,9 @@
}
/**
- * @param error The SSL error to check
- * @return True iff the set includes the error
+ * Determines whether this object includes the supplied error.
+ * @param error The SSL error to check for
+ * @return True if this object includes the error, otherwise false.
*/
public boolean hasError(int error) {
boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
@@ -212,7 +201,8 @@
}
/**
- * @return The primary, most severe, SSL error in the set
+ * Gets the most severe SSL error in this object's set of errors.
+ * @return The most severe SSL error.
*/
public int getPrimaryError() {
if (mErrors != 0) {
@@ -228,12 +218,12 @@
}
/**
- * @return A String representation of this SSL error object
- * (used mostly for debugging).
+ * Returns a string representation of this object.
+ * @return A String representation of this object.
*/
public String toString() {
return "primary error: " + getPrimaryError() +
- " certificate: " + getCertificate() +
- " on URL: " + getUrl();
+ " certificate: " + getCertificate() +
+ " on URL: " + getUrl();
}
}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index fb119b3..8483b4f 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1611,9 +1611,16 @@
}
/**
+ * <p>
* A sub-directory of a single contact that contains all of the constituent raw contact
* {@link ContactsContract.StreamItems} rows. This directory can be used either
* with a {@link #CONTENT_URI} or {@link #CONTENT_LOOKUP_URI}.
+ * </p>
+ * <p>
+ * Querying for social stream data requires android.permission.READ_SOCIAL_STREAM
+ * permission.
+ * </p>
+ * @hide
*/
public static final class StreamItems implements StreamItemsColumns {
/**
@@ -2669,6 +2676,14 @@
* {@link ContactsContract.StreamItems} for a stand-alone table containing the
* same data.
* </p>
+ * <p>
+ * Access to the social stream through this sub-directory requires additional permissions
+ * beyond the read/write contact permissions required by the provider. Querying for
+ * social stream data requires android.permission.READ_SOCIAL_STREAM permission, and
+ * inserting or updating social stream items requires android.permission.WRITE_SOCIAL_STREAM
+ * permission.
+ * </p>
+ * @hide
*/
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
/**
@@ -2963,6 +2978,12 @@
* transaction correspondingly. Insertion of more items beyond the limit will
* automatically lead to deletion of the oldest items, by {@link StreamItems#TIMESTAMP}.
* </p>
+ * <p>
+ * Access to the social stream through these URIs requires additional permissions beyond the
+ * read/write contact permissions required by the provider. Querying for social stream data
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating social
+ * stream items requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
* <h3>Operations</h3>
* <dl>
* <dt><b>Insert</b></dt>
@@ -3075,6 +3096,7 @@
* </pre>
* </dd>
* </dl>
+ * @hide
*/
public static final class StreamItems implements BaseColumns, StreamItemsColumns {
/**
@@ -3135,6 +3157,12 @@
* directory append {@link StreamItems.StreamItemPhotos#CONTENT_DIRECTORY} to
* an individual stream item URI.
* </p>
+ * <p>
+ * Access to social stream photos requires additional permissions beyond the read/write
+ * contact permissions required by the provider. Querying for social stream photos
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+ * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
*/
public static final class StreamItemPhotos
implements BaseColumns, StreamItemPhotosColumns {
@@ -3166,6 +3194,7 @@
* Columns in the StreamItems table.
*
* @see ContactsContract.StreamItems
+ * @hide
*/
protected interface StreamItemsColumns {
/**
@@ -3312,6 +3341,12 @@
* Constants for the stream_item_photos table, which contains photos associated with
* social stream updates.
* </p>
+ * <p>
+ * Access to social stream photos requires additional permissions beyond the read/write
+ * contact permissions required by the provider. Querying for social stream photos
+ * requires android.permission.READ_SOCIAL_STREAM permission, and inserting or updating
+ * social stream photos requires android.permission.WRITE_SOCIAL_STREAM permission.
+ * </p>
* <h3>Operations</h3>
* <dl>
* <dt><b>Insert</b></dt>
@@ -3450,6 +3485,7 @@
* <pre>
* </dd>
* </dl>
+ * @hide
*/
public static final class StreamItemPhotos implements BaseColumns, StreamItemPhotosColumns {
/**
@@ -3477,6 +3513,7 @@
* Columns in the StreamItemPhotos table.
*
* @see ContactsContract.StreamItemPhotos
+ * @hide
*/
protected interface StreamItemPhotosColumns {
/**
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 5126e48..98ab310 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -440,6 +440,9 @@
private final Context mContext;
private Connection mServiceConnection;
private OnInitListener mInitListener;
+ // Written from an unspecified application thread, read from
+ // a binder thread.
+ private volatile OnUtteranceCompletedListener mUtteranceCompletedListener;
private final Object mStartLock = new Object();
private String mRequestedEngine;
@@ -1071,20 +1074,8 @@
* @return {@link #ERROR} or {@link #SUCCESS}.
*/
public int setOnUtteranceCompletedListener(final OnUtteranceCompletedListener listener) {
- return runAction(new Action<Integer>() {
- @Override
- public Integer run(ITextToSpeechService service) throws RemoteException {
- ITextToSpeechCallback.Stub callback = new ITextToSpeechCallback.Stub() {
- public void utteranceCompleted(String utteranceId) {
- if (listener != null) {
- listener.onUtteranceCompleted(utteranceId);
- }
- }
- };
- service.setCallback(getPackageName(), callback);
- return SUCCESS;
- }
- }, ERROR, "setOnUtteranceCompletedListener");
+ mUtteranceCompletedListener = listener;
+ return TextToSpeech.SUCCESS;
}
/**
@@ -1137,6 +1128,15 @@
private class Connection implements ServiceConnection {
private ITextToSpeechService mService;
+ private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+ @Override
+ public void utteranceCompleted(String utteranceId) {
+ OnUtteranceCompletedListener listener = mUtteranceCompletedListener;
+ if (listener != null) {
+ listener.onUtteranceCompleted(utteranceId);
+ }
+ }
+ };
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Connected to " + name);
@@ -1147,7 +1147,13 @@
}
mServiceConnection = this;
mService = ITextToSpeechService.Stub.asInterface(service);
- dispatchOnInit(SUCCESS);
+ try {
+ mService.setCallback(getPackageName(), mCallback);
+ dispatchOnInit(SUCCESS);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Error connecting to service, setCallback() failed");
+ dispatchOnInit(ERROR);
+ }
}
}
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index c3a2308..f82c9c4 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -76,7 +76,7 @@
boolean includepad,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
- spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth, Integer.MAX_VALUE);
+ spacingmult, spacingadd, includepad, ellipsize, ellipsizedWidth);
}
/**
@@ -93,7 +93,7 @@
int width, Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
boolean includepad,
- TextUtils.TruncateAt ellipsize, int ellipsizedWidth, int maxLines) {
+ TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
super((ellipsize == null)
? display
: (display instanceof Spanned)
@@ -135,8 +135,6 @@
mEllipsize = true;
}
- mMaxLines = maxLines;
-
// Initial state is a single line with 0 characters (0 to 0),
// with top at 0 and bottom at whatever is natural, and
// undefined ellipsis.
@@ -285,7 +283,7 @@
reflowed.generate(text, where, where + after,
getPaint(), getWidth(), getAlignment(), getTextDirectionHeuristic(),
getSpacingMultiplier(), getSpacingAdd(),
- false, true, mEllipsizedWidth, mEllipsizeAt, mMaxLines);
+ false, true, mEllipsizedWidth, mEllipsizeAt);
int n = reflowed.getLineCount();
// If the new layout has a blank line at the end, but it is not
@@ -490,8 +488,6 @@
private int mTopPadding, mBottomPadding;
- private int mMaxLines;
-
private static StaticLayout sStaticLayout = new StaticLayout(null);
private static final Object[] sLock = new Object[0];
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 7c27396..583cbe6 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -139,7 +139,7 @@
generate(source, bufstart, bufend, paint, outerwidth, align, textDir,
spacingmult, spacingadd, includepad, includepad,
- ellipsizedWidth, ellipsize, mMaximumVisibleLineCount);
+ ellipsizedWidth, ellipsize);
mMeasured = MeasuredText.recycle(mMeasured);
mFontMetricsInt = null;
@@ -160,7 +160,7 @@
Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
boolean includepad, boolean trackpad,
- float ellipsizedWidth, TextUtils.TruncateAt ellipsize, int maxLines) {
+ float ellipsizedWidth, TextUtils.TruncateAt ellipsize) {
mLineCount = 0;
int v = 0;
@@ -477,13 +477,13 @@
width = restWidth;
}
}
- if (mLineCount >= maxLines) {
+ if (mLineCount >= mMaximumVisibleLineCount) {
break;
}
}
}
- if (paraEnd != here && mLineCount < maxLines) {
+ if (paraEnd != here && mLineCount < mMaximumVisibleLineCount) {
if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
paint.getFontMetricsInt(fm);
@@ -514,7 +514,7 @@
}
if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) &&
- mLineCount < maxLines) {
+ mLineCount < mMaximumVisibleLineCount) {
// Log.e("text", "output last " + bufEnd);
paint.getFontMetricsInt(fm);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 17f0e05..f7a9dc1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6262,7 +6262,7 @@
result = new DynamicLayout(mText, mTransformed, mTextPaint, w,
alignment, mTextDir, mSpacingMult,
mSpacingAdd, mIncludePad, mInput == null ? effectiveEllipsize : null,
- ellipsisWidth, mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
+ ellipsisWidth);
} else {
if (boring == UNKNOWN_BORING) {
boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 2694aa2..d5450e4 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -119,6 +119,8 @@
private final static String LOCKSCREEN_OPTIONS = "lockscreen.options";
public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK
= "lockscreen.biometric_weak_fallback";
+ public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY
+ = "lockscreen.biometricweakeverchosen";
private final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory";
@@ -341,6 +343,16 @@
}
/**
+ * Return true if the user has ever chosen biometric weak. This is true even if biometric
+ * weak is not current set.
+ *
+ * @return True if the user has ever chosen biometric weak.
+ */
+ public boolean isBiometricWeakEverChosen() {
+ return getBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY);
+ }
+
+ /**
* Used by device policy manager to validate the current password
* information it has.
*/
@@ -489,6 +501,7 @@
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY,
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
+ setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
moveTempGallery();
}
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
@@ -606,6 +619,7 @@
} else {
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
setLong(PASSWORD_TYPE_ALTERNATE_KEY, Math.max(quality, computedQuality));
+ setBoolean(BIOMETRIC_WEAK_EVER_CHOSEN_KEY, true);
moveTempGallery();
}
if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9755f22..18194ee 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,6 +263,23 @@
android:label="@string/permlab_writeProfile"
android:description="@string/permdesc_writeProfile" />
+ <!-- Allows an application to read from the user's social stream.
+ @hide -->
+ <permission android:name="android.permission.READ_SOCIAL_STREAM"
+ android:permissionGroup="android.permission-group.PERSONAL_INFO"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_readSocialStream"
+ android:description="@string/permdesc_readSocialStream" />
+
+ <!-- Allows an application to write (but not read) the user's
+ social stream data.
+ @hide -->
+ <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
+ android:permissionGroup="android.permission-group.PERSONAL_INFO"
+ android:protectionLevel="dangerous"
+ android:label="@string/permlab_writeSocialStream"
+ android:description="@string/permdesc_writeSocialStream" />
+
<!-- Allows an application to read the user's calendar data. -->
<permission android:name="android.permission.READ_CALENDAR"
android:permissionGroup="android.permission-group.PERSONAL_INFO"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1e0151a..b1dc252 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -941,6 +941,19 @@
information. This means other applications can identify you and send your profile
information to others.</string>
+ <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] -->
+ <string name="permlab_readSocialStream" product="default">read your social stream</string>
+ <string name="permdesc_readSocialStream" product="default">Allows the application to access
+ and sync social updates from you and your friends. Malicious apps can use this to read
+ private communications between you and your friends on social networks.</string>
+
+ <!-- Title of the write social stream permission, listed so the user can decide whether to allow the application to write information to the user's social stream. [CHAR LIMIT=30] -->
+ <string name="permlab_writeSocialStream" product="default">write to your social stream</string>
+ <string name="permdesc_writeSocialStream" product="default">Allows the application to display
+ social updates from your friends. Malicious apps can use this to pretend to be a friend
+ and trick you into revealing passwords or other confidential information.</string>
+
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCalendar">read calendar events plus confidential information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -3216,8 +3229,9 @@
<string name="description_target_soundon">Sound on</string>
<!-- Announce that a headset is required to hear keyboard keys while typing a password. [CHAR LIMIT=NONE] -->
- <string name="keyboard_headset_required_to_hear_password">Key. Headset required to hear
- keys while typing a password.</string>
+ <string name="keyboard_headset_required_to_hear_password">Plug in a headset to hear password keys spoken aloud.</string>
+ <!-- The value of a keyboard key announced when accessibility is enabled and no headsed is used. [CHAR LIMIT=NONE] -->
+ <string name="keyboard_password_character_no_headset">Dot.</string>
<!-- Content description for the action bar "home" affordance. [CHAR LIMIT=NONE] -->
<string name="action_bar_home_description">Navigate home</string>
@@ -3316,4 +3330,4 @@
<!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
<string name="list_delimeter">", "</string>
-</resources>
\ No newline at end of file
+</resources>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
deleted file mode 100644
index 1fd7bba..0000000
--- a/data/fonts/fonts.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-<!--
- This is only used by the layoutlib to display
- layouts in ADT.
--->
-<fonts>
- <font ttf="DroidSans">
- <name>sans-serif</name>
- <name>arial</name>
- <name>helvetica</name>
- <name>tahoma</name>
- <name>verdana</name>
- </font>
- <font ttf="DroidSerif">
- <name>serif</name>
- <name>times</name>
- <name>times new roman</name>
- <name>palatino</name>
- <name>georgia</name>
- <name>baskerville</name>
- <name>goudy</name>
- <name>fantasy</name>
- <name>cursive</name>
- <name>ITC Stone Serif</name>
- </font>
- <font ttf="DroidSansMono">
- <name>monospace</name>
- <name>courier</name>
- <name>courier new</name>
- <name>monaco</name>
- </font>
- <fallback ttf="DroidSansFallback" />
- <fallback ttf="MTLmr3m" />
-</fonts>
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 6c5d882..d7700ee 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -408,6 +408,16 @@
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/AndroidBeam/index.html',
+ title: {
+ en: 'Android Beam'
+ },
+ description: {
+ en: 'An example of how to use the Android Beam feature to send messages between two Android-powered devices (API level 14 or later) that support NFC.'
+ }
+ },
+ {
tags: ['sample', 'layout', 'ui'],
path: 'samples/ApiDemos/index.html',
title: {
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index bd70319..d51154d 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -70,13 +70,6 @@
clipRect = s->clipRect;
}
- if ((s->flags & Snapshot::kFlagClipSet) &&
- !(s->flags & Snapshot::kFlagDirtyLocalClip)) {
- mLocalClip.set(s->mLocalClip);
- } else {
- flags |= Snapshot::kFlagDirtyLocalClip;
- }
-
if (s->flags & Snapshot::kFlagFboTarget) {
flags |= Snapshot::kFlagFboTarget;
region = s->region;
@@ -106,18 +99,14 @@
*/
kFlagIsFboLayer = 0x4,
/**
- * Indicates that the local clip should be recomputed.
- */
- kFlagDirtyLocalClip = 0x8,
- /**
* Indicates that this snapshot has changed the ortho matrix.
*/
- kFlagDirtyOrtho = 0x10,
+ kFlagDirtyOrtho = 0x8,
/**
* Indicates that this snapshot or an ancestor snapshot is
* an FBO layer.
*/
- kFlagFboTarget = 0x20
+ kFlagFboTarget = 0x10
};
/**
@@ -169,7 +158,7 @@
}
if (clipped) {
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
return clipped;
@@ -180,19 +169,16 @@
*/
void setClip(float left, float top, float right, float bottom) {
clipRect->set(left, top, right, bottom);
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
const Rect& getLocalClip() {
- if (flags & Snapshot::kFlagDirtyLocalClip) {
- mat4 inverse;
- inverse.loadInverse(*transform);
+ mat4 inverse;
+ inverse.loadInverse(*transform);
- mLocalClip.set(*clipRect);
- inverse.mapRect(mLocalClip);
+ mLocalClip.set(*clipRect);
+ inverse.mapRect(mLocalClip);
- flags &= ~Snapshot::kFlagDirtyLocalClip;
- }
return mLocalClip;
}
@@ -204,7 +190,7 @@
void resetClip(float left, float top, float right, float bottom) {
clipRect = &mClipRectRoot;
clipRect->set(left, top, right, bottom);
- flags |= Snapshot::kFlagClipSet | Snapshot::kFlagDirtyLocalClip;
+ flags |= Snapshot::kFlagClipSet;
}
bool isIgnored() const {
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0755fb7..5fd5c35 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -302,7 +302,10 @@
DrvScript *drv = (DrvScript *)s->mHal.drv;
// We only support slot 0 (root) at this point in time.
rsAssert(slot == 0);
- mtls.sig = drv->mExportForEachSignatureList[slot];
+ mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp
+ if (drv->mExportForEachSignatureList) {
+ mtls.sig = drv->mExportForEachSignatureList[slot];
+ }
if (ain) {
mtls.dimX = ain->getType()->getDimX();
mtls.dimY = ain->getType()->getDimY();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index ca5d274..899a761 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -231,6 +231,8 @@
}
};
+ private TransportControlView mTransportControlView;
+
/**
* @return Whether we are stuck on the lock screen because the sim is
* missing.
@@ -516,7 +518,10 @@
// When screen is turned on, need to bind to FaceLock service if we are using FaceLock
// But only if not dealing with a call
- if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE) {
+ final boolean transportInvisible = mTransportControlView == null ? true :
+ mTransportControlView.getVisibility() != View.VISIBLE;
+ if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+ && transportInvisible) {
bindToFaceLock();
} else {
mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW);
@@ -805,14 +810,13 @@
}
private void initializeTransportControlView(View view) {
- com.android.internal.widget.TransportControlView tcv =
- (TransportControlView) view.findViewById(R.id.transport);
- if (tcv == null) {
+ mTransportControlView = (TransportControlView) view.findViewById(R.id.transport);
+ if (mTransportControlView == null) {
if (DEBUG) Log.w(TAG, "Couldn't find transport control widget");
} else {
mUpdateMonitor.reportClockVisible(true);
- tcv.setVisibility(View.GONE); // hide tcv until we get the callback below to show it.
- tcv.setCallback(mWidgetCallback);
+ mTransportControlView.setVisibility(View.GONE); // hide until it requests being shown.
+ mTransportControlView.setCallback(mWidgetCallback);
}
}
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index fe49cd2..7b8657a 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -325,14 +325,16 @@
public boolean includeApks;
public boolean includeShared;
public boolean allApps;
+ public boolean includeSystem;
public String[] packages;
FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveShared,
- boolean doAllApps, String[] pkgList) {
+ boolean doAllApps, boolean doSystem, String[] pkgList) {
fd = output;
includeApks = saveApks;
includeShared = saveShared;
allApps = doAllApps;
+ includeSystem = doSystem;
packages = pkgList;
}
}
@@ -504,7 +506,7 @@
PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
params.observer, params.includeApks,
params.includeShared, params.curPassword, params.encryptPassword,
- params.allApps, params.packages, params.latch);
+ params.allApps, params.includeSystem, params.packages, params.latch);
(new Thread(task)).start();
break;
}
@@ -2161,6 +2163,7 @@
boolean mIncludeApks;
boolean mIncludeShared;
boolean mAllApps;
+ final boolean mIncludeSystem;
String[] mPackages;
String mCurrentPassword;
String mEncryptPassword;
@@ -2219,13 +2222,14 @@
PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer,
boolean includeApks, boolean includeShared, String curPassword,
- String encryptPassword, boolean doAllApps, String[] packages,
+ String encryptPassword, boolean doAllApps, boolean doSystem, String[] packages,
AtomicBoolean latch) {
mOutputFile = fd;
mObserver = observer;
mIncludeApks = includeApks;
mIncludeShared = includeShared;
mAllApps = doAllApps;
+ mIncludeSystem = doSystem;
mPackages = packages;
mCurrentPassword = curPassword;
// when backing up, if there is a current backup password, we require that
@@ -2245,7 +2249,7 @@
@Override
public void run() {
- final List<PackageInfo> packagesToBackup;
+ List<PackageInfo> packagesToBackup = new ArrayList<PackageInfo>();
Slog.i(TAG, "--- Performing full-dataset backup ---");
sendStartBackup();
@@ -2254,8 +2258,23 @@
if (mAllApps) {
packagesToBackup = mPackageManager.getInstalledPackages(
PackageManager.GET_SIGNATURES);
- } else {
- packagesToBackup = new ArrayList<PackageInfo>();
+ // Exclude system apps if we've been asked to do so
+ if (mIncludeSystem == false) {
+ for (int i = 0; i < packagesToBackup.size(); ) {
+ PackageInfo pkg = packagesToBackup.get(i);
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ packagesToBackup.remove(i);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+
+ // Now process the command line argument packages, if any. Note that explicitly-
+ // named system-partition packages will be included even if includeSystem was
+ // set to false.
+ if (mPackages != null) {
for (String pkgName : mPackages) {
try {
packagesToBackup.add(mPackageManager.getPackageInfo(pkgName,
@@ -2268,8 +2287,8 @@
// Cull any packages that have indicated that backups are not permitted.
for (int i = 0; i < packagesToBackup.size(); ) {
- PackageInfo info = packagesToBackup.get(i);
- if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+ PackageInfo pkg = packagesToBackup.get(i);
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
packagesToBackup.remove(i);
} else {
i++;
@@ -4781,7 +4800,7 @@
// to the supplied file descriptor. This method is synchronous and does not return
// to the caller until the backup has been completed.
public void fullBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeShared,
- boolean doAllApps, String[] pkgList) {
+ boolean doAllApps, boolean includeSystem, String[] pkgList) {
mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
// Validate
@@ -4811,7 +4830,7 @@
Slog.i(TAG, "Beginning full backup...");
FullBackupParams params = new FullBackupParams(fd, includeApks, includeShared,
- doAllApps, pkgList);
+ doAllApps, includeSystem, pkgList);
final int token = generateToken();
synchronized (mFullConfirmations) {
mFullConfirmations.put(token, params);
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 3ea9e81..73ac296 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5704,6 +5704,7 @@
Configuration computeNewConfigurationLocked() {
Configuration config = new Configuration();
+ config.fontScale = 0;
if (!computeNewConfigurationLocked(config)) {
return null;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index e60a61c..1523823 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1166,7 +1166,7 @@
if (mTextScaleX != 1.0 || mTextSkewX != 0) {
// TODO: support skew
info.mFont = info.mFont.deriveFont(new AffineTransform(
- mTextScaleX, mTextSkewX, 0, 0, 1, 0));
+ mTextScaleX, mTextSkewX, 0, 1, 0, 0));
}
info.mMetrics = Toolkit.getDefaultToolkit().getFontMetrics(info.mFont);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 0f084f7..2414d70 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -25,8 +25,8 @@
import android.content.res.AssetManager;
import java.awt.Font;
+import java.io.File;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
/**
@@ -44,13 +44,14 @@
*/
public final class Typeface_Delegate {
+ private static final String SYSTEM_FONTS = "/system/fonts/";
+
// ---- delegate manager ----
private static final DelegateManager<Typeface_Delegate> sManager =
new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class);
// ---- delegate helper data ----
private static final String DEFAULT_FAMILY = "sans-serif";
- private static final int[] STYLE_BUFFER = new int[1];
private static FontLoader sFontLoader;
private static final List<Typeface_Delegate> sPostInitDelegate =
@@ -145,9 +146,31 @@
@LayoutlibDelegate
/*package*/ static synchronized int nativeCreateFromFile(String path) {
- Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
- "Typeface.createFromFile() is not supported.", null /*throwable*/, null /*data*/);
- return 0;
+ if (path.startsWith(SYSTEM_FONTS) ) {
+ String relativePath = path.substring(SYSTEM_FONTS.length());
+ File f = new File(sFontLoader.getOsFontsLocation(), relativePath);
+
+ try {
+ Font font = Font.createFont(Font.TRUETYPE_FONT, f);
+ if (font != null) {
+ Typeface_Delegate newDelegate = new Typeface_Delegate(font);
+ return sManager.addNewDelegate(newDelegate);
+ }
+ } catch (Exception e) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_BROKEN,
+ String.format("Unable to load font %1$s", relativePath),
+ null /*throwable*/, null /*data*/);
+ }
+ } else {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+ "Typeface.createFromFile() can only work with platform fonts located in " +
+ SYSTEM_FONTS,
+ null /*throwable*/, null /*data*/);
+ }
+
+
+ // return a copy of the base font
+ return nativeCreate(null, 0);
}
@LayoutlibDelegate
@@ -177,15 +200,17 @@
mStyle = style;
}
+ private Typeface_Delegate(Font font) {
+ mFamily = font.getFamily();
+ mStyle = Typeface.NORMAL;
+
+ mFonts = sFontLoader.getFallbackFonts(mStyle);
+
+ // insert the font glyph first.
+ mFonts.add(0, font);
+ }
+
private void init() {
- STYLE_BUFFER[0] = mStyle;
- Font font = sFontLoader.getFont(mFamily, STYLE_BUFFER);
- if (font != null) {
- List<Font> list = new ArrayList<Font>();
- list.add(font);
- list.addAll(sFontLoader.getFallBackFonts());
- mFonts = Collections.unmodifiableList(list);
- mStyle = STYLE_BUFFER[0];
- }
+ mFonts = sFontLoader.getFont(mFamily, mStyle);
}
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
index f62fad2..081ce67 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/FontLoader.java
@@ -23,17 +23,13 @@
import android.graphics.Typeface;
import java.awt.Font;
-import java.awt.FontFormatException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
@@ -47,49 +43,55 @@
* fonts.xml file located alongside the ttf files.
*/
public final class FontLoader {
- private static final String FONTS_DEFINITIONS = "fonts.xml";
+ private static final String FONTS_SYSTEM = "system_fonts.xml";
+ private static final String FONTS_VENDOR = "vendor_fonts.xml";
+ private static final String FONTS_FALLBACK = "fallback_fonts.xml";
- private static final String NODE_FONTS = "fonts";
- private static final String NODE_FONT = "font";
+ private static final String NODE_FAMILYSET = "familyset";
+ private static final String NODE_FAMILY = "family";
private static final String NODE_NAME = "name";
- private static final String NODE_FALLBACK = "fallback";
+ private static final String NODE_FILE = "file";
- private static final String ATTR_TTF = "ttf";
+ private static final String FONT_SUFFIX_NONE = ".ttf";
+ private static final String FONT_SUFFIX_REGULAR = "-Regular.ttf";
+ private static final String FONT_SUFFIX_BOLD = "-Bold.ttf";
+ private static final String FONT_SUFFIX_ITALIC = "-Italic.ttf";
+ private static final String FONT_SUFFIX_BOLDITALIC = "-BoldItalic.ttf";
- private static final String FONT_EXT = ".ttf";
-
- private static final String[] FONT_STYLE_DEFAULT = { "", "-Regular" };
- private static final String[] FONT_STYLE_BOLD = { "-Bold" };
- private static final String[] FONT_STYLE_ITALIC = { "-Italic" };
- private static final String[] FONT_STYLE_BOLDITALIC = { "-BoldItalic" };
-
- // list of font style, in the order matching the Typeface Font style
- private static final String[][] FONT_STYLES = {
- FONT_STYLE_DEFAULT,
- FONT_STYLE_BOLD,
- FONT_STYLE_ITALIC,
- FONT_STYLE_BOLDITALIC
+ // This must match the values of Typeface styles so that we can use them for indices in this
+ // array.
+ private static final int[] AWT_STYLES = new int[] {
+ Font.PLAIN,
+ Font.BOLD,
+ Font.ITALIC,
+ Font.BOLD | Font.ITALIC
};
+ private static int[] DERIVE_BOLD_ITALIC = new int[] {
+ Typeface.ITALIC, Typeface.BOLD, Typeface.NORMAL
+ };
+ private static int[] DERIVE_ITALIC = new int[] { Typeface.NORMAL };
+ private static int[] DERIVE_BOLD = new int[] { Typeface.NORMAL };
- private final Map<String, String> mFamilyToTtf = new HashMap<String, String>();
- private final Map<String, Map<Integer, Font>> mTtfToFontMap =
- new HashMap<String, Map<Integer, Font>>();
+ private static final List<FontInfo> mMainFonts = new ArrayList<FontInfo>();
+ private static final List<FontInfo> mFallbackFonts = new ArrayList<FontInfo>();
- private List<Font> mFallBackFonts = null;
+ private final String mOsFontsLocation;
public static FontLoader create(String fontOsLocation) {
try {
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
- SAXParser parser = parserFactory.newSAXParser();
- File f = new File(fontOsLocation + File.separator + FONTS_DEFINITIONS);
+ // parse the system fonts
+ FontHandler handler = parseFontFile(parserFactory, fontOsLocation, FONTS_SYSTEM);
+ List<FontInfo> systemFonts = handler.getFontList();
- FontDefinitionParser definitionParser = new FontDefinitionParser(
- fontOsLocation + File.separator);
- parser.parse(new FileInputStream(f), definitionParser);
- return definitionParser.getFontLoader();
+ // parse the fallback fonts
+ handler = parseFontFile(parserFactory, fontOsLocation, FONTS_FALLBACK);
+ List<FontInfo> fallbackFonts = handler.getFontList();
+
+ return new FontLoader(fontOsLocation, systemFonts, fallbackFonts);
} catch (ParserConfigurationException e) {
// return null below
} catch (SAXException e) {
@@ -103,35 +105,29 @@
return null;
}
- private FontLoader(List<FontInfo> fontList, List<String> fallBackList) {
- for (FontInfo info : fontList) {
- for (String family : info.families) {
- mFamilyToTtf.put(family, info.ttf);
- }
- }
+ private static FontHandler parseFontFile(SAXParserFactory parserFactory,
+ String fontOsLocation, String fontFileName)
+ throws ParserConfigurationException, SAXException, IOException, FileNotFoundException {
- ArrayList<Font> list = new ArrayList<Font>();
- for (String path : fallBackList) {
- File f = new File(path + FONT_EXT);
- if (f.isFile()) {
- try {
- Font font = Font.createFont(Font.TRUETYPE_FONT, f);
- if (font != null) {
- list.add(font);
- }
- } catch (FontFormatException e) {
- // skip this font name
- } catch (IOException e) {
- // skip this font name
- }
- }
- }
+ SAXParser parser = parserFactory.newSAXParser();
+ File f = new File(fontOsLocation, fontFileName);
- mFallBackFonts = Collections.unmodifiableList(list);
+ FontHandler definitionParser = new FontHandler(
+ fontOsLocation + File.separator);
+ parser.parse(new FileInputStream(f), definitionParser);
+ return definitionParser;
}
- public List<Font> getFallBackFonts() {
- return mFallBackFonts;
+ private FontLoader(String fontOsLocation,
+ List<FontInfo> fontList, List<FontInfo> fallBackList) {
+ mOsFontsLocation = fontOsLocation;
+ mMainFonts.addAll(fontList);
+ mFallbackFonts.addAll(fallBackList);
+ }
+
+
+ public String getOsFontsLocation() {
+ return mOsFontsLocation;
}
/**
@@ -143,96 +139,43 @@
* the method returns.
* @return the font object or null if no match could be found.
*/
- public synchronized Font getFont(String family, int[] style) {
+ public synchronized List<Font> getFont(String family, int style) {
+ List<Font> result = new ArrayList<Font>();
+
if (family == null) {
- return null;
+ return result;
}
- // get the ttf name from the family
- String ttf = mFamilyToTtf.get(family);
- if (ttf == null) {
- return null;
- }
-
- // get the font from the ttf
- Map<Integer, Font> styleMap = mTtfToFontMap.get(ttf);
-
- if (styleMap == null) {
- styleMap = new HashMap<Integer, Font>();
- mTtfToFontMap.put(ttf, styleMap);
- }
-
- Font f = styleMap.get(style[0]);
-
- if (f != null) {
- return f;
- }
-
- // if it doesn't exist, we create it, and we can't, we try with a simpler style
- switch (style[0]) {
- case Typeface.NORMAL:
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
+ // get the font objects from the main list based on family.
+ for (FontInfo info : mMainFonts) {
+ if (info.families.contains(family)) {
+ result.add(info.font[style]);
break;
- case Typeface.BOLD:
- case Typeface.ITALIC:
- f = getFont(ttf, FONT_STYLES[style[0]]);
- if (f == null) {
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
- style[0] = Typeface.NORMAL;
- }
- break;
- case Typeface.BOLD_ITALIC:
- f = getFont(ttf, FONT_STYLES[style[0]]);
- if (f == null) {
- f = getFont(ttf, FONT_STYLES[Typeface.BOLD]);
- if (f != null) {
- style[0] = Typeface.BOLD;
- } else {
- f = getFont(ttf, FONT_STYLES[Typeface.ITALIC]);
- if (f != null) {
- style[0] = Typeface.ITALIC;
- } else {
- f = getFont(ttf, FONT_STYLES[Typeface.NORMAL]);
- style[0] = Typeface.NORMAL;
- }
- }
- }
- break;
- }
-
- if (f != null) {
- styleMap.put(style[0], f);
- return f;
- }
-
- return null;
- }
-
- private Font getFont(String ttf, String[] fontFileSuffix) {
- for (String suffix : fontFileSuffix) {
- String name = ttf + suffix + FONT_EXT;
-
- File f = new File(name);
- if (f.isFile()) {
- try {
- Font font = Font.createFont(Font.TRUETYPE_FONT, f);
- if (font != null) {
- return font;
- }
- } catch (FontFormatException e) {
- // skip this font name
- } catch (IOException e) {
- // skip this font name
- }
}
}
- return null;
+ // add all the fallback fonts for the given style
+ for (FontInfo info : mFallbackFonts) {
+ result.add(info.font[style]);
+ }
+
+ return result;
}
+
+ public synchronized List<Font> getFallbackFonts(int style) {
+ List<Font> result = new ArrayList<Font>();
+ // add all the fallback fonts
+ for (FontInfo info : mFallbackFonts) {
+ result.add(info.font[style]);
+ }
+ return result;
+ }
+
+
private final static class FontInfo {
- String ttf;
+ final Font[] font = new Font[4]; // Matches the 4 type-face styles.
final Set<String> families;
FontInfo() {
@@ -240,21 +183,20 @@
}
}
- private final static class FontDefinitionParser extends DefaultHandler {
+ private final static class FontHandler extends DefaultHandler {
private final String mOsFontsLocation;
private FontInfo mFontInfo = null;
private final StringBuilder mBuilder = new StringBuilder();
- private List<FontInfo> mFontList;
- private List<String> mFallBackList;
+ private List<FontInfo> mFontList = new ArrayList<FontInfo>();
- private FontDefinitionParser(String osFontsLocation) {
+ private FontHandler(String osFontsLocation) {
super();
mOsFontsLocation = osFontsLocation;
}
- FontLoader getFontLoader() {
- return new FontLoader(mFontList, mFallBackList);
+ public List<FontInfo> getFontList() {
+ return mFontList;
}
/* (non-Javadoc)
@@ -263,26 +205,11 @@
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
- if (NODE_FONTS.equals(localName)) {
+ if (NODE_FAMILYSET.equals(localName)) {
mFontList = new ArrayList<FontInfo>();
- mFallBackList = new ArrayList<String>();
- } else if (NODE_FONT.equals(localName)) {
+ } else if (NODE_FAMILY.equals(localName)) {
if (mFontList != null) {
- String ttf = attributes.getValue(ATTR_TTF);
- if (ttf != null) {
- mFontInfo = new FontInfo();
- mFontInfo.ttf = mOsFontsLocation + ttf;
- mFontList.add(mFontInfo);
- }
- }
- } else if (NODE_NAME.equals(localName)) {
- // do nothing, we'll handle the name in the endElement
- } else if (NODE_FALLBACK.equals(localName)) {
- if (mFallBackList != null) {
- String ttf = attributes.getValue(ATTR_TTF);
- if (ttf != null) {
- mFallBackList.add(mOsFontsLocation + ttf);
- }
+ mFontInfo = new FontInfo();
}
}
@@ -304,21 +231,80 @@
*/
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
- if (NODE_FONTS.equals(localName)) {
- // top level, do nothing
- } else if (NODE_FONT.equals(localName)) {
- mFontInfo = null;
+ if (NODE_FAMILY.equals(localName)) {
+ if (mFontInfo != null) {
+ // if has a normal font file, add to the list
+ if (mFontInfo.font[Typeface.NORMAL] != null) {
+ mFontList.add(mFontInfo);
+
+ // create missing font styles, order is important.
+ if (mFontInfo.font[Typeface.BOLD_ITALIC] == null) {
+ computeDerivedFont(Typeface.BOLD_ITALIC, DERIVE_BOLD_ITALIC);
+ }
+ if (mFontInfo.font[Typeface.ITALIC] == null) {
+ computeDerivedFont(Typeface.ITALIC, DERIVE_ITALIC);
+ }
+ if (mFontInfo.font[Typeface.BOLD] == null) {
+ computeDerivedFont(Typeface.BOLD, DERIVE_BOLD);
+ }
+ }
+
+ mFontInfo = null;
+ }
} else if (NODE_NAME.equals(localName)) {
// handle a new name for an existing Font Info
if (mFontInfo != null) {
String family = trimXmlWhitespaces(mBuilder.toString());
mFontInfo.families.add(family);
}
- } else if (NODE_FALLBACK.equals(localName)) {
- // nothing to do here.
+ } else if (NODE_FILE.equals(localName)) {
+ // handle a new file for an existing Font Info
+ if (mFontInfo != null) {
+ String fileName = trimXmlWhitespaces(mBuilder.toString());
+ Font font = getFont(fileName);
+ if (font != null) {
+ if (fileName.endsWith(FONT_SUFFIX_REGULAR)) {
+ mFontInfo.font[Typeface.NORMAL] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_BOLD)) {
+ mFontInfo.font[Typeface.BOLD] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_ITALIC)) {
+ mFontInfo.font[Typeface.ITALIC] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
+ mFontInfo.font[Typeface.BOLD_ITALIC] = font;
+ } else if (fileName.endsWith(FONT_SUFFIX_NONE)) {
+ mFontInfo.font[Typeface.NORMAL] = font;
+ }
+ }
+ }
}
}
+ private Font getFont(String fileName) {
+ try {
+ File file = new File(mOsFontsLocation, fileName);
+ if (file.exists()) {
+ return Font.createFont(Font.TRUETYPE_FONT, file);
+ }
+ } catch (Exception e) {
+
+ }
+
+ return null;
+ }
+
+ private void computeDerivedFont( int toCompute, int[] basedOnList) {
+ for (int basedOn : basedOnList) {
+ if (mFontInfo.font[basedOn] != null) {
+ mFontInfo.font[toCompute] =
+ mFontInfo.font[basedOn].deriveFont(AWT_STYLES[toCompute]);
+ return;
+ }
+ }
+
+ // we really shouldn't stop there. This means we don't have a NORMAL font...
+ assert false;
+ }
+
private String trimXmlWhitespaces(String value) {
if (value == null) {
return null;