Merge "Fix bug #10514694 Specifying android:gravity="center_vertical|left" results in negative vertical positioning of child" into klp-dev
diff --git a/Android.mk b/Android.mk
index 69d1daf..eaafa87 100644
--- a/Android.mk
+++ b/Android.mk
@@ -142,7 +142,7 @@
core/java/android/net/INetworkStatsService.aidl \
core/java/android/net/INetworkStatsSession.aidl \
core/java/android/net/nsd/INsdManager.aidl \
- core/java/android/nfc/INdefPushCallback.aidl \
+ core/java/android/nfc/IAppCallback.aidl \
core/java/android/nfc/INfcAdapter.aidl \
core/java/android/nfc/INfcAdapterExtras.aidl \
core/java/android/nfc/INfcTag.aidl \
diff --git a/api/current.txt b/api/current.txt
index e4d8b76..eb3596a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -289,6 +289,7 @@
field public static final deprecated int animationResolution = 16843546; // 0x101031a
field public static final int antialias = 16843034; // 0x101011a
field public static final int anyDensity = 16843372; // 0x101026c
+ field public static final int apduServiceBanner = 16843755; // 0x10103eb
field public static final int apiKey = 16843281; // 0x1010211
field public static final int author = 16843444; // 0x10102b4
field public static final int authorities = 16842776; // 0x1010018
@@ -844,6 +845,7 @@
field public static final int prompt = 16843131; // 0x101017b
field public static final int propertyName = 16843489; // 0x10102e1
field public static final int protectionLevel = 16842761; // 0x1010009
+ field public static final int provideAssistData = 16843756; // 0x10103ec
field public static final int publicKey = 16843686; // 0x10103a6
field public static final int queryActionMsg = 16843227; // 0x10101db
field public static final int queryAfterZeroResults = 16843394; // 0x1010282
@@ -5736,7 +5738,6 @@
method public final android.os.Bundle call(android.net.Uri, java.lang.String, java.lang.String, android.os.Bundle);
method public deprecated void cancelSync(android.net.Uri);
method public static void cancelSync(android.accounts.Account, java.lang.String);
- method public static void cancelSync(android.content.SyncRequest);
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public static deprecated android.content.SyncInfo getCurrentSync();
method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
@@ -5957,6 +5958,7 @@
field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
field public static final java.lang.String BLUETOOTH_SERVICE = "bluetooth";
field public static final java.lang.String CAMERA_SERVICE = "camera";
+ field public static final java.lang.String CAPTIONING_SERVICE = "captioning";
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -6715,9 +6717,7 @@
field public final android.accounts.Account account;
field public final java.lang.String authority;
field public final android.os.Bundle extras;
- field public final boolean isService;
field public final long period;
- field public final android.content.ComponentName service;
}
public class ReceiverCallNotAllowedException extends android.util.AndroidRuntimeException {
@@ -6838,7 +6838,6 @@
public class SyncRequest implements android.os.Parcelable {
method public int describeContents();
- method public boolean isExpedited();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -6846,18 +6845,15 @@
public static class SyncRequest.Builder {
ctor public SyncRequest.Builder();
method public android.content.SyncRequest build();
- method public android.content.SyncRequest.Builder setAllowMetered(boolean);
+ method public android.content.SyncRequest.Builder setDisallowMetered(boolean);
method public android.content.SyncRequest.Builder setExpedited(boolean);
method public android.content.SyncRequest.Builder setExtras(android.os.Bundle);
method public android.content.SyncRequest.Builder setIgnoreBackoff(boolean);
method public android.content.SyncRequest.Builder setIgnoreSettings(boolean);
method public android.content.SyncRequest.Builder setManual(boolean);
method public android.content.SyncRequest.Builder setNoRetry(boolean);
- method public android.content.SyncRequest.Builder setPriority(int);
method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
- method public android.content.SyncRequest.Builder setSyncAdapter(android.content.ComponentName);
- method public android.content.SyncRequest.Builder setTransferSize(long, long);
- method public android.content.SyncRequest.Builder syncOnce(long, long);
+ method public android.content.SyncRequest.Builder syncOnce();
method public android.content.SyncRequest.Builder syncPeriodic(long, long);
}
@@ -6884,12 +6880,6 @@
field public boolean tooManyRetries;
}
- public abstract class SyncService extends android.app.Service {
- ctor public SyncService();
- method public android.os.IBinder onBind(android.content.Intent);
- method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
- }
-
public class SyncStats implements android.os.Parcelable {
ctor public SyncStats();
ctor public SyncStats(android.os.Parcel);
@@ -11933,6 +11923,7 @@
field public static final java.lang.String KEY_PROVIDER_ENABLED = "providerEnabled";
field public static final java.lang.String KEY_PROXIMITY_ENTERING = "entering";
field public static final java.lang.String KEY_STATUS_CHANGED = "status";
+ field public static final java.lang.String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
field public static final java.lang.String NETWORK_PROVIDER = "network";
field public static final java.lang.String PASSIVE_PROVIDER = "passive";
field public static final java.lang.String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
@@ -11959,13 +11950,14 @@
ctor public SettingInjectorService(java.lang.String);
method protected abstract android.location.SettingInjectorService.Status getStatus();
method protected final void onHandleIntent(android.content.Intent);
- field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "com.android.location.InjectedSettingChanged";
+ field public static final java.lang.String ACTION_INJECTED_SETTING_CHANGED = "android.location.InjectedSettingChanged";
+ field public static final java.lang.String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+ field public static final java.lang.String ATTRIBUTES_NAME = "injected-location-setting";
+ field public static final java.lang.String META_DATA_NAME = "android.location.SettingInjectorService";
}
public static final class SettingInjectorService.Status {
ctor public SettingInjectorService.Status(java.lang.String, boolean);
- field public final boolean enabled;
- field public final java.lang.String summary;
}
}
@@ -12902,7 +12894,9 @@
field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
field public static final int MEDIA_INFO_METADATA_UPDATE = 802; // 0x322
field public static final int MEDIA_INFO_NOT_SEEKABLE = 801; // 0x321
+ field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
+ field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -13199,6 +13193,7 @@
ctor public RemoteControlClient(android.app.PendingIntent);
ctor public RemoteControlClient(android.app.PendingIntent, android.os.Looper);
method public android.media.RemoteControlClient.MetadataEditor editMetadata(boolean);
+ method public void setMetadataUpdateListener(android.media.RemoteControlClient.OnMetadataUpdateListener);
method public void setOnGetPlaybackPositionListener(android.media.RemoteControlClient.OnGetPlaybackPositionListener);
method public void setPlaybackPositionUpdateListener(android.media.RemoteControlClient.OnPlaybackPositionUpdateListener);
method public void setPlaybackState(int);
@@ -13211,6 +13206,7 @@
field public static final int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
field public static final int FLAG_KEY_MEDIA_POSITION_UPDATE = 256; // 0x100
field public static final int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+ field public static final int FLAG_KEY_MEDIA_RATING = 512; // 0x200
field public static final int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
field public static final int FLAG_KEY_MEDIA_STOP = 32; // 0x20
field public static final int PLAYSTATE_BUFFERING = 8; // 0x8
@@ -13225,18 +13221,32 @@
}
public class RemoteControlClient.MetadataEditor {
+ method public synchronized void addEditableKey(int);
method public synchronized void apply();
method public synchronized void clear();
+ method public synchronized void clearEditableKeys();
method public synchronized android.media.RemoteControlClient.MetadataEditor putBitmap(int, android.graphics.Bitmap) throws java.lang.IllegalArgumentException;
method public synchronized android.media.RemoteControlClient.MetadataEditor putLong(int, long) throws java.lang.IllegalArgumentException;
method public synchronized android.media.RemoteControlClient.MetadataEditor putString(int, java.lang.String) throws java.lang.IllegalArgumentException;
field public static final int BITMAP_KEY_ARTWORK = 100; // 0x64
+ field public static final int LONG_KEY_RATING_BY_OTHERS = 102; // 0x66
+ field public static final int LONG_KEY_RATING_BY_USER = 268435457; // 0x10000001
+ field public static final int LONG_KEY_RATING_TYPE = 101; // 0x65
+ field public static final long RATING_HEART = -1L; // 0xffffffffffffffffL
+ field public static final long RATING_NOT_RATED = -101L; // 0xffffffffffffff9bL
+ field public static final long RATING_THUMB_UP_DOWN = -2L; // 0xfffffffffffffffeL
}
public static abstract interface RemoteControlClient.OnGetPlaybackPositionListener {
method public abstract long onGetPlaybackPosition();
}
+ public static abstract interface RemoteControlClient.OnMetadataUpdateListener {
+ method public abstract void onMetadataUpdateBitmap(int, android.graphics.Bitmap);
+ method public abstract void onMetadataUpdateLong(int, long);
+ method public abstract void onMetadataUpdateString(int, java.lang.String);
+ }
+
public static abstract interface RemoteControlClient.OnPlaybackPositionUpdateListener {
method public abstract void onPlaybackPositionUpdate(long);
}
@@ -15194,7 +15204,7 @@
method public void disableReaderMode(android.app.Activity);
method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]);
method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
- method public void enableReaderMode(android.app.Activity, int);
+ method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
method public boolean isEnabled();
method public boolean isNdefPushEnabled();
@@ -15210,12 +15220,14 @@
field public static final java.lang.String EXTRA_ADAPTER_STATE = "android.nfc.extra.ADAPTER_STATE";
field public static final java.lang.String EXTRA_ID = "android.nfc.extra.ID";
field public static final java.lang.String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES";
+ field public static final java.lang.String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
field public static final int FLAG_READER_KOVIO = 16; // 0x10
field public static final int FLAG_READER_NFC_A = 1; // 0x1
field public static final int FLAG_READER_NFC_B = 2; // 0x2
field public static final int FLAG_READER_NFC_F = 4; // 0x4
field public static final int FLAG_READER_NFC_V = 8; // 0x8
+ field public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 256; // 0x100
field public static final int FLAG_READER_SKIP_NDEF_CHECK = 128; // 0x80
field public static final int STATE_OFF = 1; // 0x1
field public static final int STATE_ON = 3; // 0x3
@@ -15235,6 +15247,10 @@
method public abstract void onNdefPushComplete(android.nfc.NfcEvent);
}
+ public static abstract interface NfcAdapter.ReaderCallback {
+ method public abstract void onTagDiscovered(android.nfc.Tag);
+ }
+
public final class NfcEvent {
field public final android.nfc.NfcAdapter nfcAdapter;
}
@@ -15260,12 +15276,12 @@
package android.nfc.cardemulation {
- public final class CardEmulationManager {
- method public static synchronized android.nfc.cardemulation.CardEmulationManager getInstance(android.nfc.NfcAdapter);
+ public final class CardEmulation {
+ method public static synchronized android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
method public int getSelectionModeForCategory(java.lang.String);
method public boolean isDefaultServiceForAid(android.content.ComponentName, java.lang.String);
method public boolean isDefaultServiceForCategory(android.content.ComponentName, java.lang.String);
- field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.ACTION_CHANGE_DEFAULT";
+ field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
field public static final java.lang.String CATEGORY_OTHER = "other";
field public static final java.lang.String CATEGORY_PAYMENT = "payment";
field public static final java.lang.String EXTRA_CATEGORY = "category";
@@ -15281,19 +15297,18 @@
method public final android.os.IBinder onBind(android.content.Intent);
method public abstract void onDeactivated(int);
method public byte[] processCommandApdu(byte[], android.os.Bundle);
- method public abstract deprecated byte[] processCommandApdu(byte[], int);
method public final void sendResponseApdu(byte[]);
field public static final int DEACTIVATION_DESELECTED = 1; // 0x1
field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
- field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.HostApduService";
- field public static final java.lang.String SERVICE_META_DATA = "android.nfc.HostApduService";
+ field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
+ field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
}
public abstract class OffHostApduService extends android.app.Service {
ctor public OffHostApduService();
method public abstract android.os.IBinder onBind(android.content.Intent);
- field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.OffHostApduService";
- field public static final java.lang.String SERVICE_META_DATA = "android.nfc.OffHostApduService";
+ field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
+ field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service";
}
}
@@ -20827,67 +20842,70 @@
}
public final class DocumentsContract {
+ method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String);
method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
- method public static java.lang.String getDocId(android.net.Uri);
+ method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String);
+ method public static android.net.Uri buildRootsUri(java.lang.String);
+ method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
+ method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
+ method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri);
+ method public static java.lang.String getDocumentId(android.net.Uri);
+ method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal);
method public static android.net.Uri[] getOpenDocuments(android.content.Context);
+ method public static java.lang.String getRootId(android.net.Uri);
+ method public static java.lang.String getSearchDocumentsQuery(android.net.Uri);
field public static final java.lang.String EXTRA_ERROR = "error";
field public static final java.lang.String EXTRA_INFO = "info";
field public static final java.lang.String EXTRA_LOADING = "loading";
}
- public static abstract interface DocumentsContract.DocumentColumns implements android.provider.OpenableColumns {
- field public static final java.lang.String DOC_ID = "doc_id";
- field public static final java.lang.String FLAGS = "flags";
- field public static final java.lang.String ICON = "icon";
- field public static final java.lang.String LAST_MODIFIED = "last_modified";
- field public static final java.lang.String MIME_TYPE = "mime_type";
- field public static final java.lang.String SUMMARY = "summary";
+ public static final class DocumentsContract.Document {
+ field public static final java.lang.String COLUMN_DISPLAY_NAME = "_display_name";
+ field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id";
+ field public static final java.lang.String COLUMN_FLAGS = "flags";
+ field public static final java.lang.String COLUMN_ICON = "icon";
+ field public static final java.lang.String COLUMN_LAST_MODIFIED = "last_modified";
+ field public static final java.lang.String COLUMN_MIME_TYPE = "mime_type";
+ field public static final java.lang.String COLUMN_SIZE = "_size";
+ field public static final java.lang.String COLUMN_SUMMARY = "summary";
+ field public static final int FLAG_DIR_PREFERS_GRID = 32; // 0x20
+ field public static final int FLAG_DIR_SUPPORTS_CREATE = 8; // 0x8
+ field public static final int FLAG_DIR_SUPPORTS_SEARCH = 16; // 0x10
+ field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
+ field public static final int FLAG_SUPPORTS_THUMBNAIL = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_WRITE = 2; // 0x2
+ field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.document/directory";
}
- public static final class DocumentsContract.DocumentRoot implements android.os.Parcelable {
- ctor public DocumentsContract.DocumentRoot();
- method public int describeContents();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator CREATOR;
+ public static final class DocumentsContract.Root {
+ field public static final java.lang.String COLUMN_AVAILABLE_BYTES = "available_bytes";
+ field public static final java.lang.String COLUMN_DOCUMENT_ID = "document_id";
+ field public static final java.lang.String COLUMN_FLAGS = "flags";
+ field public static final java.lang.String COLUMN_ICON = "icon";
+ field public static final java.lang.String COLUMN_ROOT_ID = "root_id";
+ field public static final java.lang.String COLUMN_ROOT_TYPE = "root_type";
+ field public static final java.lang.String COLUMN_SUMMARY = "summary";
+ field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final int FLAG_ADVANCED = 4; // 0x4
field public static final int FLAG_LOCAL_ONLY = 2; // 0x2
+ field public static final int FLAG_PROVIDES_AUDIO = 8; // 0x8
+ field public static final int FLAG_PROVIDES_IMAGES = 32; // 0x20
+ field public static final int FLAG_PROVIDES_VIDEO = 16; // 0x10
field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
+ field public static final int FLAG_SUPPORTS_RECENTS = 64; // 0x40
field public static final int ROOT_TYPE_DEVICE = 3; // 0x3
- field public static final int ROOT_TYPE_DEVICE_ADVANCED = 4; // 0x4
field public static final int ROOT_TYPE_SERVICE = 1; // 0x1
field public static final int ROOT_TYPE_SHORTCUT = 2; // 0x2
- field public long availableBytes;
- field public java.lang.String docId;
- field public int flags;
- field public int icon;
- field public java.lang.String[] mimeTypes;
- field public java.lang.String recentDocId;
- field public int rootType;
- field public java.lang.String summary;
- field public java.lang.String title;
- }
-
- public static final class DocumentsContract.Documents {
- field public static final int FLAG_PREFERS_GRID = 64; // 0x40
- field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1
- field public static final int FLAG_SUPPORTS_DELETE = 4; // 0x4
- field public static final int FLAG_SUPPORTS_RENAME = 2; // 0x2
- field public static final int FLAG_SUPPORTS_SEARCH = 16; // 0x10
- field public static final int FLAG_SUPPORTS_THUMBNAIL = 8; // 0x8
- field public static final int FLAG_SUPPORTS_WRITE = 32; // 0x20
- field public static final java.lang.String MIME_TYPE_DIR = "vnd.android.doc/dir";
}
public abstract class DocumentsProvider extends android.content.ContentProvider {
ctor public DocumentsProvider();
- method public final android.os.Bundle callFromPackage(java.lang.String, java.lang.String, java.lang.String, android.os.Bundle);
method public java.lang.String createDocument(java.lang.String, java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
method public final int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public void deleteDocument(java.lang.String) throws java.io.FileNotFoundException;
- method public abstract java.util.List<android.provider.DocumentsContract.DocumentRoot> getDocumentRoots();
- method public java.lang.String getType(java.lang.String) throws java.io.FileNotFoundException;
+ method public java.lang.String getDocumentType(java.lang.String) throws java.io.FileNotFoundException;
method public final java.lang.String getType(android.net.Uri);
method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
- method public void notifyDocumentRootsChanged();
method public abstract android.os.ParcelFileDescriptor openDocument(java.lang.String, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public android.content.res.AssetFileDescriptor openDocumentThumbnail(java.lang.String, android.graphics.Point, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -20895,10 +20913,11 @@
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle) throws java.io.FileNotFoundException;
method public final android.content.res.AssetFileDescriptor openTypedAssetFile(android.net.Uri, java.lang.String, android.os.Bundle, android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public final android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String);
- method public abstract android.database.Cursor queryDocument(java.lang.String) throws java.io.FileNotFoundException;
- method public abstract android.database.Cursor queryDocumentChildren(java.lang.String) throws java.io.FileNotFoundException;
- method public android.database.Cursor querySearch(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
- method public void renameDocument(java.lang.String, java.lang.String) throws java.io.FileNotFoundException;
+ method public abstract android.database.Cursor queryChildDocuments(java.lang.String, java.lang.String[], java.lang.String) throws java.io.FileNotFoundException;
+ method public abstract android.database.Cursor queryDocument(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+ method public android.database.Cursor queryRecentDocuments(java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
+ method public abstract android.database.Cursor queryRoots(java.lang.String[]) throws java.io.FileNotFoundException;
+ method public android.database.Cursor querySearchDocuments(java.lang.String, java.lang.String, java.lang.String[]) throws java.io.FileNotFoundException;
method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
}
@@ -21253,6 +21272,7 @@
field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
+ field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -22584,8 +22604,11 @@
}
public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
method public android.content.Context getContext();
method public java.util.Date getEndDate();
+ method public int getKeySize();
+ method public java.lang.String getKeyType();
method public java.lang.String getKeystoreAlias();
method public java.math.BigInteger getSerialNumber();
method public java.util.Date getStartDate();
@@ -22596,9 +22619,12 @@
public static final class KeyPairGeneratorSpec.Builder {
ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
method public android.security.KeyPairGeneratorSpec build();
+ method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
@@ -25748,7 +25774,7 @@
method public android.util.JsonWriter value(java.lang.Number) throws java.io.IOException;
}
- public abstract interface LayoutDirection {
+ public final class LayoutDirection {
field public static final int INHERIT = 2; // 0x2
field public static final int LOCALE = 3; // 0x3
field public static final int LTR = 0; // 0x0
@@ -27147,6 +27173,7 @@
public class ScaleGestureDetector {
ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener);
+ ctor public ScaleGestureDetector(android.content.Context, android.view.ScaleGestureDetector.OnScaleGestureListener, android.os.Handler);
method public float getCurrentSpan();
method public float getCurrentSpanX();
method public float getCurrentSpanY();
@@ -27160,6 +27187,7 @@
method public long getTimeDelta();
method public boolean isInProgress();
method public boolean onTouchEvent(android.view.MotionEvent);
+ method public void setQuickScaleEnabled(boolean);
}
public static abstract interface ScaleGestureDetector.OnScaleGestureListener {
@@ -28963,15 +28991,15 @@
}
public class CaptioningManager {
- ctor public CaptioningManager();
- method public static final float getFontSize(android.content.ContentResolver);
- method public static final java.util.Locale getLocale(android.content.ContentResolver);
- method public static final boolean isEnabled(android.content.ContentResolver);
- field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
+ method public void addCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
+ method public final float getFontScale();
+ method public final java.util.Locale getLocale();
+ method public android.view.accessibility.CaptioningManager.CaptionStyle getUserStyle();
+ method public final boolean isEnabled();
+ method public void removeCaptioningStateChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
}
public static final class CaptioningManager.CaptionStyle {
- method public static android.view.accessibility.CaptioningManager.CaptionStyle defaultUserStyle(android.content.ContentResolver);
method public android.graphics.Typeface getTypeface();
field public static final int EDGE_TYPE_DROP_SHADOW = 2; // 0x2
field public static final int EDGE_TYPE_NONE = 0; // 0x0
@@ -28982,6 +29010,14 @@
field public final int foregroundColor;
}
+ public abstract class CaptioningManager.CaptioningChangeListener {
+ ctor public CaptioningManager.CaptioningChangeListener();
+ method public void onEnabledChanged(boolean);
+ method public void onFontScaleChanged(float);
+ method public void onLocaleChanged(java.util.Locale);
+ method public void onUserStyleChanged(android.view.accessibility.CaptioningManager.CaptionStyle);
+ }
+
}
package android.view.animation {
@@ -30369,6 +30405,7 @@
ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
method public void afterTextChanged(android.text.Editable);
method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
+ method public boolean canScrollList(int);
method public void clearChoices();
method public void clearTextFilter();
method public void deferNotifyDataSetChanged();
@@ -30410,7 +30447,7 @@
method public int pointToPosition(int, int);
method public long pointToRowId(int, int);
method public void reclaimViews(java.util.List<android.view.View>);
- method public boolean scrollListBy(int);
+ method public void scrollListBy(int);
method public void setAdapter(android.widget.ListAdapter);
method public void setCacheColorHint(int);
method public void setChoiceMode(int);
@@ -32633,6 +32670,7 @@
ctor public VideoView(android.content.Context);
ctor public VideoView(android.content.Context, android.util.AttributeSet);
ctor public VideoView(android.content.Context, android.util.AttributeSet, int);
+ method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
method public boolean canPause();
method public boolean canSeekBackward();
method public boolean canSeekForward();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index cdec399..f10290d 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -105,6 +105,7 @@
import android.view.Display;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.CaptioningManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textservice.TextServicesManager;
import android.accounts.AccountManager;
@@ -307,6 +308,11 @@
return AccessibilityManager.getInstance(ctx);
}});
+ registerService(CAPTIONING_SERVICE, new ServiceFetcher() {
+ public Object getService(ContextImpl ctx) {
+ return new CaptioningManager(ctx);
+ }});
+
registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index b390aa1..a2bb78c 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -702,6 +702,10 @@
* @param start Start or stop advertising
*/
/*package*/ void listen(boolean start) {
+ if (mContext == null || !mContext.getResources().
+ getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+ throw new UnsupportedOperationException("BluetoothGatt#listen is blocked");
+ }
if (DBG) Log.d(TAG, "listen() - start: " + start);
if (mService == null || mClientIf == 0) return;
@@ -728,6 +732,10 @@
/*package*/ void setAdvData(boolean advData, boolean includeName, boolean includeTxPower,
Integer minInterval, Integer maxInterval,
Integer appearance, Byte[] manufacturerData) {
+ if (mContext == null || !mContext.getResources().
+ getBoolean(com.android.internal.R.bool.config_bluetooth_le_peripheral_mode_supported)) {
+ throw new UnsupportedOperationException("BluetoothGatt#setAdvData is blocked");
+ }
if (DBG) Log.d(TAG, "setAdvData()");
if (mService == null || mClientIf == 0) return;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index a761a89..8a5a56c 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -141,7 +141,7 @@
public static final String SYNC_EXTRAS_PRIORITY = "sync_priority";
/** {@hide} Flag to allow sync to occur on metered network. */
- public static final String SYNC_EXTRAS_ALLOW_METERED = "allow_metered";
+ public static final String SYNC_EXTRAS_DISALLOW_METERED = "disallow_metered";
/**
* Set by the SyncManager to request that the SyncAdapter initialize itself for
@@ -1669,7 +1669,7 @@
new SyncRequest.Builder()
.setSyncAdapter(account, authority)
.setExtras(extras)
- .syncOnce(0, 0) // Immediate sync.
+ .syncOnce()
.build();
requestSync(request);
}
@@ -1677,6 +1677,9 @@
/**
* Register a sync with the SyncManager. These requests are built using the
* {@link SyncRequest.Builder}.
+ *
+ * @param request The immutable SyncRequest object containing the sync parameters. Use
+ * {@link SyncRequest.Builder} to construct these.
*/
public static void requestSync(SyncRequest request) {
try {
@@ -1812,6 +1815,9 @@
* {@link #SYNC_EXTRAS_INITIALIZE}, {@link #SYNC_EXTRAS_FORCE},
* {@link #SYNC_EXTRAS_EXPEDITED}, {@link #SYNC_EXTRAS_MANUAL} set to true.
* If any are supplied then an {@link IllegalArgumentException} will be thrown.
+ * <p>As of API level 19 this function introduces a default flexibility of ~4% (up to a maximum
+ * of one hour in the day) into the requested period. Use
+ * {@link SyncRequest.Builder#syncPeriodic(long, long)} to set this flexibility manually.
*
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
@@ -1875,22 +1881,6 @@
}
/**
- * Remove the specified sync. This will remove any syncs that have been scheduled to run, but
- * will not cancel any running syncs.
- * <p>This method requires the caller to hold the permission</p>
- * If the request is for a periodic sync this will cancel future occurrences of the sync.
- *
- * It is possible to cancel a sync using a SyncRequest object that is different from the object
- * with which you requested the sync. Do so by building a SyncRequest with exactly the same
- * service/adapter, frequency, <b>and</b> extras bundle.
- *
- * @param request SyncRequest object containing information about sync to cancel.
- */
- public static void cancelSync(SyncRequest request) {
- // TODO: Finish this implementation.
- }
-
- /**
* Get the list of information about the periodic syncs for the given account and authority.
* <p>This method requires the caller to hold the permission
* {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index cd1f87b..2ff9182 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2011,6 +2011,17 @@
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.view.accessibility.CaptioningManager} for obtaining
+ * captioning properties and listening for changes in captioning
+ * preferences.
+ *
+ * @see #getSystemService
+ * @see android.view.accessibility.CaptioningManager
+ */
+ public static final String CAPTIONING_SERVICE = "captioning";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.app.NotificationManager} for controlling keyguard.
*
* @see #getSystemService
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d7ca9153..dfc0412 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3300,8 +3300,10 @@
/**
* Optional extra for {@link #ACTION_SHUTDOWN} that allows the sender to qualify that
* this shutdown is only for the user space of the system, not a complete shutdown.
- * Hardware should not be shut down when this is true. The default if not supplied
- * is false.
+ * When this is true, hardware devices can use this information to determine that
+ * they shouldn't do a complete shutdown of their device since this is not a
+ * complete shutdown down to the kernel, but only user space restarting.
+ * The default if not supplied is false.
*/
public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
= "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index 6aca151..b586eec 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -29,17 +29,13 @@
public final Account account;
/** The authority of the sync. Can be null. */
public final String authority;
- /** The service for syncing, if this is an anonymous sync. Can be null.*/
- public final ComponentName service;
/** Any extras that parameters that are to be passed to the sync adapter. */
public final Bundle extras;
/** How frequently the sync should be scheduled, in seconds. Kept around for API purposes. */
public final long period;
- /** Whether this periodic sync uses a service. */
- public final boolean isService;
/**
- * How much flexibility can be taken in scheduling the sync, in seconds.
* {@hide}
+ * How much flexibility can be taken in scheduling the sync, in seconds.
*/
public final long flexTime;
@@ -52,76 +48,44 @@
public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
this.account = account;
this.authority = authority;
- this.service = null;
- this.isService = false;
if (extras == null) {
this.extras = new Bundle();
} else {
this.extras = new Bundle(extras);
}
this.period = periodInSeconds;
- // Old API uses default flex time. No-one should be using this ctor anyway.
+ // Initialise to a sane value.
this.flexTime = 0L;
}
- // TODO: Add copy ctor from SyncRequest?
-
/**
- * Create a copy of a periodic sync.
* {@hide}
+ * Create a copy of a periodic sync.
*/
public PeriodicSync(PeriodicSync other) {
this.account = other.account;
this.authority = other.authority;
- this.service = other.service;
- this.isService = other.isService;
this.extras = new Bundle(other.extras);
this.period = other.period;
this.flexTime = other.flexTime;
}
/**
- * A PeriodicSync for a sync with a specified provider.
* {@hide}
+ * A PeriodicSync for a sync with a specified provider.
*/
public PeriodicSync(Account account, String authority, Bundle extras,
long period, long flexTime) {
this.account = account;
this.authority = authority;
- this.service = null;
- this.isService = false;
- this.extras = new Bundle(extras);
- this.period = period;
- this.flexTime = flexTime;
- }
-
- /**
- * A PeriodicSync for a sync with a specified SyncService.
- * {@hide}
- */
- public PeriodicSync(ComponentName service, Bundle extras,
- long period,
- long flexTime) {
- this.account = null;
- this.authority = null;
- this.service = service;
- this.isService = true;
this.extras = new Bundle(extras);
this.period = period;
this.flexTime = flexTime;
}
private PeriodicSync(Parcel in) {
- this.isService = (in.readInt() != 0);
- if (this.isService) {
- this.service = in.readParcelable(null);
- this.account = null;
- this.authority = null;
- } else {
- this.account = in.readParcelable(null);
- this.authority = in.readString();
- this.service = null;
- }
+ this.account = in.readParcelable(null);
+ this.authority = in.readString();
this.extras = in.readBundle();
this.period = in.readLong();
this.flexTime = in.readLong();
@@ -134,13 +98,8 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(isService ? 1 : 0);
- if (account == null && authority == null) {
- dest.writeParcelable(service, flags);
- } else {
- dest.writeParcelable(account, flags);
- dest.writeString(authority);
- }
+ dest.writeParcelable(account, flags);
+ dest.writeString(authority);
dest.writeBundle(extras);
dest.writeLong(period);
dest.writeLong(flexTime);
@@ -167,17 +126,8 @@
return false;
}
final PeriodicSync other = (PeriodicSync) o;
- if (this.isService != other.isService) {
- return false;
- }
- boolean equal = false;
- if (this.isService) {
- equal = service.equals(other.service);
- } else {
- equal = account.equals(other.account)
- && authority.equals(other.authority);
- }
- return equal
+ return account.equals(other.account)
+ && authority.equals(other.authority)
&& period == other.period
&& syncExtrasEquals(extras, other.extras);
}
@@ -208,7 +158,6 @@
public String toString() {
return "account: " + account +
", authority: " + authority +
- ", service: " + service +
". period: " + period + "s " +
", flex: " + flexTime;
}
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 4474c70..d4e0c2a 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -20,20 +20,19 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Pair;
public class SyncRequest implements Parcelable {
private static final String TAG = "SyncRequest";
- /** Account to pass to the sync adapter. Can be null. */
+ /** Account to pass to the sync adapter. May be null. */
private final Account mAccountToSync;
/** Authority string that corresponds to a ContentProvider. */
private final String mAuthority;
- /** {@link SyncService} identifier. */
+ /** Sync service identifier. May be null.*/
private final ComponentName mComponentInfo;
/** Bundle containing user info as well as sync settings. */
private final Bundle mExtras;
- /** Allow this sync request on metered networks. */
- private final boolean mAllowMetered;
+ /** Disallow this sync request on metered networks. */
+ private final boolean mDisallowMetered;
/**
* Anticipated upload size in bytes.
* TODO: Not yet used - we put this information into the bundle for simplicity.
@@ -70,14 +69,18 @@
return mIsPeriodic;
}
+ /**
+ * {@hide}
+ * @return whether this is an expedited sync.
+ */
public boolean isExpedited() {
return mIsExpedited;
}
/**
* {@hide}
- * @return true if this sync uses an account/authority pair, or false if
- * this is an anonymous sync bound to an @link AnonymousSyncService.
+ * @return true if this sync uses an account/authority pair, or false if this sync is bound to
+ * a Sync Service.
*/
public boolean hasAuthority() {
return mIsAuthority;
@@ -85,31 +88,30 @@
/**
* {@hide}
- * Throws a runtime IllegalArgumentException if this function is called for an
- * anonymous sync.
- *
- * @return (Account, Provider) for this SyncRequest.
+ * @return account object for this sync.
+ * @throws IllegalArgumentException if this function is called for a request that does not
+ * specify an account/provider authority.
*/
- public Pair<Account, String> getProviderInfo() {
+ public Account getAccount() {
if (!hasAuthority()) {
- throw new IllegalArgumentException("Cannot getProviderInfo() for an anonymous sync.");
+ throw new IllegalArgumentException("Cannot getAccount() for a sync that does not"
+ + "specify an authority.");
}
- return Pair.create(mAccountToSync, mAuthority);
+ return mAccountToSync;
}
/**
* {@hide}
- * Throws a runtime IllegalArgumentException if this function is called for a
- * SyncRequest that is bound to an account/provider.
- *
- * @return ComponentName for the service that this sync will bind to.
+ * @return provider for this sync.
+ * @throws IllegalArgumentException if this function is called for a request that does not
+ * specify an account/provider authority.
*/
- public ComponentName getService() {
- if (hasAuthority()) {
- throw new IllegalArgumentException(
- "Cannot getAnonymousService() for a sync that has specified a provider.");
+ public String getProvider() {
+ if (!hasAuthority()) {
+ throw new IllegalArgumentException("Cannot getProvider() for a sync that does not"
+ + "specify a provider.");
}
- return mComponentInfo;
+ return mAuthority;
}
/**
@@ -127,6 +129,7 @@
public long getSyncFlexTime() {
return mSyncFlexTimeSecs;
}
+
/**
* {@hide}
* @return the last point in time at which this sync must scheduled.
@@ -159,7 +162,7 @@
parcel.writeLong(mSyncFlexTimeSecs);
parcel.writeLong(mSyncRunTimeSecs);
parcel.writeInt((mIsPeriodic ? 1 : 0));
- parcel.writeInt((mAllowMetered ? 1 : 0));
+ parcel.writeInt((mDisallowMetered ? 1 : 0));
parcel.writeLong(mTxBytes);
parcel.writeLong(mRxBytes);
parcel.writeInt((mIsAuthority ? 1 : 0));
@@ -177,7 +180,7 @@
mSyncFlexTimeSecs = in.readLong();
mSyncRunTimeSecs = in.readLong();
mIsPeriodic = (in.readInt() != 0);
- mAllowMetered = (in.readInt() != 0);
+ mDisallowMetered = (in.readInt() != 0);
mTxBytes = in.readLong();
mRxBytes = in.readLong();
mIsAuthority = (in.readInt() != 0);
@@ -207,13 +210,13 @@
// For now we merge the sync config extras & the custom extras into one bundle.
// TODO: pass the configuration extras through separately.
mExtras.putAll(b.mSyncConfigExtras);
- mAllowMetered = b.mAllowMetered;
+ mDisallowMetered = b.mDisallowMetered;
mTxBytes = b.mTxBytes;
mRxBytes = b.mRxBytes;
}
/**
- * Builder class for a @link SyncRequest. As you build your SyncRequest this class will also
+ * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
* perform validation.
*/
public static class Builder {
@@ -229,12 +232,9 @@
private static final int SYNC_TARGET_SERVICE = 1;
/** Specify that this is a sync with a provider. */
private static final int SYNC_TARGET_ADAPTER = 2;
- /**
- * Earliest point of displacement into the future at which this sync can
- * occur.
- */
+ /** Earliest point of displacement into the future at which this sync can occur. */
private long mSyncFlexTimeSecs;
- /** Displacement into the future at which this sync must occur. */
+ /** Latest point of displacement into the future at which this sync must occur. */
private long mSyncRunTimeSecs;
/**
* Sync configuration information - custom user data explicitly provided by the developer.
@@ -253,7 +253,7 @@
/** Expected download transfer in bytes. */
private long mRxBytes = -1L;
/** Whether or not this sync can occur on metered networks. Default false. */
- private boolean mAllowMetered;
+ private boolean mDisallowMetered;
/** Priority of this sync relative to others from calling app [-2, 2]. Default 0. */
private int mPriority = 0;
/**
@@ -283,9 +283,8 @@
private boolean mExpedited;
/**
- * The {@link SyncService} component that
- * contains the sync logic if this is a provider-less sync, otherwise
- * null.
+ * The sync component that contains the sync logic if this is a provider-less sync,
+ * otherwise null.
*/
private ComponentName mComponentName;
/**
@@ -303,46 +302,28 @@
}
/**
- * Developer can define timing constraints for this one-shot request.
- * These values are elapsed real-time.
- *
- * @param whenSeconds The time in seconds at which you want this
- * sync to occur.
- * @param beforeSeconds The amount of time in advance of whenSeconds that this
- * sync may be permitted to occur. This is rounded up to a minimum of 5
- * seconds, for any sync for which whenSeconds > 5.
+ * Request that a sync occur immediately.
*
* Example
* <pre>
- * Perform an immediate sync.
- * SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce(0, 0);
- * That is, a sync 0 seconds from now with 0 seconds of flex.
- *
- * Perform a sync in exactly 5 minutes.
- * SyncRequest.Builder builder =
- * new SyncRequest.Builder().syncOnce(5 * MIN_IN_SECS, 0);
- *
- * Perform a sync in 5 minutes, with one minute of leeway (between 4 and 5 minutes from
- * now).
- * SyncRequest.Builder builder =
- * new SyncRequest.Builder().syncOnce(5 * MIN_IN_SECS, 1 * MIN_IN_SECS);
+ * SyncRequest.Builder builder = (new SyncRequest.Builder()).syncOnce();
* </pre>
*/
- public Builder syncOnce(long whenSeconds, long beforeSeconds) {
+ public Builder syncOnce() {
if (mSyncType != SYNC_TYPE_UNKNOWN) {
throw new IllegalArgumentException("Sync type has already been defined.");
}
mSyncType = SYNC_TYPE_ONCE;
- setupInterval(whenSeconds, beforeSeconds);
+ setupInterval(0, 0);
return this;
}
/**
* Build a periodic sync. Either this or syncOnce() <b>must</b> be called for this builder.
- * Syncs are identified by target {@link SyncService}/{@link android.provider} and by the
- * contents of the extras bundle.
- * You cannot reuse the same builder for one-time syncs after having specified a periodic
- * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
+ * Syncs are identified by target {@link android.provider}/{@link android.accounts.Account}
+ * and by the contents of the extras bundle.
+ * You cannot reuse the same builder for one-time syncs (by calling this function) after
+ * having specified a periodic sync. If you do, an <code>IllegalArgumentException</code>
* will be thrown.
*
* Example usage.
@@ -394,6 +375,7 @@
}
/**
+ * {@hide}
* Developer can provide insight into their payload size; optional. -1 specifies unknown,
* so that you are not restricted to defining both fields.
*
@@ -407,21 +389,20 @@
}
/**
- * @param allow false to allow this transfer on metered networks. Default true.
+ * @see android.net.ConnectivityManager#isActiveNetworkMetered()
+ * @param disallow true to enforce that this transfer not occur on metered networks.
+ * Default false.
*/
- public Builder setAllowMetered(boolean allow) {
- mAllowMetered = true;
+ public Builder setDisallowMetered(boolean disallow) {
+ mDisallowMetered = disallow;
return this;
}
/**
- * Specify an authority and account for this transfer. Cannot be used with
- * {@link #setSyncAdapter(ComponentName cname)}.
+ * Specify an authority and account for this transfer.
*
- * @param authority
- * @param account Account to sync. Can be null unless this is a periodic
- * sync, for which verification by the ContentResolver will
- * fail. If a sync is performed without an account, the
+ * @param authority String identifying which content provider to sync.
+ * @param account Account to sync. Can be null unless this is a periodic sync.
*/
public Builder setSyncAdapter(Account account, String authority) {
if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
@@ -435,26 +416,10 @@
}
/**
- * Specify the {@link SyncService} component for this sync. This is not validated until
- * sync time so providing an incorrect component name here will not fail. Cannot be used
- * with {@link #setSyncAdapter(Account account, String authority)}.
- *
- * @param cname ComponentName to identify your Anonymous service
- */
- public Builder setSyncAdapter(ComponentName cname) {
- if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
- throw new IllegalArgumentException("Sync target has already been defined.");
- }
- mSyncTarget = SYNC_TARGET_SERVICE;
- mComponentName = cname;
- mAccount = null;
- mAuthority = null;
- return this;
- }
-
- /**
- * Developer-provided extras handed back when sync actually occurs. This bundle is copied
- * into the SyncRequest returned by {@link #build()}.
+ * Optional developer-provided extras handed back in
+ * {@link AbstractThreadedSyncAdapter#onPerformSync(Account, Bundle, String,
+ * ContentProviderClient, SyncResult)} occurs. This bundle is copied into the SyncRequest
+ * returned by {@link #build()}.
*
* Example:
* <pre>
@@ -468,7 +433,7 @@
* Bundle extras = new Bundle();
* extras.setString("data", syncData);
* builder.setExtras(extras);
- * ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync.
+ * ContentResolver.sync(builder.build()); // Each sync() request is for a unique sync.
* }
* </pre>
* Only values of the following types may be used in the extras bundle:
@@ -509,7 +474,8 @@
/**
* Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_SETTINGS}.
*
- * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+ * A sync can specify that system sync settings be ignored (user has turned sync off). Not
+ * valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
* {@link #build()}.
*
* @param ignoreSettings true to ignore the sync automatically settings. Default false.
@@ -522,13 +488,13 @@
/**
* Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_IGNORE_BACKOFF}.
*
- * Ignoring back-off will force the sync scheduling process to ignore any back-off that was
- * the result of a failed sync, as well as to invalidate any {@link SyncResult#delayUntil}
- * value that may have been set by the adapter. Successive failures will not honor this
- * flag. Not valid for periodic sync and will throw an <code>IllegalArgumentException</code>
- * in {@link #build()}.
+ * Force the sync scheduling process to ignore any back-off that was the result of a failed
+ * sync, as well as to invalidate any {@link SyncResult#delayUntil} value that may have
+ * been set by the adapter. Successive failures will not honor this flag. Not valid for
+ * periodic sync and will throw an <code>IllegalArgumentException</code> in
+ * {@link #build()}.
*
- * @param ignoreBackoff ignore back off settings. Default false.
+ * @param ignoreBackoff ignore back-off settings. Default false.
*/
public Builder setIgnoreBackoff(boolean ignoreBackoff) {
mIgnoreBackoff = ignoreBackoff;
@@ -538,8 +504,9 @@
/**
* Convenience function for setting {@link ContentResolver#SYNC_EXTRAS_MANUAL}.
*
- * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
- * {@link #build()}.
+ * A manual sync is functionally equivalent to calling {@link #setIgnoreBackoff(boolean)}
+ * and {@link #setIgnoreSettings(boolean)}. Not valid for periodic sync and will throw an
+ * <code>IllegalArgumentException</code> in {@link #build()}.
*
* @param isManual User-initiated sync or not. Default false.
*/
@@ -549,7 +516,7 @@
}
/**
- * An expedited sync runs immediately and can preempt other non-expedited running syncs.
+ * An expedited sync runs immediately and will preempt another non-expedited running sync.
*
* Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
* {@link #build()}.
@@ -562,6 +529,7 @@
}
/**
+ * {@hide}
* @param priority the priority of this request among all requests from the calling app.
* Range of [-2,2] similar to how this is done with notifications.
*/
@@ -581,18 +549,18 @@
* builder.
*/
public SyncRequest build() {
- // Validate the extras bundle
- ContentResolver.validateSyncExtrasBundle(mCustomExtras);
if (mCustomExtras == null) {
mCustomExtras = new Bundle();
}
+ // Validate the extras bundle
+ ContentResolver.validateSyncExtrasBundle(mCustomExtras);
// Combine builder extra flags into the config bundle.
mSyncConfigExtras = new Bundle();
if (mIgnoreBackoff) {
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
}
- if (mAllowMetered) {
- mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_ALLOW_METERED, true);
+ if (mDisallowMetered) {
+ mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, true);
}
if (mIgnoreSettings) {
mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
@@ -613,13 +581,22 @@
// If this is a periodic sync ensure than invalid extras were not set.
validatePeriodicExtras(mCustomExtras);
validatePeriodicExtras(mSyncConfigExtras);
+ // Verify that account and provider are not null.
+ if (mAccount == null) {
+ throw new IllegalArgumentException("Account must not be null for periodic"
+ + " sync.");
+ }
+ if (mAuthority == null) {
+ throw new IllegalArgumentException("Authority must not be null for periodic"
+ + " sync.");
+ }
} else if (mSyncType == SYNC_TYPE_UNKNOWN) {
throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
}
// Ensure that a target for the sync has been set.
if (mSyncTarget == SYNC_TARGET_UNKNOWN) {
- throw new IllegalArgumentException("Must specify an adapter with one of"
- + "setSyncAdapter(ComponentName) or setSyncAdapter(Account, String");
+ throw new IllegalArgumentException("Must specify an adapter with "
+ + "setSyncAdapter(Account, String");
}
return new SyncRequest(this);
}
diff --git a/core/java/android/content/SyncService.java b/core/java/android/content/SyncService.java
deleted file mode 100644
index 100fd40..0000000
--- a/core/java/android/content/SyncService.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.app.Service;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.Trace;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.HashMap;
-
-/**
- * Simplified @link android.content.AbstractThreadedSyncAdapter. Folds that
- * behaviour into a service to which the system can bind when requesting an
- * anonymous (providerless/accountless) sync.
- * <p>
- * In order to perform an anonymous sync operation you must extend this service,
- * implementing the abstract methods. This service must then be declared in the
- * application's manifest as usual. You can use this service for other work, however you
- * <b> must not </b> override the onBind() method unless you know what you're doing,
- * which limits the usefulness of this service for other work.
- *
- * <pre>
- * <service ndroid:name=".MyAnonymousSyncService" android:permission="android.permission.SYNC" />
- * </pre>
- * Like @link android.content.AbstractThreadedSyncAdapter this service supports
- * multiple syncs at the same time. Each incoming startSync() with a unique tag
- * will spawn a thread to do the work of that sync. If startSync() is called
- * with a tag that already exists, a SyncResult.ALREADY_IN_PROGRESS is returned.
- * Remember that your service will spawn multiple threads if you schedule multiple syncs
- * at once, so if you mutate local objects you must ensure synchronization.
- */
-public abstract class SyncService extends Service {
-
- /** SyncAdapter Instantiation that any anonymous syncs call. */
- private final AnonymousSyncAdapterImpl mSyncAdapter = new AnonymousSyncAdapterImpl();
-
- /** Keep track of on-going syncs, keyed by tag. */
- @GuardedBy("mLock")
- private final HashMap<Bundle, AnonymousSyncThread>
- mSyncThreads = new HashMap<Bundle, AnonymousSyncThread>();
- /** Lock object for accessing the SyncThreads HashMap. */
- private final Object mSyncThreadLock = new Object();
-
- @Override
- public IBinder onBind(Intent intent) {
- return mSyncAdapter.asBinder();
- }
-
- /** {@hide} */
- private class AnonymousSyncAdapterImpl extends IAnonymousSyncAdapter.Stub {
-
- @Override
- public void startSync(ISyncContext syncContext, Bundle extras) {
- // Wrap the provided Sync Context because it may go away by the time
- // we call it.
- final SyncContext syncContextClient = new SyncContext(syncContext);
- boolean alreadyInProgress = false;
- synchronized (mSyncThreadLock) {
- if (mSyncThreads.containsKey(extras)) {
- // Don't want to call back to SyncManager while still
- // holding lock.
- alreadyInProgress = true;
- } else {
- AnonymousSyncThread syncThread = new AnonymousSyncThread(
- syncContextClient, extras);
- mSyncThreads.put(extras, syncThread);
- syncThread.start();
- }
- }
- if (alreadyInProgress) {
- syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
- }
- }
-
- /**
- * Used by the SM to cancel a specific sync using the {@link
- * com.android.server.content.SyncManager.ActiveSyncContext} as a handle.
- */
- @Override
- public void cancelSync(ISyncContext syncContext) {
- AnonymousSyncThread runningSync = null;
- synchronized (mSyncThreadLock) {
- for (AnonymousSyncThread thread : mSyncThreads.values()) {
- if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
- runningSync = thread;
- break;
- }
- }
- }
- if (runningSync != null) {
- runningSync.interrupt();
- }
- }
- }
-
- /**
- * {@hide}
- * Similar to {@link android.content.AbstractThreadedSyncAdapter.SyncThread}. However while
- * the ATSA considers an already in-progress sync to be if the account provided is currently
- * syncing, this anonymous sync has no notion of account and therefore considers a sync unique
- * if the provided bundle is different.
- */
- private class AnonymousSyncThread extends Thread {
- private final SyncContext mSyncContext;
- private final Bundle mExtras;
-
- public AnonymousSyncThread(SyncContext syncContext, Bundle extras) {
- mSyncContext = syncContext;
- mExtras = extras;
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
- Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, getApplication().getPackageName());
-
- SyncResult syncResult = new SyncResult();
- try {
- if (isCancelled()) {
- return;
- }
- // Run the sync based off of the provided code.
- SyncService.this.onPerformSync(mExtras, syncResult);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
- if (!isCancelled()) {
- mSyncContext.onFinished(syncResult);
- }
- // Synchronize so that the assignment will be seen by other
- // threads
- // that also synchronize accesses to mSyncThreads.
- synchronized (mSyncThreadLock) {
- mSyncThreads.remove(mExtras);
- }
- }
- }
-
- private boolean isCancelled() {
- return Thread.currentThread().isInterrupted();
- }
- }
-
- /**
- * Initiate an anonymous sync using this service. SyncAdapter-specific
- * parameters may be specified in extras, which is guaranteed to not be
- * null.
- */
- public abstract void onPerformSync(Bundle extras, SyncResult syncResult);
-
-}
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 3f17dc4..3dc8717 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -52,7 +52,7 @@
* Bit in {@link #flags}: If set,
* {@link android.app.Service#onProvideAssistData(android.os.Bundle)} will
* be called on the service when it is running in the foreground. Set from
- * the android.R.attr#provideAssistData attribute.
+ * the {@link android.R.attr#provideAssistData} attribute.
*/
public static final int FLAG_PROVIDE_ASSIST_DATA = 0x0004;
diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java
index e1d359c..ec08393 100644
--- a/core/java/android/ddm/DdmHandleProfiling.java
+++ b/core/java/android/ddm/DdmHandleProfiling.java
@@ -186,7 +186,7 @@
* Handle a "Method PRofiling Query" request.
*/
private Chunk handleMPRQ(Chunk request) {
- int result = Debug.isMethodTracingActive() ? 1 : 0;
+ int result = Debug.getMethodTracingMode();
/* create a non-empty reply so the handler fires on completion */
byte[] reply = { (byte) result };
diff --git a/core/java/android/hardware/FlushCompleteListener.java b/core/java/android/hardware/FlushCompleteListener.java
new file mode 100644
index 0000000..cb5b9e3
--- /dev/null
+++ b/core/java/android/hardware/FlushCompleteListener.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package android.hardware;
+
+/**
+ * Used for receiving a notification when a flush() has been successfully completed.
+ * @hide
+ */
+public interface FlushCompleteListener {
+ /**
+ * Called after flush() is completed. This flush() could have been initiated by this application
+ * or some other application. All the events in the batch at the point when the flush was called
+ * have been delivered to the applications registered for those sensor events.
+ * <p>
+ *
+ * @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
+ *
+ * @see android.hardware.SensorManager#flush(Sensor)
+ */
+ public void onFlushCompleted(Sensor sensor);
+}
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 9bffdbe..bbede57 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -319,6 +319,8 @@
private float mResolution;
private float mPower;
private int mMinDelay;
+ private int mFifoReservedEventCount;
+ private int mFifoMaxEventCount;
Sensor() {
}
@@ -381,6 +383,26 @@
return mMinDelay;
}
+ /**
+ * @return Number of events reserved for this sensor in the batch mode FIFO. This gives a
+ * guarantee on the minimum number of events that can be batched
+ * @hide
+ */
+ public int getFifoReservedEventCount() {
+ return mFifoReservedEventCount;
+ }
+
+ /**
+ * @return Maximum number of events of this sensor that could be batched. If this value is zero
+ * it indicates that batch mode is not supported for this sensor. If other applications
+ * registered to batched sensors, the actual number of events that can be batched might be
+ * smaller because the hardware FiFo will be partially used to batch the other sensors.
+ * @hide
+ */
+ public int getFifoMaxEventCount() {
+ return mFifoMaxEventCount;
+ }
+
/** @hide */
public int getHandle() {
return mHandle;
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 30118f9..b6ca62a 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -608,8 +608,72 @@
}
/**
- * Registers a {@link android.hardware.SensorEventListener
- * SensorEventListener} for the given sensor.
+ * Enables batch mode for a sensor with the given rate and maxBatchReportLatency. If the
+ * underlying hardware does not support batch mode, this defaults to
+ * {@link #registerListener(SensorEventListener, Sensor, int)} and other parameters are are
+ * ignored. In non-batch mode, all sensor events must be reported as soon as they are detected.
+ * While in batch mode, sensor events do not need to be reported as soon as they are detected.
+ * They can be temporarily stored in batches and reported in batches, as long as no event is
+ * delayed by more than "maxBatchReportLatency" microseconds. That is, all events since the
+ * previous batch are recorded and returned all at once. This allows to reduce the amount of
+ * interrupts sent to the SoC, and allows the SoC to switch to a lower power state (Idle) while
+ * the sensor is capturing and batching data.
+ * <p>
+ * Registering to a sensor in batch mode will not prevent the SoC from going to suspend mode. In
+ * this case, the sensor will continue to gather events and store it in a hardware FIFO. If the
+ * FIFO gets full before the AP wakes up again, some events will be lost, as the older events
+ * get overwritten by new events in the hardware FIFO. This can be avoided by holding a wake
+ * lock. If the application holds a wake lock, the SoC will not go to suspend mode, so no events
+ * will be lost, as the events will be reported before the FIFO gets full.
+ * </p>
+ * <p>
+ * Batching is always best effort. If a different application requests updates in continuous
+ * mode, this application will also get events in continuous mode. Batch mode updates can be
+ * unregistered by calling {@link #unregisterListener(SensorEventListener)}.
+ * </p>
+ * <p class="note">
+ * </p>
+ * Note: Don't use this method with a one shot trigger sensor such as
+ * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
+ * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
+ *
+ * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
+ * that will receive the sensor events.
+ * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+ * @param rate The desired delay between two consecutive events in microseconds. This is only a
+ * hint to the system. Events may be received faster or slower than the specified
+ * rate. Usually events are received faster. Can be one of
+ * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+ * {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
+ * microseconds.
+ * @param maxBatchReportLatency An event in the batch can be delayed by at most
+ * maxBatchReportLatency microseconds. More events can be batched if this value is
+ * large. If this is set to zero, batch mode is disabled and events are delivered in
+ * continuous mode as soon as they are available which is equivalent to calling
+ * {@link #registerListener(SensorEventListener, Sensor, int)}.
+ * @param reservedFlags Always set to Zero.
+ * @param flushCompleteListener A {@link android.hardware.FlushCompleteListener
+ * FlushCompleteListener} object which is called when any application calls flush()
+ * on this sensor and all the events in the batch at the time of calling flush() are
+ * successfully delivered to the listeners.
+ * @return true if batch mode is successfully enabled for this sensor, false otherwise.
+ * @see #registerListener(SensorEventListener, Sensor, int)
+ * @see #unregisterListener(SensorEventListener)
+ * @see #flush(Sensor)
+ * @throws IllegalArgumentException when sensor or listener is null or a trigger sensor.
+ * @hide
+ */
+ public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+ int maxBatchReportLatencyUs, int reservedFlags,
+ FlushCompleteListener flushCompleteListener) {
+ int delay = getDelay(rateUs);
+ return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs,
+ reservedFlags, flushCompleteListener);
+ }
+
+ /**
+ * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+ * sensor. Events are delivered in continuous mode as soon as they are available.
*
* <p class="note"></p>
* Note: Don't use this method with a one shot trigger sensor such as
@@ -655,31 +719,55 @@
return false;
}
- int delay = -1;
- switch (rate) {
- case SENSOR_DELAY_FASTEST:
- delay = 0;
- break;
- case SENSOR_DELAY_GAME:
- delay = 20000;
- break;
- case SENSOR_DELAY_UI:
- delay = 66667;
- break;
- case SENSOR_DELAY_NORMAL:
- delay = 200000;
- break;
- default:
- delay = rate;
- break;
- }
+ int delay = getDelay(rate);
+ return registerListenerImpl(listener, sensor, delay, handler, 0, 0, null);
+ }
- return registerListenerImpl(listener, sensor, delay, handler);
+ /**
+ * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
+ * @param handler
+ * The {@link android.os.Handler Handler} the
+ * {@link android.hardware.SensorEvent sensor events} will be
+ * delivered to.
+ *
+ * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+ * @hide
+ */
+ public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
+ int maxBatchReportLatencyUs, int reservedFlags, Handler handler,
+ FlushCompleteListener flushCompleteListener) {
+ int delayUs = getDelay(rateUs);
+ return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs,
+ reservedFlags, flushCompleteListener);
}
/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
- int delay, Handler handler);
+ int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+ FlushCompleteListener flushCompleteListener);
+
+
+ /**
+ * Flushes the batch FIFO of the given sensor. If there are events in the FIFO of this sensor,
+ * they are returned as if the batch timeout has expired. Events are returned in the
+ * usual way through the SensorEventListener. This call doesn't effect the batch timeout for
+ * this sensor. This call is asynchronous and returns immediately. FlushCompleteListener is
+ * called after all the events in the batch at the time of calling this method have been
+ * delivered successfully.
+ * @param sensor
+ * The {@link android.hardware.Sensor Sensor} to flush.
+ * @return true if the flush is initiated successfully. false if the sensor isn't active
+ * i.e no application is registered for updates from this sensor.
+ * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+ * @throws IllegalArgumentException when sensor is null or a trigger sensor.
+ * @hide
+ */
+ public boolean flush(Sensor sensor) {
+ return flushImpl(sensor);
+ }
+
+ /** @hide */
+ protected abstract boolean flushImpl(Sensor sensor);
/**
* <p>
@@ -1079,15 +1167,15 @@
* <p>
* All three angles above are in <b>radians</b> and <b>positive</b> in the
* <b>counter-clockwise</b> direction.
- *
+ *
* @param R
* rotation matrix see {@link #getRotationMatrix}.
- *
+ *
* @param values
* an array of 3 floats to hold the result.
- *
+ *
* @return The array values passed as argument.
- *
+ *
* @see #getRotationMatrix(float[], float[], float[], float[])
* @see GeomagneticField
*/
@@ -1407,4 +1495,26 @@
return mLegacySensorManager;
}
}
+
+ private static int getDelay(int rate) {
+ int delay = -1;
+ switch (rate) {
+ case SENSOR_DELAY_FASTEST:
+ delay = 0;
+ break;
+ case SENSOR_DELAY_GAME:
+ delay = 20000;
+ break;
+ case SENSOR_DELAY_UI:
+ delay = 66667;
+ break;
+ case SENSOR_DELAY_NORMAL:
+ delay = 200000;
+ break;
+ default:
+ delay = rate;
+ break;
+ }
+ return delay;
+ }
}
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 852cf4a..9747f0d 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -93,30 +93,35 @@
/** @hide */
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
- int delay, Handler handler)
- {
+ int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
+ FlushCompleteListener flushCompleteListener) {
+ if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
+ if (reservedFlags != 0) throw new IllegalArgumentException("reservedFlags should be zero");
+ if (delayUs < 0) throw new IllegalArgumentException("rateUs should be positive");
+ if (maxBatchReportLatencyUs < 0)
+ throw new IllegalArgumentException("maxBatchReportLatencyUs should be positive");
+ // Trigger Sensors should use the requestTriggerSensor call.
+ if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+ throw new IllegalArgumentException("Trigger Sensors cannot use registerListener");
+
// Invariants to preserve:
// - one Looper per SensorEventListener
// - one Looper per SensorEventQueue
// We map SensorEventListener to a SensorEventQueue, which holds the looper
- if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
-
- // Trigger Sensors should use the requestTriggerSensor call.
- if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false;
-
synchronized (mSensorListeners) {
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
- queue = new SensorEventQueue(listener, looper, this);
- if (!queue.addSensor(sensor, delay)) {
+ queue = new SensorEventQueue(listener, looper, this, flushCompleteListener);
+ if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
queue.dispose();
return false;
}
mSensorListeners.put(listener, queue);
return true;
} else {
- return queue.addSensor(sensor, delay);
+ return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags);
}
}
}
@@ -157,14 +162,14 @@
TriggerEventQueue queue = mTriggerListeners.get(listener);
if (queue == null) {
queue = new TriggerEventQueue(listener, mMainLooper, this);
- if (!queue.addSensor(sensor, 0)) {
+ if (!queue.addSensor(sensor, 0, 0, 0)) {
queue.dispose();
return false;
}
mTriggerListeners.put(listener, queue);
return true;
} else {
- return queue.addSensor(sensor, 0);
+ return queue.addSensor(sensor, 0, 0, 0);
}
}
}
@@ -195,6 +200,18 @@
}
}
+ protected boolean flushImpl(Sensor sensor) {
+ if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
+ if(Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
+ throw new IllegalArgumentException("Trigger Sensors cannot call flush");
+
+ FlushEventQueue queue = new FlushEventQueue(mMainLooper, this);
+ if (queue.flushSensor(sensor) != 0) {
+ return false;
+ }
+ return true;
+ }
+
/*
* BaseEventQueue is the communication channel with the sensor service,
* SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between
@@ -202,11 +219,12 @@
*/
private static abstract class BaseEventQueue {
private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ,
-
float[] scratch);
- private static native int nativeEnableSensor(int eventQ, int handle, int us);
+ private static native int nativeEnableSensor(int eventQ, int handle, int rateUs,
+ int maxBatchReportLatencyUs, int reservedFlags);
private static native int nativeDisableSensor(int eventQ, int handle);
private static native void nativeDestroySensorEventQueue(int eventQ);
+ private static native int nativeFlushSensor(int eventQ, int handle);
private int nSensorEventQueue;
private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -225,7 +243,8 @@
dispose(false);
}
- public boolean addSensor(Sensor sensor, int delay) {
+ public boolean addSensor(
+ Sensor sensor, int delayUs, int maxBatchReportLatencyUs, int reservedFlags) {
// Check if already present.
int handle = sensor.getHandle();
if (mActiveSensors.get(handle)) return false;
@@ -233,9 +252,13 @@
// Get ready to receive events before calling enable.
mActiveSensors.put(handle, true);
addSensorEvent(sensor);
- if (enableSensor(sensor, delay) != 0) {
- removeSensor(sensor, false);
- return false;
+ if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags) != 0) {
+ // Try continuous mode if batching fails.
+ if (maxBatchReportLatencyUs == 0 ||
+ maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0, 0) != 0) {
+ removeSensor(sensor, false);
+ return false;
+ }
}
return true;
}
@@ -268,6 +291,12 @@
return false;
}
+ public int flushSensor(Sensor sensor) {
+ if (nSensorEventQueue == 0) throw new NullPointerException();
+ if (sensor == null) throw new NullPointerException();
+ return nativeFlushSensor(nSensorEventQueue, sensor.getHandle());
+ }
+
public boolean hasSensors() {
// no more sensors are set
return mActiveSensors.indexOfValue(true) >= 0;
@@ -295,11 +324,14 @@
}
}
- private int enableSensor(Sensor sensor, int us) {
+ private int enableSensor(
+ Sensor sensor, int rateUs, int maxBatchReportLatencyUs, int reservedFlags) {
if (nSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
- return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), us);
+ return nativeEnableSensor(nSensorEventQueue, sensor.getHandle(), rateUs,
+ maxBatchReportLatencyUs, reservedFlags);
}
+
private int disableSensor(Sensor sensor) {
if (nSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
@@ -307,6 +339,7 @@
}
protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
long timestamp);
+ protected abstract void dispatchFlushCompleteEvent(int handle);
protected abstract void addSensorEvent(Sensor sensor);
protected abstract void removeSensorEvent(Sensor sensor);
@@ -314,12 +347,14 @@
static final class SensorEventQueue extends BaseEventQueue {
private final SensorEventListener mListener;
+ private final FlushCompleteListener mFlushCompleteListener;
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
public SensorEventQueue(SensorEventListener listener, Looper looper,
- SystemSensorManager manager) {
+ SystemSensorManager manager, FlushCompleteListener flushCompleteListener) {
super(looper, manager);
mListener = listener;
+ mFlushCompleteListener = flushCompleteListener;
}
public void addSensorEvent(Sensor sensor) {
@@ -370,6 +405,15 @@
}
mListener.onSensorChanged(t);
}
+
+ @SuppressWarnings("unused")
+ protected void dispatchFlushCompleteEvent(int handle) {
+ final Sensor sensor = sHandleToSensor.get(handle);
+ if (mFlushCompleteListener != null) {
+ mFlushCompleteListener.onFlushCompleted(sensor);
+ }
+ return;
+ }
}
static final class TriggerEventQueue extends BaseEventQueue {
@@ -415,5 +459,35 @@
mListener.onTrigger(t);
}
+
+ @SuppressWarnings("unused")
+ protected void dispatchFlushCompleteEvent(int handle) {
+ }
+ }
+
+ static final class FlushEventQueue extends BaseEventQueue {
+ public FlushEventQueue(Looper looper, SystemSensorManager manager) {
+ super(looper, manager);
+ }
+
+ @SuppressWarnings("unused")
+ @Override
+ protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
+ long timestamp) {
+ }
+
+ @Override
+ @SuppressWarnings("unused")
+ protected void addSensorEvent(Sensor sensor) {
+ }
+
+ @Override
+ @SuppressWarnings("unused")
+ protected void removeSensorEvent(Sensor sensor) {
+ }
+
+ @SuppressWarnings("unused")
+ protected void dispatchFlushCompleteEvent(int handle) {
+ }
}
}
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 8b5bf4a..3f9b9e9 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -303,13 +303,14 @@
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
@@ -378,13 +379,14 @@
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific focus area
@@ -462,12 +464,15 @@
* <p>
* Only used in AUTO mode.
* </p><p>
- * Each area is a rectangle plus weight: xmin, ymin, xmax,
- * ymax, weight. The coordinate system is based on the active
- * pixel array, with (0,0) being the top-left of the active
- * pixel array, and (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * Each area is a rectangle plus weight: xmin, ymin,
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
+ * </p><p>
+ * The coordinate system is based on the active pixel array,
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ef6aaa0..bd151a2 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -198,13 +198,14 @@
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
@@ -258,13 +259,14 @@
* </p>
* <p>
* Each area is a rectangle plus weight: xmin, ymin,
- * xmax, ymax, weight.
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
* </p><p>
* The coordinate system is based on the active pixel array,
- * with (0,0) being the top-left of the active pixel array, and
- * (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific focus area
@@ -342,12 +344,15 @@
* <p>
* Only used in AUTO mode.
* </p><p>
- * Each area is a rectangle plus weight: xmin, ymin, xmax,
- * ymax, weight. The coordinate system is based on the active
- * pixel array, with (0,0) being the top-left of the active
- * pixel array, and (android.sensor.info.activeArraySize.width,
- * android.sensor.info.activeArraySize.height) being the
- * bottom-right point of the active pixel array. The weight
+ * Each area is a rectangle plus weight: xmin, ymin,
+ * xmax, ymax, weight. The rectangle is defined inclusive of the
+ * specified coordinates.
+ * </p><p>
+ * The coordinate system is based on the active pixel array,
+ * with (0,0) being the top-left pixel in the active pixel array, and
+ * (android.sensor.info.activeArraySize.width - 1,
+ * android.sensor.info.activeArraySize.height - 1) being the
+ * bottom-right pixel in the active pixel array. The weight
* should be nonnegative.
* </p><p>
* If all regions have 0 weight, then no specific metering area
diff --git a/core/java/android/hardware/camera2/Rational.java b/core/java/android/hardware/camera2/Rational.java
index 0260e02..77b8c26 100644
--- a/core/java/android/hardware/camera2/Rational.java
+++ b/core/java/android/hardware/camera2/Rational.java
@@ -26,22 +26,17 @@
/**
* <p>Create a Rational with a given numerator and denominator.</p>
*
- * <p>
- * The signs of the numerator and the denominator may be flipped such that the denominator
- * is always 0.
- * </p>
+ * <p>The signs of the numerator and the denominator may be flipped such that the denominator
+ * is always positive.</p>
+ *
+ * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
+ * as float NaN and INF values. The int getter functions return 0 in this case.</p>
*
* @param numerator the numerator of the rational
* @param denominator the denominator of the rational
- *
- * @throws IllegalArgumentException if the denominator is 0
*/
public Rational(int numerator, int denominator) {
- if (denominator == 0) {
- throw new IllegalArgumentException("Argument 'denominator' is 0");
- }
-
if (denominator < 0) {
numerator = -numerator;
denominator = -denominator;
@@ -55,6 +50,9 @@
* Gets the numerator of the rational.
*/
public int getNumerator() {
+ if (mDenominator == 0) {
+ return 0;
+ }
return mNumerator;
}
@@ -65,22 +63,41 @@
return mDenominator;
}
+ private boolean isNaN() {
+ return mDenominator == 0 && mNumerator == 0;
+ }
+
+ private boolean isInf() {
+ return mDenominator == 0 && mNumerator > 0;
+ }
+
+ private boolean isNegInf() {
+ return mDenominator == 0 && mNumerator < 0;
+ }
+
/**
* <p>Compare this Rational to another object and see if they are equal.</p>
*
* <p>A Rational object can only be equal to another Rational object (comparing against any other
* type will return false).</p>
*
- * <p>A Rational object is considered equal to another Rational object if and only if their
- * reduced forms have the same numerator and denominator.</p>
+ * <p>A Rational object is considered equal to another Rational object if and only if one of
+ * the following holds</p>:
+ * <ul><li>Both are NaN</li>
+ * <li>Both are infinities of the same sign</li>
+ * <li>Both have the same numerator and denominator in their reduced form</li>
+ * </ul>
*
* <p>A reduced form of a Rational is calculated by dividing both the numerator and the
* denominator by their greatest common divisor.</p>
*
* <pre>
- * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
- * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
- * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(1, 2)).equals(new Rational(1, 2)) == true // trivially true
+ * (new Rational(2, 3)).equals(new Rational(1, 2)) == false // trivially false
+ * (new Rational(1, 2)).equals(new Rational(2, 4)) == true // true after reduction
+ * (new Rational(0, 0)).equals(new Rational(0, 0)) == true // NaN.equals(NaN)
+ * (new Rational(1, 0)).equals(new Rational(5, 0)) == true // both are +infinity
+ * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
* </pre>
*
* @param obj a reference to another object
@@ -91,13 +108,17 @@
public boolean equals(Object obj) {
if (obj == null) {
return false;
- }
- if (this == obj) {
- return true;
- }
- if (obj instanceof Rational) {
+ } else if (obj instanceof Rational) {
Rational other = (Rational) obj;
- if(mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
+ if (mDenominator == 0 || other.mDenominator == 0) {
+ if (isNaN() && other.isNaN()) {
+ return true;
+ } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
+ return true;
+ } else {
+ return false;
+ }
+ } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
return true;
} else {
int thisGcd = gcd();
@@ -117,7 +138,25 @@
@Override
public String toString() {
- return mNumerator + "/" + mDenominator;
+ if (isNaN()) {
+ return "NaN";
+ } else if (isInf()) {
+ return "Infinity";
+ } else if (isNegInf()) {
+ return "-Infinity";
+ } else {
+ return mNumerator + "/" + mDenominator;
+ }
+ }
+
+ /**
+ * <p>Convert to a floating point representation.</p>
+ *
+ * @return The floating point representation of this rational number.
+ * @hide
+ */
+ public float toFloat() {
+ return (float) mNumerator / (float) mDenominator;
}
@Override
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 64e4dc9..86a073f 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -301,7 +301,9 @@
synchronized (mLock) {
try {
- mRemoteDevice.disconnect();
+ if (mRemoteDevice != null) {
+ mRemoteDevice.disconnect();
+ }
} catch (CameraRuntimeException e) {
throw e.asChecked();
} catch (RemoteException e) {
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 6b96ad4..01977cd 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -397,17 +397,14 @@
long responseTimestamp = SystemClock.elapsedRealtime();
// we got a valid response, but not from the real google
- boolean isCaptivePortal = urlConnection.getResponseCode() != 204;
+ int rspCode = urlConnection.getResponseCode();
+ boolean isCaptivePortal = rspCode != 204;
sendNetworkConditionsBroadcast(true /* response received */, isCaptivePortal,
requestTimestamp, responseTimestamp);
+
+ if (DBG) log("isCaptivePortal: ret=" + isCaptivePortal + " rspCode=" + rspCode);
return isCaptivePortal;
- } catch (SocketTimeoutException e) {
- if (DBG) log("Probably a portal: exception " + e);
- if (requestTimestamp != -1) {
- sendFailedCaptivePortalCheckBroadcast(requestTimestamp);
- } // else something went wrong with setting up the urlConnection
- return true;
} catch (IOException e) {
if (DBG) log("Probably not a portal: exception " + e);
if (requestTimestamp != -1) {
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/IAppCallback.aidl
similarity index 89%
rename from core/java/android/nfc/INdefPushCallback.aidl
rename to core/java/android/nfc/IAppCallback.aidl
index 16771dc..9599308 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/IAppCallback.aidl
@@ -17,12 +17,14 @@
package android.nfc;
import android.nfc.BeamShareData;
+import android.nfc.Tag;
/**
* @hide
*/
-interface INdefPushCallback
+interface IAppCallback
{
BeamShareData createBeamShareData();
void onNdefPushComplete();
+ void onTagDiscovered(in Tag tag);
}
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 15d0475..8414738 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -21,10 +21,11 @@
import android.nfc.NdefMessage;
import android.nfc.Tag;
import android.nfc.TechListParcel;
-import android.nfc.INdefPushCallback;
+import android.nfc.IAppCallback;
import android.nfc.INfcAdapterExtras;
import android.nfc.INfcTag;
import android.nfc.INfcCardEmulation;
+import android.os.Bundle;
/**
* @hide
@@ -44,10 +45,10 @@
void setForegroundDispatch(in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
- void setNdefPushCallback(in INdefPushCallback callback);
+ void setAppCallback(in IAppCallback callback);
void dispatch(in Tag tag);
- void setReaderMode (IBinder b, int flags);
+ void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
void setP2pModes(int initatorModes, int targetModes);
}
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index d0d943c..77c0234 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -19,6 +19,7 @@
import android.app.Activity;
import android.app.Application;
import android.net.Uri;
+import android.nfc.NfcAdapter.ReaderCallback;
import android.os.Binder;
import android.os.Bundle;
import android.os.RemoteException;
@@ -36,7 +37,7 @@
*
* @hide
*/
-public final class NfcActivityManager extends INdefPushCallback.Stub
+public final class NfcActivityManager extends IAppCallback.Stub
implements Application.ActivityLifecycleCallbacks {
static final String TAG = NfcAdapter.TAG;
static final Boolean DBG = false;
@@ -113,6 +114,8 @@
Uri[] uris = null;
int flags = 0;
int readerModeFlags = 0;
+ NfcAdapter.ReaderCallback readerCallback = null;
+ Bundle readerModeExtras = null;
Binder token;
public NfcActivityState(Activity activity) {
@@ -197,17 +200,20 @@
mDefaultEvent = new NfcEvent(mAdapter);
}
- public void enableReaderMode(Activity activity, int flags) {
+ public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+ Bundle extras) {
boolean isResumed;
Binder token;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
+ state.readerCallback = callback;
state.readerModeFlags = flags;
+ state.readerModeExtras = extras;
token = state.token;
isResumed = state.resumed;
}
if (isResumed) {
- setReaderMode(token, flags);
+ setReaderMode(token, flags, extras);
}
}
@@ -216,20 +222,22 @@
Binder token;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
+ state.readerCallback = null;
state.readerModeFlags = 0;
+ state.readerModeExtras = null;
token = state.token;
isResumed = state.resumed;
}
if (isResumed) {
- setReaderMode(token, 0);
+ setReaderMode(token, 0, null);
}
}
- public void setReaderMode(Binder token, int flags) {
+ public void setReaderMode(Binder token, int flags, Bundle extras) {
if (DBG) Log.d(TAG, "Setting reader mode");
try {
- NfcAdapter.sService.setReaderMode(token, flags);
+ NfcAdapter.sService.setReaderMode(token, this, flags, extras);
} catch (RemoteException e) {
mAdapter.attemptDeadServiceRecovery(e);
}
@@ -302,12 +310,12 @@
}
/**
- * Request or unrequest NFC service callbacks for NDEF push.
+ * Request or unrequest NFC service callbacks.
* Makes IPC call - do not hold lock.
*/
void requestNfcServiceCallback() {
try {
- NfcAdapter.sService.setNdefPushCallback(this);
+ NfcAdapter.sService.setAppCallback(this);
} catch (RemoteException e) {
mAdapter.attemptDeadServiceRecovery(e);
}
@@ -375,6 +383,22 @@
}
}
+ @Override
+ public void onTagDiscovered(Tag tag) throws RemoteException {
+ NfcAdapter.ReaderCallback callback;
+ synchronized (NfcActivityManager.this) {
+ NfcActivityState state = findResumedActivityState();
+ if (state == null) return;
+
+ callback = state.readerCallback;
+ }
+
+ // Make callback without lock
+ if (callback != null) {
+ callback.onTagDiscovered(tag);
+ }
+
+ }
/** Callback from Activity life-cycle, on main thread */
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
@@ -387,6 +411,7 @@
@Override
public void onActivityResumed(Activity activity) {
int readerModeFlags = 0;
+ Bundle readerModeExtras = null;
Binder token;
synchronized (NfcActivityManager.this) {
NfcActivityState state = findActivityState(activity);
@@ -395,9 +420,10 @@
state.resumed = true;
token = state.token;
readerModeFlags = state.readerModeFlags;
+ readerModeExtras = state.readerModeExtras;
}
if (readerModeFlags != 0) {
- setReaderMode(token, readerModeFlags);
+ setReaderMode(token, readerModeFlags, readerModeExtras);
}
requestNfcServiceCallback();
}
@@ -417,7 +443,7 @@
}
if (readerModeFlagsSet) {
// Restore default p2p modes
- setReaderMode(token, 0);
+ setReaderMode(token, 0, null);
}
}
@@ -441,4 +467,5 @@
}
}
}
+
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index fa0c1f6..2a18900 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -33,6 +33,7 @@
import android.nfc.tech.Ndef;
import android.nfc.tech.NfcA;
import android.nfc.tech.NfcF;
+import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -196,42 +197,42 @@
public static final int STATE_TURNING_OFF = 4;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag enables polling for Nfc-A technology.
*/
public static final int FLAG_READER_NFC_A = 0x1;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag enables polling for Nfc-B technology.
*/
public static final int FLAG_READER_NFC_B = 0x2;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag enables polling for Nfc-F technology.
*/
public static final int FLAG_READER_NFC_F = 0x4;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag enables polling for Nfc-V (ISO15693) technology.
*/
public static final int FLAG_READER_NFC_V = 0x8;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag enables polling for Kovio technology.
*/
public static final int FLAG_READER_KOVIO = 0x10;
/**
- * Flag for use with {@link #enableReaderMode(Activity, int)}.
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
* <p>
* Setting this flag allows the caller to prevent the
* platform from performing an NDEF check on the tags it
@@ -239,6 +240,23 @@
*/
public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80;
+ /**
+ * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+ * <p>
+ * Setting this flag allows the caller to prevent the
+ * platform from playing sounds when it discovers a tag.
+ */
+ public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100;
+
+ /**
+ * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}.
+ * <p>
+ * Setting this integer extra allows the calling application to specify
+ * the delay that the platform will use for performing presence checks
+ * on any discovered tag.
+ */
+ public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence";
+
/** @hide */
public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;
@@ -291,6 +309,14 @@
final Context mContext;
/**
+ * A callback to be invoked when the system has found a tag in
+ * reader mode.
+ */
+ public interface ReaderCallback {
+ public void onTagDiscovered(Tag tag);
+ }
+
+ /**
* A callback to be invoked when the system successfully delivers your {@link NdefMessage}
* to another device.
* @see #setOnNdefPushCompleteCallback
@@ -1167,19 +1193,18 @@
* {@link Ndef} tag technology from being enumerated on the tag, and that
* NDEF-based tag dispatch will not be functional.
*
- * <p>It is recommended to combine this method with
- * {@link #enableForegroundDispatch(Activity, PendingIntent, IntentFilter[], String[][])
- * to ensure that tags are delivered to this activity.
- *
* <p>For interacting with tags that are emulated on another Android device
* using Android's host-based card-emulation, the recommended flags are
* {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}.
*
* @param activity the Activity that requests the adapter to be in reader mode
+ * @param callback the callback to be called when a tag is discovered
* @param flags Flags indicating poll technologies and other optional parameters
+ * @param extras Additional extras for configuring reader mode.
*/
- public void enableReaderMode(Activity activity, int flags) {
- mNfcActivityManager.enableReaderMode(activity, flags);
+ public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
+ Bundle extras) {
+ mNfcActivityManager.enableReaderMode(activity, callback, flags, extras);
}
/**
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index b83911a..41c6603 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -105,8 +105,12 @@
if (onHost) {
parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA);
if (parser == null) {
- throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
- " meta-data");
+ Log.d(TAG, "Didn't find service meta-data, trying legacy.");
+ parser = si.loadXmlMetaData(pm, HostApduService.OLD_SERVICE_META_DATA);
+ if (parser == null) {
+ throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA +
+ " meta-data");
+ }
}
} else {
parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA);
@@ -170,12 +174,12 @@
com.android.internal.R.styleable.AidGroup_description);
String groupCategory = groupAttrs.getString(
com.android.internal.R.styleable.AidGroup_category);
- if (!CardEmulationManager.CATEGORY_PAYMENT.equals(groupCategory)) {
- groupCategory = CardEmulationManager.CATEGORY_OTHER;
+ if (!CardEmulation.CATEGORY_PAYMENT.equals(groupCategory)) {
+ groupCategory = CardEmulation.CATEGORY_OTHER;
}
currentGroup = mCategoryToGroup.get(groupCategory);
if (currentGroup != null) {
- if (!CardEmulationManager.CATEGORY_OTHER.equals(groupCategory)) {
+ if (!CardEmulation.CATEGORY_OTHER.equals(groupCategory)) {
Log.e(TAG, "Not allowing multiple aid-groups in the " +
groupCategory + " category");
currentGroup = null;
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
new file mode 100644
index 0000000..3cd7863
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.ActivityThread;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.nfc.INfcCardEmulation;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.List;
+
+public final class CardEmulation {
+ static final String TAG = "CardEmulation";
+
+ /**
+ * Activity action: ask the user to change the default
+ * card emulation service for a certain category. This will
+ * show a dialog that asks the user whether he wants to
+ * replace the current default service with the service
+ * identified with the ComponentName specified in
+ * {@link #EXTRA_SERVICE_COMPONENT}, for the category
+ * specified in {@link #EXTRA_CATEGORY}
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CHANGE_DEFAULT =
+ "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
+
+ /**
+ * The category extra for {@link #ACTION_CHANGE_DEFAULT}
+ *
+ * @see #ACTION_CHANGE_DEFAULT
+ */
+ public static final String EXTRA_CATEGORY = "category";
+
+ /**
+ * The ComponentName object passed in as a parcelable
+ * extra for {@link #ACTION_CHANGE_DEFAULT}
+ *
+ * @see #ACTION_CHANGE_DEFAULT
+ */
+ public static final String EXTRA_SERVICE_COMPONENT = "component";
+
+ /**
+ * The payment category can be used to indicate that an AID
+ * represents a payment application.
+ */
+ public static final String CATEGORY_PAYMENT = "payment";
+
+ /**
+ * If an AID group does not contain a category, or the
+ * specified category is not defined by the platform version
+ * that is parsing the AID group, all AIDs in the group will
+ * automatically be categorized under the {@link #CATEGORY_OTHER}
+ * category.
+ */
+ public static final String CATEGORY_OTHER = "other";
+
+ /**
+ * Return value for {@link #getSelectionModeForCategory(String)}.
+ *
+ * <p>In this mode, the user has set a default service for this
+ * AID category. If a remote reader selects any of the AIDs
+ * that the default service has registered in this category,
+ * that service will automatically be bound to to handle
+ * the transaction.
+ *
+ * <p>There are still cases where a service that is
+ * not the default for a category can selected:
+ * <p>
+ * If a remote reader selects an AID in this category
+ * that is not handled by the default service, and there is a set
+ * of other services {S} that do handle this AID, the
+ * user is asked if he wants to use any of the services in
+ * {S} instead.
+ * <p>
+ * As a special case, if the size of {S} is one, containing a single service X,
+ * and all AIDs X has registered in this category are not
+ * registered by any other service, then X will be
+ * selected automatically without asking the user.
+ * <p>Example:
+ * <ul>
+ * <li>Service A registers AIDs "1", "2" and "3" in the category
+ * <li>Service B registers AIDs "3" and "4" in the category
+ * <li>Service C registers AIDs "5" and "6" in the category
+ * </ul>
+ * In this case, the following will happen when service A
+ * is the default:
+ * <ul>
+ * <li>Reader selects AID "1", "2" or "3": service A is invoked automatically
+ * <li>Reader selects AID "4": the user is asked to confirm he
+ * wants to use service B, because its AIDs overlap with service A.
+ * <li>Reader selects AID "5" or "6": service C is invoked automatically,
+ * because all AIDs it has asked for are only registered by C,
+ * and there is no overlap.
+ * </ul>
+ *
+ */
+ public static final int SELECTION_MODE_PREFER_DEFAULT = 0;
+
+ /**
+ * Return value for {@link #getSelectionModeForCategory(String)}.
+ *
+ * <p>In this mode, whenever an AID of this category is selected,
+ * the user is asked which service he wants to use to handle
+ * the transaction, even if there is only one matching service.
+ */
+ public static final int SELECTION_MODE_ALWAYS_ASK = 1;
+
+ /**
+ * Return value for {@link #getSelectionModeForCategory(String)}.
+ *
+ * <p>In this mode, the user will only be asked to select a service
+ * if the selected AID has been registered by multiple applications.
+ */
+ public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2;
+
+ static boolean sIsInitialized = false;
+ static HashMap<Context, CardEmulation> sCardEmus = new HashMap();
+ static INfcCardEmulation sService;
+
+ final Context mContext;
+
+ private CardEmulation(Context context, INfcCardEmulation service) {
+ mContext = context.getApplicationContext();
+ sService = service;
+ }
+
+ public static synchronized CardEmulation getInstance(NfcAdapter adapter) {
+ if (adapter == null) throw new NullPointerException("NfcAdapter is null");
+ Context context = adapter.getContext();
+ if (context == null) {
+ Log.e(TAG, "NfcAdapter context is null.");
+ throw new UnsupportedOperationException();
+ }
+ if (!sIsInitialized) {
+ IPackageManager pm = ActivityThread.getPackageManager();
+ if (pm == null) {
+ Log.e(TAG, "Cannot get PackageManager");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+ Log.e(TAG, "This device does not support card emulation");
+ throw new UnsupportedOperationException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "PackageManager query failed.");
+ throw new UnsupportedOperationException();
+ }
+ sIsInitialized = true;
+ }
+ CardEmulation manager = sCardEmus.get(context);
+ if (manager == null) {
+ // Get card emu service
+ INfcCardEmulation service = adapter.getCardEmulationService();
+ manager = new CardEmulation(context, service);
+ sCardEmus.put(context, manager);
+ }
+ return manager;
+ }
+
+ /**
+ * Allows an application to query whether a service is currently
+ * the default service to handle a card emulation category.
+ *
+ * <p>Note that if {@link #getSelectionModeForCategory(String)}
+ * returns {@link #SELECTION_MODE_ALWAYS_ASK}, this method will always
+ * return false.
+ *
+ * @param service The ComponentName of the service
+ * @param category The category
+ * @return whether service is currently the default service for the category.
+ */
+ public boolean isDefaultServiceForCategory(ComponentName service, String category) {
+ try {
+ return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service, category);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.isDefaultServiceForCategory(UserHandle.myUserId(), service,
+ category);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ *
+ * Allows an application to query whether a service is currently
+ * the default handler for a specified ISO7816-4 Application ID.
+ *
+ * @param service The ComponentName of the service
+ * @param aid The ISO7816-4 Application ID
+ * @return
+ */
+ public boolean isDefaultServiceForAid(ComponentName service, String aid) {
+ try {
+ return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.isDefaultServiceForAid(UserHandle.myUserId(), service, aid);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Returns the application selection mode for the passed in category.
+ * Valid return values are:
+ * <p>{@link #SELECTION_MODE_PREFER_DEFAULT} the user has requested a default
+ * application for this category, which will be preferred.
+ * <p>{@link #SELECTION_MODE_ALWAYS_ASK} the user has requested to be asked
+ * every time what app he would like to use in this category.
+ * <p>{@link #SELECTION_MODE_ASK_IF_CONFLICT} the user will only be asked
+ * to pick a service if there is a conflict.
+ * @param category The category, for example {@link #CATEGORY_PAYMENT}
+ * @return
+ */
+ public int getSelectionModeForCategory(String category) {
+ if (CATEGORY_PAYMENT.equals(category)) {
+ String defaultComponent = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
+ if (defaultComponent != null) {
+ return SELECTION_MODE_PREFER_DEFAULT;
+ } else {
+ return SELECTION_MODE_ALWAYS_ASK;
+ }
+ } else {
+ // All other categories are in "only ask if conflict" mode
+ return SELECTION_MODE_ASK_IF_CONFLICT;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean setDefaultServiceForCategory(ComponentName service, String category) {
+ try {
+ return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service, category);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.setDefaultServiceForCategory(UserHandle.myUserId(), service,
+ category);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean setDefaultForNextTap(ComponentName service) {
+ try {
+ return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.setDefaultForNextTap(UserHandle.myUserId(), service);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+ /**
+ * @hide
+ */
+ public List<ApduServiceInfo> getServices(String category) {
+ try {
+ return sService.getServices(UserHandle.myUserId(), category);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ return sService.getServices(UserHandle.myUserId(), category);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ void recoverService() {
+ NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
+ sService = adapter.getCardEmulationService();
+ }
+}
diff --git a/core/java/android/nfc/cardemulation/CardEmulationManager.java b/core/java/android/nfc/cardemulation/CardEmulationManager.java
index 9d60c73..124ea1c 100644
--- a/core/java/android/nfc/cardemulation/CardEmulationManager.java
+++ b/core/java/android/nfc/cardemulation/CardEmulationManager.java
@@ -33,6 +33,10 @@
import java.util.HashMap;
import java.util.List;
+/**
+ * TODO Remove when calling .apks are upgraded
+ * @hide
+ */
public final class CardEmulationManager {
static final String TAG = "CardEmulationManager";
diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java
index ae94b2f..174acc0 100644
--- a/core/java/android/nfc/cardemulation/HostApduService.java
+++ b/core/java/android/nfc/cardemulation/HostApduService.java
@@ -40,13 +40,31 @@
*/
@SdkConstant(SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE =
- "android.nfc.HostApduService";
+ "android.nfc.cardemulation.action.HOST_APDU_SERVICE";
/**
* The name of the meta-data element that contains
* more information about this service.
*/
- public static final String SERVICE_META_DATA = "android.nfc.HostApduService";
+ public static final String SERVICE_META_DATA =
+ "android.nfc.cardemulation.host_apdu_service";
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ * TODO Remove
+ * @hide
+ */
+ public static final String OLD_SERVICE_INTERFACE =
+ "android.nfc.HostApduService";
+
+ /**
+ * The name of the meta-data element that contains
+ * more information about this service.
+ *
+ * TODO Remove
+ * @hide
+ */
+ public static final String OLD_SERVICE_META_DATA = "android.nfc.HostApduService";
/**
* Reason for {@link #onDeactivated(int)}.
@@ -63,7 +81,7 @@
* currently active on the logical channel).
*
* <p>Note that this next AID may still be resolved to this
- * service, in which case {@link #processCommandApdu(byte[], int)}
+ * service, in which case {@link #processCommandApdu(byte[], Bundle)}
* will be called again.
*/
public static final int DEACTIVATION_DESELECTED = 1;
@@ -131,7 +149,7 @@
byte[] apdu = dataBundle.getByteArray(KEY_DATA);
if (apdu != null) {
- byte[] responseApdu = processCommandApdu(apdu, 0);
+ byte[] responseApdu = processCommandApdu(apdu, null);
if (responseApdu != null) {
if (mNfcService == null) {
Log.e(TAG, "Response not sent; service was deactivated.");
@@ -230,7 +248,7 @@
* transaction.
*
* <p>Note: this method may be called anywhere between
- * the first {@link #processCommandApdu(byte[], int)}
+ * the first {@link #processCommandApdu(byte[], Bundle)}
* call and a {@link #onDeactivated(int)} call.
*/
public final void notifyUnhandled() {
@@ -290,8 +308,11 @@
* @param flags
* @return a byte-array containing the response APDU, or null if no
* response APDU can be sent at this point.
+ * @hide
*/
- public abstract byte[] processCommandApdu(byte[] commandApdu, int flags);
+ public byte[] processCommandApdu(byte[] commandApdu, int flags) {
+ return null;
+ }
/**
* This method will be called in two possible scenarios:
diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java
index 79599db..15f63f9 100644
--- a/core/java/android/nfc/cardemulation/OffHostApduService.java
+++ b/core/java/android/nfc/cardemulation/OffHostApduService.java
@@ -42,13 +42,14 @@
*/
@SdkConstant(SdkConstantType.SERVICE_ACTION)
public static final String SERVICE_INTERFACE =
- "android.nfc.OffHostApduService";
+ "android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE";
/**
* The name of the meta-data element that contains
* more information about this service.
*/
- public static final String SERVICE_META_DATA = "android.nfc.OffHostApduService";
+ public static final String SERVICE_META_DATA =
+ "android.nfc.cardemulation.off_host_apdu_service";
/**
* The Android platform itself will not bind to this service,
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index b78bbc3..60ce132 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -645,11 +645,13 @@
}
/**
- * Determine whether method tracing is currently active.
+ * Determine whether method tracing is currently active and what type is
+ * active.
+ *
* @hide
*/
- public static boolean isMethodTracingActive() {
- return VMDebug.isMethodTracingActive();
+ public static int getMethodTracingMode() {
+ return VMDebug.getMethodTracingMode();
}
/**
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 83426ae..10b9765 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -357,7 +357,18 @@
* @param restrictionKey the string key representing the restriction
*/
public boolean hasUserRestriction(String restrictionKey) {
- return getUserRestrictions().getBoolean(restrictionKey, false);
+ return hasUserRestriction(restrictionKey, Process.myUserHandle());
+ }
+
+ /**
+ * @hide
+ * Returns whether the given user has been disallowed from performing certain actions
+ * or setting certain settings.
+ * @param restrictionKey the string key representing the restriction
+ * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+ */
+ public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+ return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
}
/**
diff --git a/core/java/android/printservice/PrinterDiscoverySession.java b/core/java/android/printservice/PrinterDiscoverySession.java
index 1f86ecc..6464cc1 100644
--- a/core/java/android/printservice/PrinterDiscoverySession.java
+++ b/core/java/android/printservice/PrinterDiscoverySession.java
@@ -80,7 +80,7 @@
public abstract class PrinterDiscoverySession {
private static final String LOG_TAG = "PrinterDiscoverySession";
- private static final int MAX_ITEMS_PER_CALLBACK = 100;
+ private static final int MAX_ITEMS_PER_CALLBACK = 50;
private static int sIdCounter = 0;
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index ebb7eb8..f445fd5 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -19,7 +19,6 @@
import static android.net.TrafficStats.KB_IN_BYTES;
import static libcore.io.OsConstants.SEEK_SET;
-import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -30,16 +29,13 @@
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
-import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Parcel;
+import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
-import android.os.Parcelable;
import android.util.Log;
-import com.android.internal.util.Preconditions;
import com.google.android.collect.Lists;
import libcore.io.ErrnoException;
@@ -62,9 +58,12 @@
public final class DocumentsContract {
private static final String TAG = "Documents";
- // content://com.example/docs/12/
- // content://com.example/docs/12/children/
- // content://com.example/docs/12/search/?query=pony
+ // content://com.example/root/
+ // content://com.example/root/sdcard/
+ // content://com.example/root/sdcard/recent/
+ // content://com.example/document/12/
+ // content://com.example/document/12/children/
+ // content://com.example/document/12/search/?query=pony
private DocumentsContract() {
}
@@ -75,207 +74,69 @@
/** {@hide} */
public static final String ACTION_MANAGE_DOCUMENTS = "android.provider.action.MANAGE_DOCUMENTS";
- /** {@hide} */
- public static final String
- ACTION_DOCUMENT_ROOT_CHANGED = "android.provider.action.DOCUMENT_ROOT_CHANGED";
-
/**
- * Constants for individual documents.
+ * Constants related to a document, including {@link Cursor} columns names
+ * and flags.
+ * <p>
+ * A document can be either an openable file (with a specific MIME type), or
+ * a directory containing additional documents (with the
+ * {@link #MIME_TYPE_DIR} MIME type).
+ * <p>
+ * All columns are <em>read-only</em> to client applications.
*/
- public final static class Documents {
- private Documents() {
+ public final static class Document {
+ private Document() {
}
/**
- * MIME type of a document which is a directory that may contain additional
- * documents.
- */
- public static final String MIME_TYPE_DIR = "vnd.android.doc/dir";
-
- /**
- * Flag indicating that a document is a directory that supports creation of
- * new files within it.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_CREATE = 1;
-
- /**
- * Flag indicating that a document is renamable.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_RENAME = 1 << 1;
-
- /**
- * Flag indicating that a document is deletable.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
-
- /**
- * Flag indicating that a document can be represented as a thumbnail.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 3;
-
- /**
- * Flag indicating that a document is a directory that supports search.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_SEARCH = 1 << 4;
-
- /**
- * Flag indicating that a document supports writing.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_SUPPORTS_WRITE = 1 << 5;
-
- /**
- * Flag indicating that a document is a directory that prefers its contents
- * be shown in a larger format grid. Usually suitable when a directory
- * contains mostly pictures.
- *
- * @see DocumentColumns#FLAGS
- */
- public static final int FLAG_PREFERS_GRID = 1 << 6;
- }
-
- /**
- * Extra boolean flag included in a directory {@link Cursor#getExtras()}
- * indicating that a document provider is still loading data. For example, a
- * provider has returned some results, but is still waiting on an
- * outstanding network request.
- *
- * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver,
- * boolean)
- */
- public static final String EXTRA_LOADING = "loading";
-
- /**
- * Extra string included in a directory {@link Cursor#getExtras()}
- * providing an informational message that should be shown to a user. For
- * example, a provider may wish to indicate that not all documents are
- * available.
- */
- public static final String EXTRA_INFO = "info";
-
- /**
- * Extra string included in a directory {@link Cursor#getExtras()} providing
- * an error message that should be shown to a user. For example, a provider
- * may wish to indicate that a network error occurred. The user may choose
- * to retry, resulting in a new query.
- */
- public static final String EXTRA_ERROR = "error";
-
- /** {@hide} */
- public static final String METHOD_GET_ROOTS = "android:getRoots";
- /** {@hide} */
- public static final String METHOD_CREATE_DOCUMENT = "android:createDocument";
- /** {@hide} */
- public static final String METHOD_RENAME_DOCUMENT = "android:renameDocument";
- /** {@hide} */
- public static final String METHOD_DELETE_DOCUMENT = "android:deleteDocument";
-
- /** {@hide} */
- public static final String EXTRA_AUTHORITY = "authority";
- /** {@hide} */
- public static final String EXTRA_PACKAGE_NAME = "packageName";
- /** {@hide} */
- public static final String EXTRA_URI = "uri";
- /** {@hide} */
- public static final String EXTRA_ROOTS = "roots";
- /** {@hide} */
- public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
-
- private static final String PATH_DOCS = "docs";
- private static final String PATH_CHILDREN = "children";
- private static final String PATH_SEARCH = "search";
-
- private static final String PARAM_QUERY = "query";
-
- /**
- * Build Uri representing the given {@link DocumentColumns#DOC_ID} in a
- * document provider.
- */
- public static Uri buildDocumentUri(String authority, String docId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
- .authority(authority).appendPath(PATH_DOCS).appendPath(docId).build();
- }
-
- /**
- * Build Uri representing the contents of the given directory in a document
- * provider. The given document must be {@link Documents#MIME_TYPE_DIR}.
- *
- * @hide
- */
- public static Uri buildChildrenUri(String authority, String docId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
- .appendPath(PATH_DOCS).appendPath(docId).appendPath(PATH_CHILDREN).build();
- }
-
- /**
- * Build Uri representing a search for matching documents under a specific
- * directory in a document provider. The given document must have
- * {@link Documents#FLAG_SUPPORTS_SEARCH}.
- *
- * @hide
- */
- public static Uri buildSearchUri(String authority, String docId, String query) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
- .appendPath(PATH_DOCS).appendPath(docId).appendPath(PATH_SEARCH)
- .appendQueryParameter(PARAM_QUERY, query).build();
- }
-
- /**
- * Extract the {@link DocumentColumns#DOC_ID} from the given Uri.
- */
- public static String getDocId(Uri documentUri) {
- final List<String> paths = documentUri.getPathSegments();
- if (paths.size() < 2) {
- throw new IllegalArgumentException("Not a document: " + documentUri);
- }
- if (!PATH_DOCS.equals(paths.get(0))) {
- throw new IllegalArgumentException("Not a document: " + documentUri);
- }
- return paths.get(1);
- }
-
- /** {@hide} */
- public static String getSearchQuery(Uri documentUri) {
- return documentUri.getQueryParameter(PARAM_QUERY);
- }
-
- /**
- * Standard columns for document queries. Document providers <em>must</em>
- * support at least these columns when queried.
- */
- public interface DocumentColumns extends OpenableColumns {
- /**
- * Unique ID for a document. Values <em>must</em> never change once
- * returned, since they may used for long-term Uri permission grants.
+ * Unique ID of a document. This ID is both provided by and interpreted
+ * by a {@link DocumentsProvider}, and should be treated as an opaque
+ * value by client applications.
+ * <p>
+ * Each document must have a unique ID within a provider, but that
+ * single document may be included as a child of multiple directories.
+ * <p>
+ * A provider must always return durable IDs, since they will be used to
+ * issue long-term Uri permission grants when an application interacts
+ * with {@link Intent#ACTION_OPEN_DOCUMENT} and
+ * {@link Intent#ACTION_CREATE_DOCUMENT}.
* <p>
* Type: STRING
*/
- public static final String DOC_ID = "doc_id";
+ public static final String COLUMN_DOCUMENT_ID = "document_id";
/**
- * MIME type of a document.
+ * Concrete MIME type of a document. For example, "image/png" or
+ * "application/pdf" for openable files. A document can also be a
+ * directory containing additional documents, which is represented with
+ * the {@link #MIME_TYPE_DIR} MIME type.
* <p>
* Type: STRING
*
- * @see Documents#MIME_TYPE_DIR
+ * @see #MIME_TYPE_DIR
*/
- public static final String MIME_TYPE = "mime_type";
+ public static final String COLUMN_MIME_TYPE = "mime_type";
+
+ /**
+ * Display name of a document, used as the primary title displayed to a
+ * user.
+ * <p>
+ * Type: STRING
+ */
+ public static final String COLUMN_DISPLAY_NAME = OpenableColumns.DISPLAY_NAME;
+
+ /**
+ * Summary of a document, which may be shown to a user. The summary may
+ * be {@code null}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String COLUMN_SUMMARY = "summary";
/**
* Timestamp when a document was last modified, in milliseconds since
- * January 1, 1970 00:00:00.0 UTC, or {@code null} if unknown. Document
- * providers can update this field using events from
+ * January 1, 1970 00:00:00.0 UTC, or {@code null} if unknown. A
+ * {@link DocumentsProvider} can update this field using events from
* {@link OnCloseListener} or other reliable
* {@link ParcelFileDescriptor} transports.
* <p>
@@ -283,71 +144,227 @@
*
* @see System#currentTimeMillis()
*/
- public static final String LAST_MODIFIED = "last_modified";
+ public static final String COLUMN_LAST_MODIFIED = "last_modified";
/**
- * Specific icon resource for a document, or {@code null} to resolve
- * default using {@link #MIME_TYPE}.
+ * Specific icon resource ID for a document, or {@code null} to use
+ * platform default icon based on {@link #COLUMN_MIME_TYPE}.
* <p>
* Type: INTEGER (int)
*/
- public static final String ICON = "icon";
+ public static final String COLUMN_ICON = "icon";
/**
- * Summary for a document, or {@code null} to omit.
- * <p>
- * Type: STRING
- */
- public static final String SUMMARY = "summary";
-
- /**
- * Flags that apply to a specific document.
+ * Flags that apply to a document.
* <p>
* Type: INTEGER (int)
+ *
+ * @see #FLAG_SUPPORTS_WRITE
+ * @see #FLAG_SUPPORTS_DELETE
+ * @see #FLAG_SUPPORTS_THUMBNAIL
+ * @see #FLAG_DIR_PREFERS_GRID
+ * @see #FLAG_DIR_SUPPORTS_CREATE
+ * @see #FLAG_DIR_SUPPORTS_SEARCH
*/
- public static final String FLAGS = "flags";
+ public static final String COLUMN_FLAGS = "flags";
+
+ /**
+ * Size of a document, in bytes, or {@code null} if unknown.
+ * <p>
+ * Type: INTEGER (long)
+ */
+ public static final String COLUMN_SIZE = OpenableColumns.SIZE;
+
+ /**
+ * MIME type of a document which is a directory that may contain
+ * additional documents.
+ *
+ * @see #COLUMN_MIME_TYPE
+ */
+ public static final String MIME_TYPE_DIR = "vnd.android.document/directory";
+
+ /**
+ * Flag indicating that a document can be represented as a thumbnail.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#getDocumentThumbnail(ContentResolver, Uri,
+ * Point, CancellationSignal)
+ * @see DocumentsProvider#openDocumentThumbnail(String, Point,
+ * android.os.CancellationSignal)
+ */
+ public static final int FLAG_SUPPORTS_THUMBNAIL = 1;
+
+ /**
+ * Flag indicating that a document supports writing.
+ * <p>
+ * When a document is opened with {@link Intent#ACTION_OPEN_DOCUMENT},
+ * the calling application is granted both
+ * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION} and
+ * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}. However, the actual
+ * writability of a document may change over time, for example due to
+ * remote access changes. This flag indicates that a document client can
+ * expect {@link ContentResolver#openOutputStream(Uri)} to succeed.
+ *
+ * @see #COLUMN_FLAGS
+ */
+ public static final int FLAG_SUPPORTS_WRITE = 1 << 1;
+
+ /**
+ * Flag indicating that a document is deletable.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
+ * @see DocumentsProvider#deleteDocument(String)
+ */
+ public static final int FLAG_SUPPORTS_DELETE = 1 << 2;
+
+ /**
+ * Flag indicating that a document is a directory that supports creation
+ * of new files within it. Only valid when {@link #COLUMN_MIME_TYPE} is
+ * {@link #MIME_TYPE_DIR}.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#createDocument(ContentResolver, Uri, String,
+ * String)
+ * @see DocumentsProvider#createDocument(String, String, String)
+ */
+ public static final int FLAG_DIR_SUPPORTS_CREATE = 1 << 3;
+
+ /**
+ * Flag indicating that a directory supports search. Only valid when
+ * {@link #COLUMN_MIME_TYPE} is {@link #MIME_TYPE_DIR}.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsProvider#querySearchDocuments(String, String,
+ * String[])
+ */
+ public static final int FLAG_DIR_SUPPORTS_SEARCH = 1 << 4;
+
+ /**
+ * Flag indicating that a directory prefers its contents be shown in a
+ * larger format grid. Usually suitable when a directory contains mostly
+ * pictures. Only valid when {@link #COLUMN_MIME_TYPE} is
+ * {@link #MIME_TYPE_DIR}.
+ *
+ * @see #COLUMN_FLAGS
+ */
+ public static final int FLAG_DIR_PREFERS_GRID = 1 << 5;
}
/**
- * Metadata about a specific root of documents.
+ * Constants related to a root of documents, including {@link Cursor}
+ * columns names and flags.
+ * <p>
+ * All columns are <em>read-only</em> to client applications.
*/
- public final static class DocumentRoot implements Parcelable {
+ public final static class Root {
+ private Root() {
+ }
+
/**
- * Root that represents a storage service, such as a cloud-based
+ * Unique ID of a root. This ID is both provided by and interpreted by a
+ * {@link DocumentsProvider}, and should be treated as an opaque value
+ * by client applications.
+ * <p>
+ * Type: STRING
+ */
+ public static final String COLUMN_ROOT_ID = "root_id";
+
+ /**
+ * Type of a root, used for clustering when presenting multiple roots to
+ * a user.
+ * <p>
+ * Type: INTEGER (int)
+ *
+ * @see #ROOT_TYPE_SERVICE
+ * @see #ROOT_TYPE_SHORTCUT
+ * @see #ROOT_TYPE_DEVICE
+ */
+ public static final String COLUMN_ROOT_TYPE = "root_type";
+
+ /**
+ * Flags that apply to a root.
+ * <p>
+ * Type: INTEGER (int)
+ *
+ * @see #FLAG_LOCAL_ONLY
+ * @see #FLAG_SUPPORTS_CREATE
+ * @see #FLAG_ADVANCED
+ * @see #FLAG_PROVIDES_AUDIO
+ * @see #FLAG_PROVIDES_IMAGES
+ * @see #FLAG_PROVIDES_VIDEO
+ */
+ public static final String COLUMN_FLAGS = "flags";
+
+ /**
+ * Icon resource ID for a root.
+ * <p>
+ * Type: INTEGER (int)
+ */
+ public static final String COLUMN_ICON = "icon";
+
+ /**
+ * Title for a root, which will be shown to a user.
+ * <p>
+ * Type: STRING
+ */
+ public static final String COLUMN_TITLE = "title";
+
+ /**
+ * Summary for this root, which may be shown to a user. The summary may
+ * be {@code null}.
+ * <p>
+ * Type: STRING
+ */
+ public static final String COLUMN_SUMMARY = "summary";
+
+ /**
+ * Document which is a directory that represents the top directory of
+ * this root.
+ * <p>
+ * Type: STRING
+ *
+ * @see Document#COLUMN_DOCUMENT_ID
+ */
+ public static final String COLUMN_DOCUMENT_ID = "document_id";
+
+ /**
+ * Number of bytes available in this root, or {@code null} if unknown or
+ * unbounded.
+ * <p>
+ * Type: INTEGER (long)
+ */
+ public static final String COLUMN_AVAILABLE_BYTES = "available_bytes";
+
+ /**
+ * Type of root that represents a storage service, such as a cloud-based
* service.
*
- * @see #rootType
+ * @see #COLUMN_ROOT_TYPE
*/
public static final int ROOT_TYPE_SERVICE = 1;
/**
- * Root that represents a shortcut to content that may be available
- * elsewhere through another storage root.
+ * Type of root that represents a shortcut to content that may be
+ * available elsewhere through another storage root.
*
- * @see #rootType
+ * @see #COLUMN_ROOT_TYPE
*/
public static final int ROOT_TYPE_SHORTCUT = 2;
/**
- * Root that represents a physical storage device.
+ * Type of root that represents a physical storage device.
*
- * @see #rootType
+ * @see #COLUMN_ROOT_TYPE
*/
public static final int ROOT_TYPE_DEVICE = 3;
/**
- * Root that represents a physical storage device that should only be
- * displayed to advanced users.
- *
- * @see #rootType
- */
- public static final int ROOT_TYPE_DEVICE_ADVANCED = 4;
-
- /**
* Flag indicating that at least one directory under this root supports
- * creating content.
+ * creating content. Roots with this flag will be shown when an
+ * application interacts with {@link Intent#ACTION_CREATE_DOCUMENT}.
*
- * @see #flags
+ * @see #COLUMN_FLAGS
*/
public static final int FLAG_SUPPORTS_CREATE = 1;
@@ -355,138 +372,210 @@
* Flag indicating that this root offers content that is strictly local
* on the device. That is, no network requests are made for the content.
*
- * @see #flags
+ * @see #COLUMN_FLAGS
+ * @see Intent#EXTRA_LOCAL_ONLY
*/
public static final int FLAG_LOCAL_ONLY = 1 << 1;
- /** {@hide} */
- public String authority;
-
/**
- * Root type, use for clustering.
+ * Flag indicating that this root should only be visible to advanced
+ * users.
*
- * @see #ROOT_TYPE_SERVICE
- * @see #ROOT_TYPE_DEVICE
+ * @see #COLUMN_FLAGS
*/
- public int rootType;
+ public static final int FLAG_ADVANCED = 1 << 2;
/**
- * Flags for this root.
+ * Flag indicating that a root offers audio documents. When a user is
+ * selecting audio, roots not providing audio may be excluded.
*
- * @see #FLAG_LOCAL_ONLY
+ * @see #COLUMN_FLAGS
+ * @see Intent#EXTRA_MIME_TYPES
*/
- public int flags;
+ public static final int FLAG_PROVIDES_AUDIO = 1 << 3;
/**
- * Icon resource ID for this root.
- */
- public int icon;
-
- /**
- * Title for this root.
- */
- public String title;
-
- /**
- * Summary for this root. May be {@code null}.
- */
- public String summary;
-
- /**
- * Document which is a directory that represents the top of this root.
- * Must not be {@code null}.
+ * Flag indicating that a root offers video documents. When a user is
+ * selecting video, roots not providing video may be excluded.
*
- * @see DocumentColumns#DOC_ID
+ * @see #COLUMN_FLAGS
+ * @see Intent#EXTRA_MIME_TYPES
*/
- public String docId;
+ public static final int FLAG_PROVIDES_VIDEO = 1 << 4;
/**
- * Document which is a directory representing recently modified
- * documents under this root. This directory should return at most two
- * dozen documents modified within the last 90 days. May be {@code null}
- * if this root doesn't support recents.
+ * Flag indicating that a root offers image documents. When a user is
+ * selecting images, roots not providing images may be excluded.
*
- * @see DocumentColumns#DOC_ID
+ * @see #COLUMN_FLAGS
+ * @see Intent#EXTRA_MIME_TYPES
*/
- public String recentDocId;
+ public static final int FLAG_PROVIDES_IMAGES = 1 << 5;
/**
- * Number of free bytes of available in this root, or -1 if unknown or
- * unbounded.
+ * Flag indicating that this root can report recently modified
+ * documents.
+ *
+ * @see #COLUMN_FLAGS
+ * @see DocumentsContract#buildRecentDocumentsUri(String, String)
*/
- public long availableBytes;
+ public static final int FLAG_SUPPORTS_RECENTS = 1 << 6;
+ }
- /**
- * Set of MIME type filters describing the content offered by this root,
- * or {@code null} to indicate that all MIME types are supported. For
- * example, a provider only supporting audio and video might set this to
- * {@code ["audio/*", "video/*"]}.
- */
- public String[] mimeTypes;
+ /**
+ * Optional boolean flag included in a directory {@link Cursor#getExtras()}
+ * indicating that a document provider is still loading data. For example, a
+ * provider has returned some results, but is still waiting on an
+ * outstanding network request. The provider must send a content changed
+ * notification when loading is finished.
+ *
+ * @see ContentResolver#notifyChange(Uri, android.database.ContentObserver,
+ * boolean)
+ */
+ public static final String EXTRA_LOADING = "loading";
- public DocumentRoot() {
+ /**
+ * Optional string included in a directory {@link Cursor#getExtras()}
+ * providing an informational message that should be shown to a user. For
+ * example, a provider may wish to indicate that not all documents are
+ * available.
+ */
+ public static final String EXTRA_INFO = "info";
+
+ /**
+ * Optional string included in a directory {@link Cursor#getExtras()}
+ * providing an error message that should be shown to a user. For example, a
+ * provider may wish to indicate that a network error occurred. The user may
+ * choose to retry, resulting in a new query.
+ */
+ public static final String EXTRA_ERROR = "error";
+
+ /** {@hide} */
+ public static final String METHOD_CREATE_DOCUMENT = "android:createDocument";
+ /** {@hide} */
+ public static final String METHOD_DELETE_DOCUMENT = "android:deleteDocument";
+
+ /** {@hide} */
+ public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size";
+
+ private static final String PATH_ROOT = "root";
+ private static final String PATH_RECENT = "recent";
+ private static final String PATH_DOCUMENT = "document";
+ private static final String PATH_CHILDREN = "children";
+ private static final String PATH_SEARCH = "search";
+
+ private static final String PARAM_QUERY = "query";
+
+ /**
+ * Build Uri representing the roots of a document provider. When queried, a
+ * provider will return one or more rows with columns defined by
+ * {@link Root}.
+ *
+ * @see DocumentsProvider#queryRoots(String[])
+ */
+ public static Uri buildRootsUri(String authority) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_ROOT).build();
+ }
+
+ /**
+ * Build Uri representing the recently modified documents of a specific
+ * root. When queried, a provider will return zero or more rows with columns
+ * defined by {@link Document}.
+ *
+ * @see DocumentsProvider#queryRecentDocuments(String, String[])
+ * @see #getRootId(Uri)
+ */
+ public static Uri buildRecentDocumentsUri(String authority, String rootId) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_ROOT).appendPath(rootId)
+ .appendPath(PATH_RECENT).build();
+ }
+
+ /**
+ * Build Uri representing the given {@link Document#COLUMN_DOCUMENT_ID} in a
+ * document provider. When queried, a provider will return a single row with
+ * columns defined by {@link Document}.
+ *
+ * @see DocumentsProvider#queryDocument(String, String[])
+ * @see #getDocumentId(Uri)
+ */
+ public static Uri buildDocumentUri(String authority, String documentId) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_DOCUMENT).appendPath(documentId).build();
+ }
+
+ /**
+ * Build Uri representing the children of the given directory in a document
+ * provider. When queried, a provider will return zero or more rows with
+ * columns defined by {@link Document}.
+ *
+ * @param parentDocumentId the document to return children for, which must
+ * be a directory with MIME type of
+ * {@link Document#MIME_TYPE_DIR}.
+ * @see DocumentsProvider#queryChildDocuments(String, String[], String)
+ * @see #getDocumentId(Uri)
+ */
+ public static Uri buildChildDocumentsUri(String authority, String parentDocumentId) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+ .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_CHILDREN)
+ .build();
+ }
+
+ /**
+ * Build Uri representing a search for matching documents under a specific
+ * directory in a document provider. When queried, a provider will return
+ * zero or more rows with columns defined by {@link Document}.
+ *
+ * @param parentDocumentId the document to return children for, which must
+ * be both a directory with MIME type of
+ * {@link Document#MIME_TYPE_DIR} and have
+ * {@link Document#FLAG_DIR_SUPPORTS_SEARCH} set.
+ * @see DocumentsProvider#querySearchDocuments(String, String, String[])
+ * @see #getDocumentId(Uri)
+ * @see #getSearchDocumentsQuery(Uri)
+ */
+ public static Uri buildSearchDocumentsUri(
+ String authority, String parentDocumentId, String query) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority)
+ .appendPath(PATH_DOCUMENT).appendPath(parentDocumentId).appendPath(PATH_SEARCH)
+ .appendQueryParameter(PARAM_QUERY, query).build();
+ }
+
+ /**
+ * Extract the {@link Root#COLUMN_ROOT_ID} from the given Uri.
+ */
+ public static String getRootId(Uri rootUri) {
+ final List<String> paths = rootUri.getPathSegments();
+ if (paths.size() < 2) {
+ throw new IllegalArgumentException("Not a root: " + rootUri);
}
-
- /** {@hide} */
- public DocumentRoot(Parcel in) {
- rootType = in.readInt();
- flags = in.readInt();
- icon = in.readInt();
- title = in.readString();
- summary = in.readString();
- docId = in.readString();
- recentDocId = in.readString();
- availableBytes = in.readLong();
- mimeTypes = in.readStringArray();
+ if (!PATH_ROOT.equals(paths.get(0))) {
+ throw new IllegalArgumentException("Not a root: " + rootUri);
}
+ return paths.get(1);
+ }
- /** {@hide} */
- public Drawable loadIcon(Context context) {
- if (icon != 0) {
- if (authority != null) {
- final PackageManager pm = context.getPackageManager();
- final ProviderInfo info = pm.resolveContentProvider(authority, 0);
- if (info != null) {
- return pm.getDrawable(info.packageName, icon, info.applicationInfo);
- }
- } else {
- return context.getResources().getDrawable(icon);
- }
- }
- return null;
+ /**
+ * Extract the {@link Document#COLUMN_DOCUMENT_ID} from the given Uri.
+ */
+ public static String getDocumentId(Uri documentUri) {
+ final List<String> paths = documentUri.getPathSegments();
+ if (paths.size() < 2) {
+ throw new IllegalArgumentException("Not a document: " + documentUri);
}
-
- @Override
- public int describeContents() {
- return 0;
+ if (!PATH_DOCUMENT.equals(paths.get(0))) {
+ throw new IllegalArgumentException("Not a document: " + documentUri);
}
+ return paths.get(1);
+ }
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- Preconditions.checkNotNull(docId);
-
- dest.writeInt(rootType);
- dest.writeInt(flags);
- dest.writeInt(icon);
- dest.writeString(title);
- dest.writeString(summary);
- dest.writeString(docId);
- dest.writeString(recentDocId);
- dest.writeLong(availableBytes);
- dest.writeStringArray(mimeTypes);
- }
-
- public static final Creator<DocumentRoot> CREATOR = new Creator<DocumentRoot>() {
- @Override
- public DocumentRoot createFromParcel(Parcel in) {
- return new DocumentRoot(in);
- }
-
- @Override
- public DocumentRoot[] newArray(int size) {
- return new DocumentRoot[size];
- }
- };
+ /**
+ * Extract the search query from a Uri built by
+ * {@link #buildSearchDocumentsUri(String, String, String)}.
+ */
+ public static String getSearchDocumentsQuery(Uri searchDocumentsUri) {
+ return searchDocumentsUri.getQueryParameter(PARAM_QUERY);
}
/**
@@ -497,6 +586,7 @@
* {@link Intent#ACTION_CREATE_DOCUMENT}.
*
* @see Context#grantUriPermission(String, Uri, int)
+ * @see Context#revokeUriPermission(Uri, int)
* @see ContentResolver#getIncomingUriPermissionGrants(int, int)
*/
public static Uri[] getOpenDocuments(Context context) {
@@ -520,20 +610,28 @@
}
/**
- * Return thumbnail representing the document at the given URI. Callers are
- * responsible for their own in-memory caching. Given document must have
- * {@link Documents#FLAG_SUPPORTS_THUMBNAIL} set.
+ * Return thumbnail representing the document at the given Uri. Callers are
+ * responsible for their own in-memory caching.
*
+ * @param documentUri document to return thumbnail for, which must have
+ * {@link Document#FLAG_SUPPORTS_THUMBNAIL} set.
+ * @param size optimal thumbnail size desired. A provider may return a
+ * thumbnail of a different size, but never more than double the
+ * requested size.
+ * @param signal signal used to indicate that caller is no longer interested
+ * in the thumbnail.
* @return decoded thumbnail, or {@code null} if problem was encountered.
- * @hide
+ * @see DocumentsProvider#openDocumentThumbnail(String, Point,
+ * android.os.CancellationSignal)
*/
- public static Bitmap getThumbnail(ContentResolver resolver, Uri documentUri, Point size) {
+ public static Bitmap getDocumentThumbnail(
+ ContentResolver resolver, Uri documentUri, Point size, CancellationSignal signal) {
final Bundle openOpts = new Bundle();
openOpts.putParcelable(DocumentsContract.EXTRA_THUMBNAIL_SIZE, size);
AssetFileDescriptor afd = null;
try {
- afd = resolver.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts);
+ afd = resolver.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);
final FileDescriptor fd = afd.getFileDescriptor();
final long offset = afd.getStartOffset();
@@ -583,38 +681,26 @@
}
}
- /** {@hide} */
- public static List<DocumentRoot> getDocumentRoots(ContentProviderClient client) {
- try {
- final Bundle out = client.call(METHOD_GET_ROOTS, null, null);
- final List<DocumentRoot> roots = out.getParcelableArrayList(EXTRA_ROOTS);
- return roots;
- } catch (Exception e) {
- Log.w(TAG, "Failed to get roots", e);
- return null;
- }
- }
-
/**
- * Create a new document under the given parent document with MIME type and
- * display name.
+ * Create a new document with given MIME type and display name.
*
- * @param docId document with {@link Documents#FLAG_SUPPORTS_CREATE}
+ * @param parentDocumentUri directory with
+ * {@link Document#FLAG_DIR_SUPPORTS_CREATE}
* @param mimeType MIME type of new document
* @param displayName name of new document
* @return newly created document, or {@code null} if failed
- * @hide
*/
- public static String createDocument(
- ContentProviderClient client, String docId, String mimeType, String displayName) {
+ public static Uri createDocument(ContentResolver resolver, Uri parentDocumentUri,
+ String mimeType, String displayName) {
final Bundle in = new Bundle();
- in.putString(DocumentColumns.DOC_ID, docId);
- in.putString(DocumentColumns.MIME_TYPE, mimeType);
- in.putString(DocumentColumns.DISPLAY_NAME, displayName);
+ in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(parentDocumentUri));
+ in.putString(Document.COLUMN_MIME_TYPE, mimeType);
+ in.putString(Document.COLUMN_DISPLAY_NAME, displayName);
try {
- final Bundle out = client.call(METHOD_CREATE_DOCUMENT, null, in);
- return out.getString(DocumentColumns.DOC_ID);
+ final Bundle out = resolver.call(parentDocumentUri, METHOD_CREATE_DOCUMENT, null, in);
+ return buildDocumentUri(
+ parentDocumentUri.getAuthority(), out.getString(Document.COLUMN_DOCUMENT_ID));
} catch (Exception e) {
Log.w(TAG, "Failed to create document", e);
return null;
@@ -622,40 +708,16 @@
}
/**
- * Rename the given document.
- *
- * @param docId document with {@link Documents#FLAG_SUPPORTS_RENAME}
- * @return document which may have changed due to rename, or {@code null} if
- * rename failed.
- * @hide
- */
- public static String renameDocument(
- ContentProviderClient client, String docId, String displayName) {
- final Bundle in = new Bundle();
- in.putString(DocumentColumns.DOC_ID, docId);
- in.putString(DocumentColumns.DISPLAY_NAME, displayName);
-
- try {
- final Bundle out = client.call(METHOD_RENAME_DOCUMENT, null, in);
- return out.getString(DocumentColumns.DOC_ID);
- } catch (Exception e) {
- Log.w(TAG, "Failed to rename document", e);
- return null;
- }
- }
-
- /**
* Delete the given document.
*
- * @param docId document with {@link Documents#FLAG_SUPPORTS_DELETE}
- * @hide
+ * @param documentUri document with {@link Document#FLAG_SUPPORTS_DELETE}
*/
- public static boolean deleteDocument(ContentProviderClient client, String docId) {
+ public static boolean deleteDocument(ContentResolver resolver, Uri documentUri) {
final Bundle in = new Bundle();
- in.putString(DocumentColumns.DOC_ID, docId);
+ in.putString(Document.COLUMN_DOCUMENT_ID, getDocumentId(documentUri));
try {
- client.call(METHOD_DELETE_DOCUMENT, null, in);
+ final Bundle out = resolver.call(documentUri, METHOD_DELETE_DOCUMENT, null, in);
return true;
} catch (Exception e) {
Log.w(TAG, "Failed to delete document", e);
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index eeb8c41..09f4866 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -16,16 +16,12 @@
package android.provider;
-import static android.provider.DocumentsContract.ACTION_DOCUMENT_ROOT_CHANGED;
-import static android.provider.DocumentsContract.EXTRA_AUTHORITY;
-import static android.provider.DocumentsContract.EXTRA_ROOTS;
import static android.provider.DocumentsContract.EXTRA_THUMBNAIL_SIZE;
import static android.provider.DocumentsContract.METHOD_CREATE_DOCUMENT;
import static android.provider.DocumentsContract.METHOD_DELETE_DOCUMENT;
-import static android.provider.DocumentsContract.METHOD_GET_ROOTS;
-import static android.provider.DocumentsContract.METHOD_RENAME_DOCUMENT;
-import static android.provider.DocumentsContract.getDocId;
-import static android.provider.DocumentsContract.getSearchQuery;
+import static android.provider.DocumentsContract.getDocumentId;
+import static android.provider.DocumentsContract.getRootId;
+import static android.provider.DocumentsContract.getSearchDocumentsQuery;
import android.content.ContentProvider;
import android.content.ContentValues;
@@ -41,15 +37,12 @@
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.os.ParcelFileDescriptor.OnCloseListener;
-import android.provider.DocumentsContract.DocumentColumns;
-import android.provider.DocumentsContract.DocumentRoot;
-import android.provider.DocumentsContract.Documents;
+import android.provider.DocumentsContract.Document;
import android.util.Log;
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
-import java.util.List;
/**
* Base class for a document provider. A document provider should extend this
@@ -58,13 +51,13 @@
* Each document provider expresses one or more "roots" which each serve as the
* top-level of a tree. For example, a root could represent an account, or a
* physical storage device. Under each root, documents are referenced by
- * {@link DocumentColumns#DOC_ID}, which must not change once returned.
+ * {@link Document#COLUMN_DOCUMENT_ID}, which must not change once returned.
* <p>
* Documents can be either an openable file (with a specific MIME type), or a
* directory containing additional documents (with the
- * {@link Documents#MIME_TYPE_DIR} MIME type). Each document can have different
- * capabilities, as described by {@link DocumentColumns#FLAGS}. The same
- * {@link DocumentColumns#DOC_ID} can be included in multiple directories.
+ * {@link Document#MIME_TYPE_DIR} MIME type). Each document can have different
+ * capabilities, as described by {@link Document#COLUMN_FLAGS}. The same
+ * {@link Document#COLUMN_DOCUMENT_ID} can be included in multiple directories.
* <p>
* Document providers must be protected with the
* {@link android.Manifest.permission#MANAGE_DOCUMENTS} permission, which can
@@ -78,22 +71,29 @@
public abstract class DocumentsProvider extends ContentProvider {
private static final String TAG = "DocumentsProvider";
- private static final int MATCH_DOCUMENT = 1;
- private static final int MATCH_CHILDREN = 2;
- private static final int MATCH_SEARCH = 3;
+ private static final int MATCH_ROOT = 1;
+ private static final int MATCH_RECENT = 2;
+ private static final int MATCH_DOCUMENT = 3;
+ private static final int MATCH_CHILDREN = 4;
+ private static final int MATCH_SEARCH = 5;
private String mAuthority;
private UriMatcher mMatcher;
+ /**
+ * Implementation is provided by the parent class.
+ */
@Override
public void attachInfo(Context context, ProviderInfo info) {
mAuthority = info.authority;
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mMatcher.addURI(mAuthority, "docs/*", MATCH_DOCUMENT);
- mMatcher.addURI(mAuthority, "docs/*/children", MATCH_CHILDREN);
- mMatcher.addURI(mAuthority, "docs/*/search", MATCH_SEARCH);
+ mMatcher.addURI(mAuthority, "root", MATCH_ROOT);
+ mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
+ mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
+ mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
+ mMatcher.addURI(mAuthority, "document/*/search", MATCH_SEARCH);
// Sanity check our setup
if (!info.exported) {
@@ -111,83 +111,80 @@
}
/**
- * Return list of all document roots provided by this document provider.
- * When this list changes, a provider must call
- * {@link #notifyDocumentRootsChanged()}.
- */
- public abstract List<DocumentRoot> getDocumentRoots();
-
- /**
- * Create and return a new document. A provider must allocate a new
- * {@link DocumentColumns#DOC_ID} to represent the document, which must not
- * change once returned.
+ * Create a new document and return its {@link Document#COLUMN_DOCUMENT_ID}.
+ * A provider must allocate a new {@link Document#COLUMN_DOCUMENT_ID} to
+ * represent the document, which must not change once returned.
*
- * @param docId the parent directory to create the new document under.
+ * @param documentId the parent directory to create the new document under.
* @param mimeType the MIME type associated with the new document.
* @param displayName the display name of the new document.
*/
@SuppressWarnings("unused")
- public String createDocument(String docId, String mimeType, String displayName)
+ public String createDocument(String documentId, String mimeType, String displayName)
throws FileNotFoundException {
throw new UnsupportedOperationException("Create not supported");
}
/**
- * Rename the given document.
+ * Delete the given document. Upon returning, any Uri permission grants for
+ * the given document will be revoked. If additional documents were deleted
+ * as a side effect of this call, such as documents inside a directory, the
+ * implementor is responsible for revoking those permissions.
*
- * @param docId the document to rename.
- * @param displayName the new display name.
+ * @param documentId the document to delete.
*/
@SuppressWarnings("unused")
- public void renameDocument(String docId, String displayName) throws FileNotFoundException {
- throw new UnsupportedOperationException("Rename not supported");
+ public void deleteDocument(String documentId) throws FileNotFoundException {
+ throw new UnsupportedOperationException("Delete not supported");
}
- /**
- * Delete the given document.
- *
- * @param docId the document to delete.
- */
+ public abstract Cursor queryRoots(String[] projection) throws FileNotFoundException;
+
@SuppressWarnings("unused")
- public void deleteDocument(String docId) throws FileNotFoundException {
- throw new UnsupportedOperationException("Delete not supported");
+ public Cursor queryRecentDocuments(String rootId, String[] projection)
+ throws FileNotFoundException {
+ throw new UnsupportedOperationException("Recent not supported");
}
/**
* Return metadata for the given document. A provider should avoid making
* network requests to keep this request fast.
*
- * @param docId the document to return.
+ * @param documentId the document to return.
*/
- public abstract Cursor queryDocument(String docId) throws FileNotFoundException;
+ public abstract Cursor queryDocument(String documentId, String[] projection)
+ throws FileNotFoundException;
/**
* Return the children of the given document which is a directory.
*
- * @param docId the directory to return children for.
+ * @param parentDocumentId the directory to return children for.
*/
- public abstract Cursor queryDocumentChildren(String docId) throws FileNotFoundException;
+ public abstract Cursor queryChildDocuments(
+ String parentDocumentId, String[] projection, String sortOrder)
+ throws FileNotFoundException;
/**
* Return documents that that match the given query, starting the search at
* the given directory.
*
- * @param docId the directory to start search at.
+ * @param parentDocumentId the directory to start search at.
*/
@SuppressWarnings("unused")
- public Cursor querySearch(String docId, String query) throws FileNotFoundException {
+ public Cursor querySearchDocuments(String parentDocumentId, String query, String[] projection)
+ throws FileNotFoundException {
throw new UnsupportedOperationException("Search not supported");
}
/**
* Return MIME type for the given document. Must match the value of
- * {@link DocumentColumns#MIME_TYPE} for this document.
+ * {@link Document#COLUMN_MIME_TYPE} for this document.
*/
- public String getType(String docId) throws FileNotFoundException {
- final Cursor cursor = queryDocument(docId);
+ public String getDocumentType(String documentId) throws FileNotFoundException {
+ final Cursor cursor = queryDocument(documentId, null);
try {
if (cursor.moveToFirst()) {
- return cursor.getString(cursor.getColumnIndexOrThrow(DocumentColumns.MIME_TYPE));
+ return cursor.getString(cursor.getColumnIndexOrThrow(Document.COLUMN_MIME_TYPE));
} else {
return null;
}
@@ -233,7 +230,7 @@
* @param sizeHint hint of the optimal thumbnail dimensions.
* @param signal used by the caller to signal if the request should be
* cancelled.
- * @see Documents#FLAG_SUPPORTS_THUMBNAIL
+ * @see Document#FLAG_SUPPORTS_THUMBNAIL
*/
@SuppressWarnings("unused")
public AssetFileDescriptor openDocumentThumbnail(
@@ -241,17 +238,31 @@
throw new UnsupportedOperationException("Thumbnails not supported");
}
+ /**
+ * Implementation is provided by the parent class. Cannot be overriden.
+ *
+ * @see #queryRoots(String[])
+ * @see #queryRecentDocuments(String, String[])
+ * @see #queryDocument(String, String[])
+ * @see #queryChildDocuments(String, String[], String)
+ * @see #querySearchDocuments(String, String, String[])
+ */
@Override
- public final Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
+ public final Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
try {
switch (mMatcher.match(uri)) {
+ case MATCH_ROOT:
+ return queryRoots(projection);
+ case MATCH_RECENT:
+ return queryRecentDocuments(getRootId(uri), projection);
case MATCH_DOCUMENT:
- return queryDocument(getDocId(uri));
+ return queryDocument(getDocumentId(uri), projection);
case MATCH_CHILDREN:
- return queryDocumentChildren(getDocId(uri));
+ return queryChildDocuments(getDocumentId(uri), projection, sortOrder);
case MATCH_SEARCH:
- return querySearch(getDocId(uri), getSearchQuery(uri));
+ return querySearchDocuments(
+ getDocumentId(uri), getSearchDocumentsQuery(uri), projection);
default:
throw new UnsupportedOperationException("Unsupported Uri " + uri);
}
@@ -261,12 +272,17 @@
}
}
+ /**
+ * Implementation is provided by the parent class. Cannot be overriden.
+ *
+ * @see #getDocumentType(String)
+ */
@Override
public final String getType(Uri uri) {
try {
switch (mMatcher.match(uri)) {
case MATCH_DOCUMENT:
- return getType(getDocId(uri));
+ return getDocumentType(getDocumentId(uri));
default:
return null;
}
@@ -276,22 +292,39 @@
}
}
+ /**
+ * Implementation is provided by the parent class. Throws by default, and
+ * cannot be overriden.
+ *
+ * @see #createDocument(String, String, String)
+ */
@Override
public final Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException("Insert not supported");
}
+ /**
+ * Implementation is provided by the parent class. Throws by default, and
+ * cannot be overriden.
+ *
+ * @see #deleteDocument(String)
+ */
@Override
public final int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("Delete not supported");
}
+ /**
+ * Implementation is provided by the parent class. Throws by default, and
+ * cannot be overriden.
+ */
@Override
public final int update(
Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("Update not supported");
}
+ /** {@hide} */
@Override
public final Bundle callFromPackage(
String callingPackage, String method, String arg, Bundle extras) {
@@ -300,33 +333,25 @@
return super.callFromPackage(callingPackage, method, arg, extras);
}
- // Platform operations require the caller explicitly hold manage
- // permission; Uri permissions don't extend management operations.
- getContext().enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_DOCUMENTS, "Document management");
+ // Require that caller can manage given document
+ final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
+ final Uri documentUri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
+ getContext().enforceCallingOrSelfUriPermission(
+ documentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, method);
final Bundle out = new Bundle();
try {
- if (METHOD_GET_ROOTS.equals(method)) {
- final List<DocumentRoot> roots = getDocumentRoots();
- out.putParcelableList(EXTRA_ROOTS, roots);
+ if (METHOD_CREATE_DOCUMENT.equals(method)) {
+ final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
+ final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
- } else if (METHOD_CREATE_DOCUMENT.equals(method)) {
- final String docId = extras.getString(DocumentColumns.DOC_ID);
- final String mimeType = extras.getString(DocumentColumns.MIME_TYPE);
- final String displayName = extras.getString(DocumentColumns.DISPLAY_NAME);
-
- // TODO: issue Uri grant towards caller
- final String newDocId = createDocument(docId, mimeType, displayName);
- out.putString(DocumentColumns.DOC_ID, newDocId);
-
- } else if (METHOD_RENAME_DOCUMENT.equals(method)) {
- final String docId = extras.getString(DocumentColumns.DOC_ID);
- final String displayName = extras.getString(DocumentColumns.DISPLAY_NAME);
- renameDocument(docId, displayName);
+ // TODO: issue Uri grant towards calling package
+ // TODO: enforce that package belongs to caller
+ final String newDocumentId = createDocument(documentId, mimeType, displayName);
+ out.putString(Document.COLUMN_DOCUMENT_ID, newDocumentId);
} else if (METHOD_DELETE_DOCUMENT.equals(method)) {
- final String docId = extras.getString(DocumentColumns.DOC_ID);
+ final String docId = extras.getString(Document.COLUMN_DOCUMENT_ID);
deleteDocument(docId);
} else {
@@ -338,47 +363,57 @@
return out;
}
+ /**
+ * Implementation is provided by the parent class.
+ *
+ * @see #openDocument(String, String, CancellationSignal)
+ */
@Override
public final ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- return openDocument(getDocId(uri), mode, null);
+ return openDocument(getDocumentId(uri), mode, null);
}
+ /**
+ * Implementation is provided by the parent class.
+ *
+ * @see #openDocument(String, String, CancellationSignal)
+ */
@Override
public final ParcelFileDescriptor openFile(Uri uri, String mode, CancellationSignal signal)
throws FileNotFoundException {
- return openDocument(getDocId(uri), mode, signal);
+ return openDocument(getDocumentId(uri), mode, signal);
}
+ /**
+ * Implementation is provided by the parent class.
+ *
+ * @see #openDocumentThumbnail(String, Point, CancellationSignal)
+ */
@Override
public final AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
throws FileNotFoundException {
if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
- return openDocumentThumbnail(getDocId(uri), sizeHint, null);
+ return openDocumentThumbnail(getDocumentId(uri), sizeHint, null);
} else {
return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
}
}
+ /**
+ * Implementation is provided by the parent class.
+ *
+ * @see #openDocumentThumbnail(String, Point, CancellationSignal)
+ */
@Override
public final AssetFileDescriptor openTypedAssetFile(
Uri uri, String mimeTypeFilter, Bundle opts, CancellationSignal signal)
throws FileNotFoundException {
if (opts != null && opts.containsKey(EXTRA_THUMBNAIL_SIZE)) {
final Point sizeHint = opts.getParcelable(EXTRA_THUMBNAIL_SIZE);
- return openDocumentThumbnail(getDocId(uri), sizeHint, signal);
+ return openDocumentThumbnail(getDocumentId(uri), sizeHint, signal);
} else {
return super.openTypedAssetFile(uri, mimeTypeFilter, opts, signal);
}
}
-
- /**
- * Notify system that {@link #getDocumentRoots()} has changed, usually due to an
- * account or device change.
- */
- public void notifyDocumentRootsChanged() {
- final Intent intent = new Intent(ACTION_DOCUMENT_ROOT_CHANGED);
- intent.putExtra(EXTRA_AUTHORITY, mAuthority);
- getContext().sendBroadcast(intent);
- }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 802bedf..83e1544 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -690,6 +690,19 @@
public static final String ACTION_NOTIFICATION_LISTENER_SETTINGS
= "android.settings.NOTIFICATION_LISTENER_SETTINGS";
+ /**
+ * Activity Action: Show settings for video captioning.
+ * <p>
+ * In some cases, a matching Activity may not exist, so ensure you safeguard
+ * against this.
+ * <p>
+ * Input: Nothing.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
+
// End of Intent actions for Settings
/**
@@ -3588,7 +3601,7 @@
* <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_COLOR}
* <li>{@link #ACCESSIBILITY_CAPTIONING_EDGE_TYPE}
* <li>{@link #ACCESSIBILITY_CAPTIONING_TYPEFACE}
- * <li>{@link #ACCESSIBILITY_CAPTIONING_FONT_SIZE}
+ * <li>{@link #ACCESSIBILITY_CAPTIONING_FONT_SCALE}
* </ul>
*
* @hide
@@ -3610,9 +3623,8 @@
* Integer property that specifies the preset style for captions, one
* of:
* <ul>
- * <li>{@link android.view.accessibility.CaptioningManager#PRESET_WHITE_ON_BLACK}
- * <li>{@link android.view.accessibility.CaptioningManager#PRESET_BLACK_ON_WHITE}
- * <li>{@link android.view.accessibility.CaptioningManager#PRESET_CUSTOM}
+ * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESET_CUSTOM}
+ * <li>a valid index of {@link android.view.accessibility.CaptioningManager.CaptionStyle#PRESETS}
* </ul>
*
* @see java.util.Locale#toString
@@ -3644,9 +3656,9 @@
/**
* Integer property that specifes the edge type for captions, one of:
* <ul>
- * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_NONE}
- * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_OUTLINE}
- * <li>{@link android.view.accessibility.CaptioningManager#EDGE_TYPE_DROP_SHADOWED}
+ * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_NONE}
+ * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_OUTLINE}
+ * <li>{@link android.view.accessibility.CaptioningManager.CaptionStyle#EDGE_TYPE_DROP_SHADOW}
* </ul>
*
* @see #ACCESSIBILITY_CAPTIONING_EDGE_COLOR
@@ -3682,13 +3694,12 @@
"accessibility_captioning_typeface";
/**
- * Integer point property that specifies font size for captions in
- * scaled pixels (sp).
+ * Floating point property that specifies font scaling for captions.
*
* @hide
*/
- public static final String ACCESSIBILITY_CAPTIONING_FONT_SIZE =
- "accessibility_captioning_font_size";
+ public static final String ACCESSIBILITY_CAPTIONING_FONT_SCALE =
+ "accessibility_captioning_font_scale";
/**
* The timout for considering a press to be a long press in milliseconds.
@@ -3697,13 +3708,22 @@
public static final String LONG_PRESS_TIMEOUT = "long_press_timeout";
/**
- * List of the enabled print providers.
+ * List of the enabled print services.
* @hide
*/
public static final String ENABLED_PRINT_SERVICES =
"enabled_print_services";
/**
+ * List of the system print services we enabled on first boot. On
+ * first boot we enable all system, i.e. bundled print services,
+ * once, so they work out-of-the-box.
+ * @hide
+ */
+ public static final String ENABLED_ON_FIRST_BOOT_SYSTEM_PRINT_SERVICES =
+ "enabled_on_first_boot_system_print_services";
+
+ /**
* Setting to always use the default text-to-speech settings regardless
* of the application settings.
* 1 = override application settings,
@@ -4327,7 +4347,7 @@
ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
ACCESSIBILITY_CAPTIONING_TYPEFACE,
- ACCESSIBILITY_CAPTIONING_FONT_SIZE,
+ ACCESSIBILITY_CAPTIONING_FONT_SCALE,
TTS_USE_DEFAULTS,
TTS_DEFAULT_RATE,
TTS_DEFAULT_PITCH,
diff --git a/core/java/android/security/IKeystoreService.java b/core/java/android/security/IKeystoreService.java
index 3d75dc8..bf8d4e5 100644
--- a/core/java/android/security/IKeystoreService.java
+++ b/core/java/android/security/IKeystoreService.java
@@ -244,7 +244,8 @@
return _result;
}
- public int generate(String name, int uid, int flags) throws RemoteException {
+ public int generate(String name, int uid, int keyType, int keySize, int flags,
+ byte[][] args) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
int _result;
@@ -252,7 +253,17 @@
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(name);
_data.writeInt(uid);
+ _data.writeInt(keyType);
+ _data.writeInt(keySize);
_data.writeInt(flags);
+ if (args == null) {
+ _data.writeInt(0);
+ } else {
+ _data.writeInt(args.length);
+ for (int i = 0; i < args.length; i++) {
+ _data.writeByteArray(args[i]);
+ }
+ }
mRemote.transact(Stub.TRANSACTION_generate, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
@@ -560,7 +571,8 @@
public int zero() throws RemoteException;
- public int generate(String name, int uid, int flags) throws RemoteException;
+ public int generate(String name, int uid, int keyType, int keySize, int flags, byte[][] args)
+ throws RemoteException;
public int import_key(String name, byte[] data, int uid, int flags) throws RemoteException;
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index 917a109..12a026b 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -30,7 +30,7 @@
* </ul>
*
* Any additional parameters sent to the text to speech service are passed in
- * uninterpreted, see the @code{params} argument in {@link TextToSpeech#speak}
+ * uninterpreted, see the {@code params} argument in {@link TextToSpeech#speak}
* and {@link TextToSpeech#synthesizeToFile}.
*/
public final class SynthesisRequest {
diff --git a/core/java/android/util/LayoutDirection.java b/core/java/android/util/LayoutDirection.java
index e37d2f2..20af20b 100644
--- a/core/java/android/util/LayoutDirection.java
+++ b/core/java/android/util/LayoutDirection.java
@@ -17,11 +17,15 @@
package android.util;
/**
- * An interface for defining layout directions. A layout direction can be left-to-right (LTR)
+ * A class for defining layout directions. A layout direction can be left-to-right (LTR)
* or right-to-left (RTL). It can also be inherited (from a parent) or deduced from the default
* language script of a locale.
*/
-public interface LayoutDirection {
+public final class LayoutDirection {
+
+ // No instantiation
+ private LayoutDirection() {}
+
/**
* Horizontal layout direction is from Left to Right.
*/
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 28c1058..6bbfe0f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -323,7 +323,7 @@
/**
* Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * You may only use this constructor from a {@link android.os.Looper} thread.
* @see android.os.Handler#Handler()
*
* @param context the application's context
@@ -337,14 +337,14 @@
}
/**
- * Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * Creates a GestureDetector with the supplied listener that runs deferred events on the
+ * thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
- * @param handler the handler to use
+ * @param handler the handler to use for running deferred listener events.
*
* @throws NullPointerException if {@code listener} is null.
*/
@@ -362,14 +362,15 @@
}
/**
- * Creates a GestureDetector with the supplied listener.
- * You may only use this constructor from a UI thread (this is the usual situation).
+ * Creates a GestureDetector with the supplied listener that runs deferred events on the
+ * thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
- * @param handler the handler to use
+ * @param handler the handler to use for running deferred listener events.
+ * @param unused currently not used.
*
* @throws NullPointerException if {@code listener} is null.
*/
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index 51c5c7b..0bebc04 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -18,6 +18,8 @@
import android.content.Context;
import android.content.res.Resources;
+import android.os.Build;
+import android.os.Handler;
import android.os.SystemClock;
import android.util.FloatMath;
@@ -128,6 +130,8 @@
private float mFocusX;
private float mFocusY;
+ private boolean mDoubleTapScales;
+
private float mCurrSpan;
private float mPrevSpan;
private float mInitialSpan;
@@ -148,9 +152,14 @@
private int mTouchHistoryDirection;
private long mTouchHistoryLastAcceptedTime;
private int mTouchMinMajor;
+ private MotionEvent mDoubleTapEvent;
+ private int mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
+ private final Handler mHandler;
private static final long TOUCH_STABILIZE_TIME = 128; // ms
- private static final int TOUCH_MIN_MAJOR = 48; // dp
+ private static final int DOUBLE_TAP_MODE_NONE = 0;
+ private static final int DOUBLE_TAP_MODE_IN_PROGRESS = 1;
+
/**
* Consistency verifier for debugging purposes.
@@ -158,8 +167,37 @@
private final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
InputEventConsistencyVerifier.isInstrumentationEnabled() ?
new InputEventConsistencyVerifier(this, 0) : null;
+ private GestureDetector mGestureDetector;
+ private boolean mEventBeforeOrAboveStartingGestureEvent;
+
+ /**
+ * Creates a ScaleGestureDetector with the supplied listener.
+ * You may only use this constructor from a {@link android.os.Looper Looper} thread.
+ *
+ * @param context the application's context
+ * @param listener the listener invoked for all the callbacks, this must
+ * not be null.
+ *
+ * @throws NullPointerException if {@code listener} is null.
+ */
public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
+ this(context, listener, null);
+ }
+
+ /**
+ * Creates a ScaleGestureDetector with the supplied listener.
+ * @see android.os.Handler#Handler()
+ *
+ * @param context the application's context
+ * @param listener the listener invoked for all the callbacks, this must
+ * not be null.
+ * @param handler the handler to use for running deferred listener events.
+ *
+ * @throws NullPointerException if {@code listener} is null.
+ */
+ public ScaleGestureDetector(Context context, OnScaleGestureListener listener,
+ Handler handler) {
mContext = context;
mListener = listener;
mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2;
@@ -167,8 +205,12 @@
final Resources res = context.getResources();
mTouchMinMajor = res.getDimensionPixelSize(
com.android.internal.R.dimen.config_minScalingTouchMajor);
- mMinSpan = res.getDimensionPixelSize(
- com.android.internal.R.dimen.config_minScalingSpan);
+ mMinSpan = res.getDimensionPixelSize(com.android.internal.R.dimen.config_minScalingSpan);
+ mHandler = handler;
+ // Quick scale is enabled by default after JB_MR2
+ if (context.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ setQuickScaleEnabled(true);
+ }
}
/**
@@ -263,8 +305,14 @@
final int action = event.getActionMasked();
+ // Forward the event to check for double tap gesture
+ if (mDoubleTapScales) {
+ mGestureDetector.onTouchEvent(event);
+ }
+
final boolean streamComplete = action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_CANCEL;
+
if (action == MotionEvent.ACTION_DOWN || streamComplete) {
// Reset any scale in progress with the listener.
// If it's an ACTION_DOWN we're beginning a new event stream.
@@ -273,6 +321,7 @@
mListener.onScaleEnd(this);
mInProgress = false;
mInitialSpan = 0;
+ mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
}
if (streamComplete) {
@@ -284,21 +333,37 @@
final boolean configChanged = action == MotionEvent.ACTION_DOWN ||
action == MotionEvent.ACTION_POINTER_UP ||
action == MotionEvent.ACTION_POINTER_DOWN;
+
+
final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
final int skipIndex = pointerUp ? event.getActionIndex() : -1;
// Determine focal point
float sumX = 0, sumY = 0;
final int count = event.getPointerCount();
- for (int i = 0; i < count; i++) {
- if (skipIndex == i) continue;
- sumX += event.getX(i);
- sumY += event.getY(i);
- }
final int div = pointerUp ? count - 1 : count;
- final float focusX = sumX / div;
- final float focusY = sumY / div;
+ final float focusX;
+ final float focusY;
+ if (mDoubleTapMode == DOUBLE_TAP_MODE_IN_PROGRESS) {
+ // In double tap mode, the focal pt is always where the double tap
+ // gesture started
+ focusX = mDoubleTapEvent.getX();
+ focusY = mDoubleTapEvent.getY();
+ if (event.getY() < focusY) {
+ mEventBeforeOrAboveStartingGestureEvent = true;
+ } else {
+ mEventBeforeOrAboveStartingGestureEvent = false;
+ }
+ } else {
+ for (int i = 0; i < count; i++) {
+ if (skipIndex == i) continue;
+ sumX += event.getX(i);
+ sumY += event.getY(i);
+ }
+ focusX = sumX / div;
+ focusY = sumY / div;
+ }
addTouchHistory(event);
@@ -320,7 +385,12 @@
// the focal point.
final float spanX = devX * 2;
final float spanY = devY * 2;
- final float span = FloatMath.sqrt(spanX * spanX + spanY * spanY);
+ final float span;
+ if (inDoubleTapMode()) {
+ span = spanY;
+ } else {
+ span = FloatMath.sqrt(spanX * spanX + spanY * spanY);
+ }
// Dispatch begin/end events as needed.
// If the configuration changes, notify the app to reset its current state by beginning
@@ -328,10 +398,11 @@
final boolean wasInProgress = mInProgress;
mFocusX = focusX;
mFocusY = focusY;
- if (mInProgress && (span < mMinSpan || configChanged)) {
+ if (!inDoubleTapMode() && mInProgress && (span < mMinSpan || configChanged)) {
mListener.onScaleEnd(this);
mInProgress = false;
mInitialSpan = span;
+ mDoubleTapMode = DOUBLE_TAP_MODE_NONE;
}
if (configChanged) {
mPrevSpanX = mCurrSpanX = spanX;
@@ -354,6 +425,7 @@
mCurrSpan = span;
boolean updatePrev = true;
+
if (mInProgress) {
updatePrev = mListener.onScale(this);
}
@@ -369,6 +441,34 @@
return true;
}
+
+ private boolean inDoubleTapMode() {
+ return mDoubleTapMode == DOUBLE_TAP_MODE_IN_PROGRESS;
+ }
+
+ /**
+ * Set whether the associated {@link OnScaleGestureListener} should receive onScale callbacks
+ * when the user performs a doubleTap followed by a swipe. Note that this is enabled by default
+ * if the app targets API 19 and newer.
+ * @param scales true to enable quick scaling, false to disable
+ */
+ public void setQuickScaleEnabled(boolean scales) {
+ mDoubleTapScales = scales;
+ if (mDoubleTapScales && mGestureDetector == null) {
+ GestureDetector.SimpleOnGestureListener gestureListener =
+ new GestureDetector.SimpleOnGestureListener() {
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ // Double tap: start watching for a swipe
+ mDoubleTapEvent = e;
+ mDoubleTapMode = DOUBLE_TAP_MODE_IN_PROGRESS;
+ return true;
+ }
+ };
+ mGestureDetector = new GestureDetector(mContext, gestureListener, mHandler);
+ }
+ }
+
/**
* Returns {@code true} if a scale gesture is in progress.
*/
@@ -472,6 +572,12 @@
* @return The current scaling factor.
*/
public float getScaleFactor() {
+ if (inDoubleTapMode() && mEventBeforeOrAboveStartingGestureEvent) {
+ // Drag is moving up; the further away from the gesture
+ // start, the smaller the span should be, the closer,
+ // the larger the span, and therefore the larger the scale
+ return (1 / mCurrSpan) / (1 / mPrevSpan);
+ }
return mPrevSpan > 0 ? mCurrSpan / mPrevSpan : 1;
}
@@ -493,4 +599,4 @@
public long getEventTime() {
return mCurrTime;
}
-}
+}
\ No newline at end of file
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 5b279ec..7b69a81 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8836,9 +8836,11 @@
/**
* Change the view's z order in the tree, so it's on top of other sibling
* views. This ordering change may affect layout, if the parent container
- * uses an order-dependent layout scheme (e.g., LinearLayout). This
+ * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+ * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
* method should be followed by calls to {@link #requestLayout()} and
- * {@link View#invalidate()} on the parent.
+ * {@link View#invalidate()} on the view's parent to force the parent to redraw
+ * with the new child ordering.
*
* @see ViewGroup#bringChildToFront(View)
*/
@@ -13256,14 +13258,8 @@
// Keep the DRAWING_CACHE_QUALITY_LOW flag just in case
switch (mViewFlags & DRAWING_CACHE_QUALITY_MASK) {
case DRAWING_CACHE_QUALITY_AUTO:
- quality = Bitmap.Config.ARGB_8888;
- break;
case DRAWING_CACHE_QUALITY_LOW:
- quality = Bitmap.Config.ARGB_8888;
- break;
case DRAWING_CACHE_QUALITY_HIGH:
- quality = Bitmap.Config.ARGB_8888;
- break;
default:
quality = Bitmap.Config.ARGB_8888;
break;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 03a9c37..2d75b06 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1123,6 +1123,8 @@
removeFromArray(index);
addInArray(child, mChildrenCount);
child.mParent = this;
+ requestLayout();
+ invalidate();
}
}
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 26596d9..656d756 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -148,9 +148,11 @@
/**
* Change the z order of the child so it's on top of all other children.
* This ordering change may affect layout, if this container
- * uses an order-dependent layout scheme (e.g., LinearLayout). This
+ * uses an order-dependent layout scheme (e.g., LinearLayout). Prior
+ * to {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} this
* method should be followed by calls to {@link #requestLayout()} and
- * {@link View#invalidate()} on this parent.
+ * {@link View#invalidate()} on this parent to force the parent to redraw
+ * with the new child ordering.
*
* @param child The child to bring to the top of the z order
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 354e815..0f9a2ac 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1449,7 +1449,7 @@
}
DisplayList displayList = mView.mDisplayList;
- if (displayList != null) {
+ if (displayList != null && displayList.isValid()) {
layerCanvas.drawDisplayList(displayList, null,
DisplayList.FLAG_CLIP_CHILDREN);
} else {
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index b1be24c..d4c6abe 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -17,58 +17,77 @@
package android.view.accessibility;
import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
import android.graphics.Color;
import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Handler;
import android.provider.Settings.Secure;
import android.text.TextUtils;
+import java.util.ArrayList;
import java.util.Locale;
/**
- * Contains methods for accessing preferred video captioning state and
+ * Contains methods for accessing and monitoring preferred video captioning state and visual
* properties.
+ * <p>
+ * To obtain a handle to the captioning manager, do the following:
+ * <p>
+ * <code>
+ * <pre>CaptioningManager captioningManager =
+ * (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);</pre>
+ * </code>
*/
public class CaptioningManager {
- /**
- * Activity Action: Show settings for video captioning.
- * <p>
- * In some cases, a matching Activity may not exist, so ensure you safeguard
- * against this.
- * <p>
- * Input: Nothing.
- * <p>
- * Output: Nothing.
- */
- public static final String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
-
- private static final int DEFAULT_PRESET = 0;
+ /** Default captioning enabled value. */
private static final int DEFAULT_ENABLED = 0;
- private static final float DEFAULT_FONT_SIZE = 24;
+
+ /** Default style preset as an index into {@link CaptionStyle#PRESETS}. */
+ private static final int DEFAULT_PRESET = 0;
+
+ /** Default scaling value for caption fonts. */
+ private static final float DEFAULT_FONT_SCALE = 1;
+
+ private final ArrayList<CaptioningChangeListener>
+ mListeners = new ArrayList<CaptioningChangeListener>();
+ private final Handler mHandler = new Handler();
+
+ private final ContentResolver mContentResolver;
/**
- * @param cr Resolver to access the database with.
- * @return The user's preferred caption enabled state.
- */
- public static final boolean isEnabled(ContentResolver cr) {
- return Secure.getInt(cr, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1;
- }
-
- /**
- * @param cr Resolver to access the database with.
- * @return The raw locale string for the user's preferred caption language.
+ * Creates a new captioning manager for the specified context.
+ *
* @hide
*/
- public static final String getRawLocale(ContentResolver cr) {
- return Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+ public CaptioningManager(Context context) {
+ mContentResolver = context.getContentResolver();
}
/**
- * @param cr Resolver to access the database with.
- * @return The locale for the user's preferred caption language, or null if
- * not specified.
+ * @return the user's preferred captioning enabled state
*/
- public static final Locale getLocale(ContentResolver cr) {
- final String rawLocale = getRawLocale(cr);
+ public final boolean isEnabled() {
+ return Secure.getInt(
+ mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_ENABLED, DEFAULT_ENABLED) == 1;
+ }
+
+ /**
+ * @return the raw locale string for the user's preferred captioning
+ * language
+ * @hide
+ */
+ public final String getRawLocale() {
+ return Secure.getString(mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+ }
+
+ /**
+ * @return the locale for the user's preferred captioning language, or null
+ * if not specified
+ */
+ public final Locale getLocale() {
+ final String rawLocale = getRawLocale();
if (!TextUtils.isEmpty(rawLocale)) {
final String[] splitLocale = rawLocale.split("_");
switch (splitLocale.length) {
@@ -85,14 +104,151 @@
}
/**
- * @param cr Resolver to access the database with.
- * @return The user's preferred font size for video captions, or 0 if not
- * specified.
+ * @return the user's preferred font scaling factor for video captions, or 1 if not
+ * specified
*/
- public static final float getFontSize(ContentResolver cr) {
- return Secure.getFloat(cr, Secure.ACCESSIBILITY_CAPTIONING_FONT_SIZE, DEFAULT_FONT_SIZE);
+ public final float getFontScale() {
+ return Secure.getFloat(
+ mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE, DEFAULT_FONT_SCALE);
}
+ /**
+ * @return the raw preset number, or the first preset if not specified
+ * @hide
+ */
+ public int getRawUserStyle() {
+ return Secure.getInt(
+ mContentResolver, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET);
+ }
+
+ /**
+ * @return the user's preferred visual properties for captions as a
+ * {@link CaptionStyle}, or the default style if not specified
+ */
+ public CaptionStyle getUserStyle() {
+ final int preset = getRawUserStyle();
+ if (preset == CaptionStyle.PRESET_CUSTOM) {
+ return CaptionStyle.getCustomStyle(mContentResolver);
+ }
+
+ return CaptionStyle.PRESETS[preset];
+ }
+
+ /**
+ * Adds a listener for changes in the user's preferred captioning enabled
+ * state and visual properties.
+ *
+ * @param listener the listener to add
+ */
+ public void addCaptioningStateChangeListener(CaptioningChangeListener listener) {
+ synchronized (mListeners) {
+ if (mListeners.isEmpty()) {
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE);
+ registerObserver(Secure.ACCESSIBILITY_CAPTIONING_LOCALE);
+ }
+
+ mListeners.add(listener);
+ }
+ }
+
+ private void registerObserver(String key) {
+ mContentResolver.registerContentObserver(Secure.getUriFor(key), false, mContentObserver);
+ }
+
+ /**
+ * Removes a listener previously added using
+ * {@link #addCaptioningStateChangeListener}.
+ *
+ * @param listener the listener to remove
+ */
+ public void removeCaptioningStateChangeListener(CaptioningChangeListener listener) {
+ synchronized (mListeners) {
+ mListeners.remove(listener);
+
+ if (mListeners.isEmpty()) {
+ mContentResolver.unregisterContentObserver(mContentObserver);
+ }
+ }
+ }
+
+ private void notifyEnabledChanged() {
+ final boolean enabled = isEnabled();
+ synchronized (mListeners) {
+ for (CaptioningChangeListener listener : mListeners) {
+ listener.onEnabledChanged(enabled);
+ }
+ }
+ }
+
+ private void notifyUserStyleChanged() {
+ final CaptionStyle userStyle = getUserStyle();
+ synchronized (mListeners) {
+ for (CaptioningChangeListener listener : mListeners) {
+ listener.onUserStyleChanged(userStyle);
+ }
+ }
+ }
+
+ private void notifyLocaleChanged() {
+ final Locale locale = getLocale();
+ synchronized (mListeners) {
+ for (CaptioningChangeListener listener : mListeners) {
+ listener.onLocaleChanged(locale);
+ }
+ }
+ }
+
+ private void notifyFontScaleChanged() {
+ final float fontScale = getFontScale();
+ synchronized (mListeners) {
+ for (CaptioningChangeListener listener : mListeners) {
+ listener.onFontScaleChanged(fontScale);
+ }
+ }
+ }
+
+ private final ContentObserver mContentObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ final String uriPath = uri.getPath();
+ final String name = uriPath.substring(uriPath.lastIndexOf('/') + 1);
+ if (Secure.ACCESSIBILITY_CAPTIONING_ENABLED.equals(name)) {
+ notifyEnabledChanged();
+ } else if (Secure.ACCESSIBILITY_CAPTIONING_LOCALE.equals(name)) {
+ notifyLocaleChanged();
+ } else if (Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE.equals(name)) {
+ notifyFontScaleChanged();
+ } else {
+ // We only need a single callback when multiple style properties
+ // change in rapid succession.
+ mHandler.removeCallbacks(mStyleChangedRunnable);
+ mHandler.post(mStyleChangedRunnable);
+ }
+ }
+ };
+
+ /**
+ * Runnable posted when user style properties change. This is used to
+ * prevent unnecessary change notifications when multiple properties change
+ * in rapid succession.
+ */
+ private final Runnable mStyleChangedRunnable = new Runnable() {
+ @Override
+ public void run() {
+ notifyUserStyleChanged();
+ }
+ };
+
+ /**
+ * Specifies visual properties for video captions, including foreground and
+ * background colors, edge properties, and typeface.
+ */
public static final class CaptionStyle {
private static final CaptionStyle WHITE_ON_BLACK;
private static final CaptionStyle BLACK_ON_WHITE;
@@ -155,8 +311,8 @@
}
/**
- * @return The preferred {@link Typeface} for video captions, or null if
- * not specified.
+ * @return the preferred {@link Typeface} for video captions, or null if
+ * not specified
*/
public Typeface getTypeface() {
if (mParsedTypeface == null && !TextUtils.isEmpty(mRawTypeface)) {
@@ -168,41 +324,20 @@
/**
* @hide
*/
- public static int getRawPreset(ContentResolver cr) {
- return Secure.getInt(cr, Secure.ACCESSIBILITY_CAPTIONING_PRESET, DEFAULT_PRESET);
- }
-
- /**
- * @param cr Resolver to access the database with.
- * @return The user's preferred caption style.
- */
- public static CaptionStyle defaultUserStyle(ContentResolver cr) {
- final int preset = getRawPreset(cr);
- if (preset == PRESET_CUSTOM) {
- return getCustomStyle(cr);
- }
-
- return PRESETS[preset];
- }
-
- /**
- * @hide
- */
public static CaptionStyle getCustomStyle(ContentResolver cr) {
+ final CaptionStyle defStyle = CaptionStyle.DEFAULT_CUSTOM;
final int foregroundColor = Secure.getInt(
- cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
- DEFAULT_CUSTOM.foregroundColor);
- final int backgroundColor = Secure.getInt(cr,
- Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
- DEFAULT_CUSTOM.backgroundColor);
+ cr, Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, defStyle.foregroundColor);
+ final int backgroundColor = Secure.getInt(
+ cr, Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, defStyle.backgroundColor);
final int edgeType = Secure.getInt(
- cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, DEFAULT_CUSTOM.edgeType);
+ cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType);
final int edgeColor = Secure.getInt(
- cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, DEFAULT_CUSTOM.edgeColor);
+ cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor);
String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
if (rawTypeface == null) {
- rawTypeface = DEFAULT_CUSTOM.mRawTypeface;
+ rawTypeface = defStyle.mRawTypeface;
}
return new CaptionStyle(
@@ -226,4 +361,45 @@
DEFAULT_CUSTOM = WHITE_ON_BLACK;
}
}
+
+ /**
+ * Listener for changes in captioning properties, including enabled state
+ * and user style preferences.
+ */
+ public abstract class CaptioningChangeListener {
+ /**
+ * Called when the captioning enabled state changes.
+ *
+ * @param enabled the user's new preferred captioning enabled state
+ */
+ public void onEnabledChanged(boolean enabled) {
+ }
+
+ /**
+ * Called when the captioning user style changes.
+ *
+ * @param userStyle the user's new preferred style
+ * @see CaptioningManager#getUserStyle()
+ */
+ public void onUserStyleChanged(CaptionStyle userStyle) {
+ }
+
+ /**
+ * Called when the captioning locale changes.
+ *
+ * @param locale the preferred captioning locale
+ * @see CaptioningManager#getLocale()
+ */
+ public void onLocaleChanged(Locale locale) {
+ }
+
+ /**
+ * Called when the captioning font scaling factor changes.
+ *
+ * @param fontScale the preferred font scaling factor
+ * @see CaptioningManager#getFontScale()
+ */
+ public void onFontScaleChanged(float fontScale) {
+ }
+ }
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f97e3dd..54b87de 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1876,9 +1876,13 @@
}
/**
- * Returns true if the current IME needs to offer the users a way to switch to a next input
- * method. When the user triggers it, the IME has to call {@link #switchToNextInputMethod} to
- * switch to a next input method which is selected by the system.
+ * Returns true if the current IME needs to offer the users ways to switch to a next input
+ * method (e.g. a globe key.).
+ * When an IME sets supportsSwitchingToNextInputMethod and this method returns true,
+ * the IME has to offer ways to to invoke {@link #switchToNextInputMethod} accordingly.
+ * <p> Note that the system determines the most appropriate next input method
+ * and subtype in order to provide the consistent user experience in switching
+ * between IMEs and subtypes.
* @param imeToken Supplies the identifying token given to an input method when it was started,
* which allows it to perform this operation on itself.
*/
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index fea6be6..7707392 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -50,7 +50,9 @@
*/
class CallbackProxy extends Handler {
// Logging tag
- private static final String LOGTAG = "CallbackProxy";
+ static final String LOGTAG = "WebViewCallback";
+ // Enables API callback tracing
+ private static final boolean TRACE = DebugFlags.TRACE_CALLBACK;
// Instance of WebViewClient that is the client callback.
private volatile WebViewClient mWebViewClient;
// Instance of WebChromeClient for handling all chrome functions.
@@ -258,6 +260,7 @@
}
boolean override = false;
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "shouldOverrideUrlLoading=" + overrideUrl);
override = mWebViewClient.shouldOverrideUrlLoading(mWebView.getWebView(),
overrideUrl);
} else {
@@ -307,6 +310,7 @@
String startedUrl = msg.getData().getString("url");
mWebView.onPageStarted(startedUrl);
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onPageStarted=" + startedUrl);
mWebViewClient.onPageStarted(mWebView.getWebView(), startedUrl,
(Bitmap) msg.obj);
}
@@ -316,18 +320,21 @@
String finishedUrl = (String) msg.obj;
mWebView.onPageFinished(finishedUrl);
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onPageFinished=" + finishedUrl);
mWebViewClient.onPageFinished(mWebView.getWebView(), finishedUrl);
}
break;
case RECEIVED_ICON:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onReceivedIcon");
mWebChromeClient.onReceivedIcon(mWebView.getWebView(), (Bitmap) msg.obj);
}
break;
case RECEIVED_TOUCH_ICON_URL:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onReceivedTouchIconUrl");
mWebChromeClient.onReceivedTouchIconUrl(mWebView.getWebView(),
(String) msg.obj, msg.arg1 == 1);
}
@@ -335,6 +342,7 @@
case RECEIVED_TITLE:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onReceivedTitle");
mWebChromeClient.onReceivedTitle(mWebView.getWebView(),
(String) msg.obj);
}
@@ -345,6 +353,7 @@
int reasonCode = msg.arg1;
final String description = msg.getData().getString("description");
final String failUrl = msg.getData().getString("failingUrl");
+ if (TRACE) Log.d(LOGTAG, "onReceivedError=" + failUrl);
mWebViewClient.onReceivedError(mWebView.getWebView(), reasonCode,
description, failUrl);
}
@@ -356,6 +365,7 @@
Message dontResend =
(Message) msg.getData().getParcelable("dontResend");
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onFormResubmission");
mWebViewClient.onFormResubmission(mWebView.getWebView(), dontResend,
resend);
} else {
@@ -379,6 +389,7 @@
HttpAuthHandler handler = (HttpAuthHandler) msg.obj;
String host = msg.getData().getString("host");
String realm = msg.getData().getString("realm");
+ if (TRACE) Log.d(LOGTAG, "onReceivedHttpAuthRequest");
mWebViewClient.onReceivedHttpAuthRequest(mWebView.getWebView(), handler,
host, realm);
}
@@ -388,6 +399,7 @@
if (mWebViewClient != null) {
HashMap<String, Object> map =
(HashMap<String, Object>) msg.obj;
+ if (TRACE) Log.d(LOGTAG, "onReceivedSslError");
mWebViewClient.onReceivedSslError(mWebView.getWebView(),
(SslErrorHandler) map.get("handler"),
(SslError) map.get("error"));
@@ -396,6 +408,7 @@
case PROCEEDED_AFTER_SSL_ERROR:
if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+ if (TRACE) Log.d(LOGTAG, "onProceededAfterSslError");
((WebViewClientClassicExt) mWebViewClient).onProceededAfterSslError(
mWebView.getWebView(),
(SslError) msg.obj);
@@ -404,6 +417,7 @@
case CLIENT_CERT_REQUEST:
if (mWebViewClient != null && mWebViewClient instanceof WebViewClientClassicExt) {
+ if (TRACE) Log.d(LOGTAG, "onReceivedClientCertRequest");
HashMap<String, Object> map = (HashMap<String, Object>) msg.obj;
((WebViewClientClassicExt) mWebViewClient).onReceivedClientCertRequest(
mWebView.getWebView(),
@@ -418,6 +432,7 @@
// changed.
synchronized (this) {
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onProgressChanged=" + mLatestProgress);
mWebChromeClient.onProgressChanged(mWebView.getWebView(),
mLatestProgress);
}
@@ -427,14 +442,18 @@
case UPDATE_VISITED:
if (mWebViewClient != null) {
+ String url = (String) msg.obj;
+ if (TRACE) Log.d(LOGTAG, "doUpdateVisitedHistory=" + url);
mWebViewClient.doUpdateVisitedHistory(mWebView.getWebView(),
- (String) msg.obj, msg.arg1 != 0);
+ url, msg.arg1 != 0);
}
break;
case LOAD_RESOURCE:
if (mWebViewClient != null) {
- mWebViewClient.onLoadResource(mWebView.getWebView(), (String) msg.obj);
+ String url = (String) msg.obj;
+ if (TRACE) Log.d(LOGTAG, "onLoadResource=" + url);
+ mWebViewClient.onLoadResource(mWebView.getWebView(), url);
}
break;
@@ -448,6 +467,7 @@
String referer = msg.getData().getString("referer");
Long contentLength = msg.getData().getLong("contentLength");
+ if (TRACE) Log.d(LOGTAG, "onDownloadStart");
if (mDownloadListener instanceof BrowserDownloadListener) {
((BrowserDownloadListener) mDownloadListener).onDownloadStart(url,
userAgent, contentDisposition, mimetype, referer, contentLength);
@@ -460,6 +480,7 @@
case CREATE_WINDOW:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onCreateWindow");
if (!mWebChromeClient.onCreateWindow(mWebView.getWebView(),
msg.arg1 == 1, msg.arg2 == 1,
(Message) msg.obj)) {
@@ -473,12 +494,14 @@
case REQUEST_FOCUS:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onRequestFocus");
mWebChromeClient.onRequestFocus(mWebView.getWebView());
}
break;
case CLOSE_WINDOW:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onCloseWindow");
mWebChromeClient.onCloseWindow(((WebViewClassic) msg.obj).getWebView());
}
break;
@@ -500,6 +523,7 @@
case ASYNC_KEYEVENTS:
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onUnhandledKeyEvent");
mWebViewClient.onUnhandledKeyEvent(mWebView.getWebView(),
(KeyEvent) msg.obj);
}
@@ -521,6 +545,7 @@
WebStorage.QuotaUpdater quotaUpdater =
(WebStorage.QuotaUpdater) map.get("quotaUpdater");
+ if (TRACE) Log.d(LOGTAG, "onExceededDatabaseQuota");
mWebChromeClient.onExceededDatabaseQuota(url,
databaseIdentifier, quota, estimatedDatabaseSize,
totalQuota, quotaUpdater);
@@ -538,6 +563,7 @@
WebStorage.QuotaUpdater quotaUpdater =
(WebStorage.QuotaUpdater) map.get("quotaUpdater");
+ if (TRACE) Log.d(LOGTAG, "onReachedMaxAppCacheSize");
mWebChromeClient.onReachedMaxAppCacheSize(requiredStorage,
quota, quotaUpdater);
}
@@ -551,6 +577,7 @@
GeolocationPermissions.Callback callback =
(GeolocationPermissions.Callback)
map.get("callback");
+ if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsShowPrompt");
mWebChromeClient.onGeolocationPermissionsShowPrompt(origin,
callback);
}
@@ -558,6 +585,7 @@
case GEOLOCATION_PERMISSIONS_HIDE_PROMPT:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onGeolocationPermissionsHidePrompt");
mWebChromeClient.onGeolocationPermissionsHidePrompt();
}
break;
@@ -566,6 +594,7 @@
if (mWebChromeClient != null) {
final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
JsDialogHelper helper = new JsDialogHelper(receiver.mJsResult, msg);
+ if (TRACE) Log.d(LOGTAG, "onJsAlert");
if (!helper.invokeCallback(mWebChromeClient, mWebView.getWebView())) {
helper.showDialog(mContext);
}
@@ -577,6 +606,7 @@
if(mWebChromeClient != null) {
final JsResultReceiver receiver = (JsResultReceiver) msg.obj;
final JsResult res = receiver.mJsResult;
+ if (TRACE) Log.d(LOGTAG, "onJsTimeout");
if (mWebChromeClient.onJsTimeout()) {
res.confirm();
} else {
@@ -598,6 +628,7 @@
case SCALE_CHANGED:
if (mWebViewClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onScaleChanged");
mWebViewClient.onScaleChanged(mWebView.getWebView(), msg.getData()
.getFloat("old"), msg.getData().getFloat("new"));
}
@@ -624,6 +655,7 @@
ConsoleMessage.MessageLevel messageLevel =
ConsoleMessage.MessageLevel.values()[msgLevel];
+ if (TRACE) Log.d(LOGTAG, "onConsoleMessage");
if (!mWebChromeClient.onConsoleMessage(new ConsoleMessage(message, sourceID,
lineNumber, messageLevel))) {
// If false was returned the user did not provide their own console function so
@@ -654,12 +686,14 @@
case GET_VISITED_HISTORY:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "getVisitedHistory");
mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj);
}
break;
case OPEN_FILE_CHOOSER:
if (mWebChromeClient != null) {
+ if (TRACE) Log.d(LOGTAG, "openFileChooser");
UploadFileMessageData data = (UploadFileMessageData)msg.obj;
mWebChromeClient.openFileChooser(data.getUploadFile(), data.getAcceptType(),
data.getCapture());
@@ -668,6 +702,7 @@
case ADD_HISTORY_ITEM:
if (mWebBackForwardListClient != null) {
+ if (TRACE) Log.d(LOGTAG, "onNewHistoryItem");
mWebBackForwardListClient.onNewHistoryItem(
(WebHistoryItem) msg.obj);
}
@@ -693,6 +728,7 @@
String realm = msg.getData().getString("realm");
String account = msg.getData().getString("account");
String args = msg.getData().getString("args");
+ if (TRACE) Log.d(LOGTAG, "onReceivedLoginRequest");
mWebViewClient.onReceivedLoginRequest(mWebView.getWebView(), realm,
account, args);
}
@@ -910,6 +946,7 @@
return null;
}
// Note: This method does _not_ send a message.
+ if (TRACE) Log.d(LOGTAG, "shouldInterceptRequest=" + url);
WebResourceResponse r =
mWebViewClient.shouldInterceptRequest(mWebView.getWebView(), url);
if (r == null) {
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 349113e..524f610 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -24,25 +24,33 @@
* The name of each flags maps directly to the name of the class in which that
* flag is used.
*
+ * @hide Only used by WebView implementations.
*/
-class DebugFlags {
+public class DebugFlags {
+ public static final boolean COOKIE_SYNC_MANAGER = false;
+ public static final boolean TRACE_API = false;
+ public static final boolean TRACE_CALLBACK = false;
+ public static final boolean TRACE_JAVASCRIPT_BRIDGE = false;
+ public static final boolean URL_UTIL = false;
+ public static final boolean WEB_SYNC_MANAGER = false;
+
+ // TODO: Delete these when WebViewClassic is moved
public static final boolean BROWSER_FRAME = false;
public static final boolean CACHE_MANAGER = false;
public static final boolean CALLBACK_PROXY = false;
public static final boolean COOKIE_MANAGER = false;
- public static final boolean COOKIE_SYNC_MANAGER = false;
public static final boolean FRAME_LOADER = false;
public static final boolean J_WEB_CORE_JAVA_BRIDGE = false;// HIGHLY VERBOSE
public static final boolean LOAD_LISTENER = false;
+ public static final boolean MEASURE_PAGE_SWAP_FPS = false;
public static final boolean NETWORK = false;
public static final boolean SSL_ERROR_HANDLER = false;
public static final boolean STREAM_LOADER = false;
- public static final boolean URL_UTIL = false;
public static final boolean WEB_BACK_FORWARD_LIST = false;
public static final boolean WEB_SETTINGS = false;
- public static final boolean WEB_SYNC_MANAGER = false;
public static final boolean WEB_VIEW = false;
public static final boolean WEB_VIEW_CORE = false;
- public static final boolean MEASURE_PAGE_SWAP_FPS = false;
+
+
}
diff --git a/core/java/android/webkit/HTML5VideoFullScreen.java b/core/java/android/webkit/HTML5VideoFullScreen.java
index b52218d..6fb32c8 100644
--- a/core/java/android/webkit/HTML5VideoFullScreen.java
+++ b/core/java/android/webkit/HTML5VideoFullScreen.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.media.MediaPlayer;
import android.media.Metadata;
+import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
@@ -293,12 +294,16 @@
mLayout.setVisibility(View.VISIBLE);
WebChromeClient client = webView.getWebChromeClient();
if (client != null) {
+ if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onShowCustomView");
client.onShowCustomView(mLayout, mCallback);
// Plugins like Flash will draw over the video so hide
// them while we're playing.
if (webView.getViewManager() != null)
webView.getViewManager().hideAll();
+ if (DebugFlags.TRACE_CALLBACK) {
+ Log.d(CallbackProxy.LOGTAG, "getVideoLoadingProgressView");
+ }
mProgressView = client.getVideoLoadingProgressView();
if (mProgressView != null) {
mLayout.addView(mProgressView, layoutParams);
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index a3d62ae..e8538f6 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -180,6 +180,7 @@
if (!mHTML5VideoView.fullScreenExited() && mHTML5VideoView.isFullScreenMode()) {
WebChromeClient client = webView.getWebChromeClient();
if (client != null) {
+ if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
client.onHideCustomView();
}
}
@@ -405,6 +406,7 @@
case ERROR: {
WebChromeClient client = mWebView.getWebChromeClient();
if (client != null) {
+ if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onHideCustomView");
client.onHideCustomView();
}
break;
@@ -412,6 +414,9 @@
case LOAD_DEFAULT_POSTER: {
WebChromeClient client = mWebView.getWebChromeClient();
if (client != null) {
+ if (DebugFlags.TRACE_CALLBACK) {
+ Log.d(CallbackProxy.LOGTAG, "getDefaultVideoPoster");
+ }
doSetPoster(client.getDefaultVideoPoster());
}
break;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 1b57d50..f0e8c4f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -31,7 +31,9 @@
import android.os.CancellationSignal;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.StrictMode;
+import android.print.PrintAttributes;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@@ -49,7 +51,6 @@
import java.io.BufferedWriter;
import java.io.File;
-import java.io.OutputStream;
import java.util.Map;
/**
@@ -243,7 +244,7 @@
implements ViewTreeObserver.OnGlobalFocusChangeListener,
ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
- private static final String LOGTAG = "webview_proxy";
+ private static final String LOGTAG = "WebView";
// Throwing an exception for incorrect thread usage if the
// build target is JB MR2 or newer. Defaults to false, and is
@@ -495,9 +496,12 @@
sEnforceThreadChecking = context.getApplicationInfo().targetSdkVersion >=
Build.VERSION_CODES.JELLY_BEAN_MR2;
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "WebView<init>");
ensureProviderCreated();
mProvider.init(javaScriptInterfaces, privateBrowsing);
+ // Post condition of creating a webview is the CookieSyncManager instance exists.
+ CookieSyncManager.createInstance(getContext());
}
/**
@@ -507,6 +511,7 @@
*/
public void setHorizontalScrollbarOverlay(boolean overlay) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHorizontalScrollbarOverlay=" + overlay);
mProvider.setHorizontalScrollbarOverlay(overlay);
}
@@ -517,6 +522,7 @@
*/
public void setVerticalScrollbarOverlay(boolean overlay) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setVerticalScrollbarOverlay=" + overlay);
mProvider.setVerticalScrollbarOverlay(overlay);
}
@@ -571,6 +577,7 @@
@Deprecated
public void setCertificate(SslCertificate certificate) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setCertificate=" + certificate);
mProvider.setCertificate(certificate);
}
@@ -594,6 +601,7 @@
@Deprecated
public void savePassword(String host, String username, String password) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePassword=" + host);
mProvider.savePassword(host, username, password);
}
@@ -613,6 +621,7 @@
public void setHttpAuthUsernamePassword(String host, String realm,
String username, String password) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setHttpAuthUsernamePassword=" + host);
mProvider.setHttpAuthUsernamePassword(host, realm, username, password);
}
@@ -642,6 +651,7 @@
*/
public void destroy() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "destroy");
mProvider.destroy();
}
@@ -680,6 +690,7 @@
*/
public void setNetworkAvailable(boolean networkUp) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setNetworkAvailable=" + networkUp);
mProvider.setNetworkAvailable(networkUp);
}
@@ -696,6 +707,7 @@
*/
public WebBackForwardList saveState(Bundle outState) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveState");
return mProvider.saveState(outState);
}
@@ -712,6 +724,7 @@
@Deprecated
public boolean savePicture(Bundle b, final File dest) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "savePicture=" + dest.getName());
return mProvider.savePicture(b, dest);
}
@@ -729,6 +742,7 @@
@Deprecated
public boolean restorePicture(Bundle b, File src) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restorePicture=" + src.getName());
return mProvider.restorePicture(b, src);
}
@@ -746,6 +760,7 @@
*/
public WebBackForwardList restoreState(Bundle inState) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "restoreState");
return mProvider.restoreState(inState);
}
@@ -762,6 +777,7 @@
*/
public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
mProvider.loadUrl(url, additionalHttpHeaders);
}
@@ -772,6 +788,7 @@
*/
public void loadUrl(String url) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl=" + url);
mProvider.loadUrl(url);
}
@@ -786,6 +803,7 @@
*/
public void postUrl(String url, byte[] postData) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
mProvider.postUrl(url, postData);
}
@@ -820,6 +838,7 @@
*/
public void loadData(String data, String mimeType, String encoding) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadData");
mProvider.loadData(data, mimeType, encoding);
}
@@ -852,6 +871,7 @@
public void loadDataWithBaseURL(String baseUrl, String data,
String mimeType, String encoding, String historyUrl) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadDataWithBaseURL=" + baseUrl);
mProvider.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);
}
@@ -868,6 +888,7 @@
*/
public void evaluateJavascript(String script, ValueCallback<String> resultCallback) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "evaluateJavascript=" + script);
mProvider.evaluateJavaScript(script, resultCallback);
}
@@ -878,6 +899,7 @@
*/
public void saveWebArchive(String filename) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive=" + filename);
mProvider.saveWebArchive(filename);
}
@@ -895,6 +917,7 @@
*/
public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "saveWebArchive(auto)=" + basename);
mProvider.saveWebArchive(basename, autoname, callback);
}
@@ -903,6 +926,7 @@
*/
public void stopLoading() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "stopLoading");
mProvider.stopLoading();
}
@@ -911,6 +935,7 @@
*/
public void reload() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "reload");
mProvider.reload();
}
@@ -929,6 +954,7 @@
*/
public void goBack() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBack");
mProvider.goBack();
}
@@ -947,6 +973,7 @@
*/
public void goForward() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goForward");
mProvider.goForward();
}
@@ -972,6 +999,7 @@
*/
public void goBackOrForward(int steps) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "goBackOrForwad=" + steps);
mProvider.goBackOrForward(steps);
}
@@ -991,6 +1019,7 @@
*/
public boolean pageUp(boolean top) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageUp");
return mProvider.pageUp(top);
}
@@ -1002,6 +1031,7 @@
*/
public boolean pageDown(boolean bottom) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pageDown");
return mProvider.pageDown(bottom);
}
@@ -1014,6 +1044,7 @@
@Deprecated
public void clearView() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearView");
mProvider.clearView();
}
@@ -1033,6 +1064,7 @@
*/
public Picture capturePicture() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "capturePicture");
return mProvider.capturePicture();
}
@@ -1040,7 +1072,9 @@
* Exports the contents of this Webview as PDF. Only supported for API levels
* {@link android.os.Build.VERSION_CODES#KEY_LIME_PIE} and above.
*
- * @param out The stream to export the PDF contents to. Cannot be null.
+ * TODO(sgurun) the parameter list is stale. Fix it before unhiding.
+ *
+ * @param fd The FileDescriptor to export the PDF contents to. Cannot be null.
* @param width The page width. Should be larger than 0.
* @param height The page height. Should be larger than 0.
* @param resultCallback A callback to be invoked when the PDF content is exported.
@@ -1049,21 +1083,27 @@
* be null.
*
* The PDF conversion is done asynchronously and the PDF output is written to the provided
- * outputstream. The caller should not close the outputstream until the resultCallback is
- * called, indicating PDF conversion is complete. Webview cannot be drawn during the pdf
- * export so the application is recommended to take it offscreen, or putting in a layer
- * with an overlaid progress UI / spinner.
+ * file descriptor. The caller should not close the file descriptor until the resultCallback
+ * is called, indicating PDF conversion is complete. Webview will never close the file
+ * descriptor.
+ * Limitations: Webview cannot be drawn during the PDF export so the application is
+ * recommended to take it offscreen, or putting in a layer with an overlaid progress
+ * UI / spinner.
*
* If the caller cancels the task using the cancellationSignal, the cancellation will be
* acked using the resultCallback signal.
*
+ * Throws an exception if an IO error occurs accessing the file descriptor.
+ *
* TODO(sgurun) margins, explain the units, make it public.
* @hide
*/
- public void exportToPdf(OutputStream out, int width, int height,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal) {
+ public void exportToPdf(ParcelFileDescriptor fd, PrintAttributes attributes,
+ ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
+ throws java.io.IOException {
checkThread();
- mProvider.exportToPdf(out, width, height, resultCallback, cancellationSignal);
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "exportToPdf");
+ mProvider.exportToPdf(fd, attributes, resultCallback, cancellationSignal);
}
/**
@@ -1094,6 +1134,7 @@
*/
public void setInitialScale(int scaleInPercent) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setInitialScale=" + scaleInPercent);
mProvider.setInitialScale(scaleInPercent);
}
@@ -1104,6 +1145,7 @@
*/
public void invokeZoomPicker() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "invokeZoomPicker");
mProvider.invokeZoomPicker();
}
@@ -1127,6 +1169,7 @@
*/
public HitTestResult getHitTestResult() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "getHitTestResult");
return mProvider.getHitTestResult();
}
@@ -1145,6 +1188,7 @@
*/
public void requestFocusNodeHref(Message hrefMsg) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestFocusNodeHref");
mProvider.requestFocusNodeHref(hrefMsg);
}
@@ -1157,6 +1201,7 @@
*/
public void requestImageRef(Message msg) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "requestImageRef");
mProvider.requestImageRef(msg);
}
@@ -1261,6 +1306,7 @@
*/
public void pauseTimers() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "pauseTimers");
mProvider.pauseTimers();
}
@@ -1270,6 +1316,7 @@
*/
public void resumeTimers() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "resumeTimers");
mProvider.resumeTimers();
}
@@ -1282,6 +1329,7 @@
*/
public void onPause() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onPause");
mProvider.onPause();
}
@@ -1290,6 +1338,7 @@
*/
public void onResume() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "onResume");
mProvider.onResume();
}
@@ -1309,6 +1358,7 @@
*/
public void freeMemory() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "freeMemory");
mProvider.freeMemory();
}
@@ -1320,6 +1370,7 @@
*/
public void clearCache(boolean includeDiskFiles) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearCache");
mProvider.clearCache(includeDiskFiles);
}
@@ -1331,6 +1382,7 @@
*/
public void clearFormData() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearFormData");
mProvider.clearFormData();
}
@@ -1339,6 +1391,7 @@
*/
public void clearHistory() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearHistory");
mProvider.clearHistory();
}
@@ -1348,6 +1401,7 @@
*/
public void clearSslPreferences() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearSslPreferences");
mProvider.clearSslPreferences();
}
@@ -1389,6 +1443,7 @@
*/
public void findNext(boolean forward) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findNext");
mProvider.findNext(forward);
}
@@ -1404,6 +1459,7 @@
@Deprecated
public int findAll(String find) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAll");
StrictMode.noteSlowCall("findAll blocks UI: prefer findAllAsync");
return mProvider.findAll(find);
}
@@ -1418,6 +1474,7 @@
*/
public void findAllAsync(String find) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "findAllAsync");
mProvider.findAllAsync(find);
}
@@ -1438,6 +1495,7 @@
@Deprecated
public boolean showFindDialog(String text, boolean showIme) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "showFindDialog");
return mProvider.showFindDialog(text, showIme);
}
@@ -1473,6 +1531,7 @@
*/
public void clearMatches() {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "clearMatches");
mProvider.clearMatches();
}
@@ -1533,6 +1592,7 @@
@Deprecated
public void setPictureListener(PictureListener listener) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "setPictureListener=" + listener);
mProvider.setPictureListener(listener);
}
@@ -1582,6 +1642,7 @@
*/
public void addJavascriptInterface(Object object, String name) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "addJavascriptInterface=" + name);
mProvider.addJavascriptInterface(object, name);
}
@@ -1594,6 +1655,7 @@
*/
public void removeJavascriptInterface(String name) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "removeJavascriptInterface=" + name);
mProvider.removeJavascriptInterface(name);
}
@@ -1683,6 +1745,7 @@
public void flingScroll(int vx, int vy) {
checkThread();
+ if (DebugFlags.TRACE_API) Log.d(LOGTAG, "flingScroll");
mProvider.flingScroll(vx, vy);
}
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index db98d30..3f22d53 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -62,6 +62,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
+import android.print.PrintAttributes;
import android.security.KeyChain;
import android.text.Editable;
import android.text.InputType;
@@ -2896,11 +2897,11 @@
* See {@link WebView#exportToPdf()}
*/
@Override
- public void exportToPdf(java.io.OutputStream out, int width, int height,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal) {
+ public void exportToPdf(android.os.ParcelFileDescriptor fd, PrintAttributes attributes,
+ ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
+ throws java.io.IOException {
// K-only API not implemented in WebViewClassic.
throw new IllegalStateException("This API not supported on Android 4.3 and earlier");
-
}
/**
@@ -7950,6 +7951,7 @@
// triggered in setNewPicture
Picture picture = mContext.getApplicationInfo().targetSdkVersion <
Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+ if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
mPictureListener.onNewPicture(getWebView(), picture);
}
}
@@ -8037,6 +8039,7 @@
// triggered in pageSwapCallback
Picture picture = mContext.getApplicationInfo().targetSdkVersion <
Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
+ if (DebugFlags.TRACE_CALLBACK) Log.d(CallbackProxy.LOGTAG, "onNewPicture");
mPictureListener.onNewPicture(getWebView(), picture);
}
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index 8fe6edf..d625d8a 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -27,6 +27,8 @@
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.print.PrintAttributes;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -41,7 +43,6 @@
import java.io.BufferedWriter;
import java.io.File;
-import java.io.OutputStream;
import java.util.Map;
/**
@@ -148,8 +149,9 @@
public Picture capturePicture();
- public void exportToPdf(OutputStream out, int width, int height,
- ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal);
+ public void exportToPdf(ParcelFileDescriptor fd, PrintAttributes attributes,
+ ValueCallback<Boolean> resultCallback, CancellationSignal cancellationSignal)
+ throws java.io.IOException;
public float getScale();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index be47bf0..c308024 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4924,11 +4924,37 @@
* Scrolls the list items within the view by a specified number of pixels.
*
* @param y the amount of pixels to scroll by vertically
- * @return true if the list is able to scroll, or false if the list is
- * already at the beginning/end and unable to scroll any more.
+ * @see #canScrollList(int)
*/
- public boolean scrollListBy(int y) {
- return !trackMotionScroll(-y, -y);
+ public void scrollListBy(int y) {
+ trackMotionScroll(-y, -y);
+ }
+
+ /**
+ * Check if the items in the list can be scrolled in a certain direction.
+ *
+ * @param direction Negative to check scrolling up, positive to check
+ * scrolling down.
+ * @return true if the list can be scrolled in the specified direction,
+ * false otherwise.
+ * @see #scrollListBy(int)
+ */
+ public boolean canScrollList(int direction) {
+ final int childCount = getChildCount();
+ if (childCount == 0) {
+ return false;
+ }
+
+ final int firstPosition = mFirstPosition;
+ final Rect listPadding = mListPadding;
+ if (direction > 0) {
+ final int lastBottom = getChildAt(childCount - 1).getBottom();
+ final int lastPosition = firstPosition + childCount;
+ return lastPosition < mItemCount || lastBottom > getHeight() - listPadding.bottom;
+ } else {
+ final int firstTop = getChildAt(0).getTop();
+ return firstPosition > 0 || firstTop < listPadding.top;
+ }
}
/**
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 778c8db..dff1531 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -29,12 +29,14 @@
import android.util.AttributeSet;
import android.view.ActionProvider;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ActivityChooserModel.ActivityChooserModelClient;
+import android.widget.ListPopupWindow.ForwardingListener;
/**
* This class is a view for choosing an activity for handling a given {@link Intent}.
@@ -228,17 +230,37 @@
mDefaultActivityButton.setOnLongClickListener(mCallbacks);
mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
- mExpandActivityOverflowButton = (FrameLayout) findViewById(R.id.expand_activities_button);
- mExpandActivityOverflowButton.setOnClickListener(mCallbacks);
- mExpandActivityOverflowButton.setAccessibilityDelegate(new AccessibilityDelegate() {
+ final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
+ expandButton.setOnClickListener(mCallbacks);
+ expandButton.setAccessibilityDelegate(new AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.setCanOpenPopup(true);
}
});
+ expandButton.setOnTouchListener(new ForwardingListener(expandButton) {
+ @Override
+ public ListPopupWindow getPopup() {
+ return getListPopupWindow();
+ }
+
+ @Override
+ protected boolean onForwardingStarted() {
+ showPopup();
+ return true;
+ }
+
+ @Override
+ protected boolean onForwardingStopped() {
+ dismissPopup();
+ return true;
+ }
+ });
+ mExpandActivityOverflowButton = expandButton;
+
mExpandActivityOverflowButtonImage =
- (ImageView) mExpandActivityOverflowButton.findViewById(R.id.image);
+ (ImageView) expandButton.findViewById(R.id.image);
mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
mAdapter = new ActivityChooserViewAdapter();
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index f2da765..b7e1fdd 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -974,10 +974,12 @@
* currently touched list item.
* <p>
* Example usage:
- * <pre>ListPopupWindow myPopup = new ListPopupWindow(context);
+ * <pre>
+ * ListPopupWindow myPopup = new ListPopupWindow(context);
* myPopup.setAnchor(myAnchor);
* OnTouchListener dragListener = myPopup.createDragToOpenListener(myAnchor);
- * myAnchor.setOnTouchListener(dragListener);</pre>
+ * myAnchor.setOnTouchListener(dragListener);
+ * </pre>
*
* @param src the view on which the resulting listener will be set
* @return a touch listener that controls drag-to-open behavior
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index e5344c6..603db70 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -82,8 +82,10 @@
* currently touched list item.
* <p>
* Example usage:
- * <pre>PopupMenu myPopup = new PopupMenu(context, myAnchor);
- * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());</pre>
+ * <pre>
+ * PopupMenu myPopup = new PopupMenu(context, myAnchor);
+ * myAnchor.setOnTouchListener(myPopup.getDragToOpenListener());
+ * </pre>
*
* @return a touch listener that controls drag-to-open behavior
*/
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index ebf9fe0..0ddc131 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -21,12 +21,14 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.media.AudioManager;
+import android.media.MediaFormat;
import android.media.MediaPlayer;
-import android.media.Metadata;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
+import android.media.Metadata;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
@@ -40,7 +42,10 @@
import android.widget.MediaController.MediaPlayerControl;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Map;
+import java.util.Vector;
/**
* Displays a video file. The VideoView class
@@ -91,6 +96,15 @@
private boolean mCanSeekBack;
private boolean mCanSeekForward;
+ /** List of views overlaid on top of the video. */
+ private ArrayList<View> mOverlays;
+
+ /**
+ * Listener for overlay layout changes. Invalidates the video view to ensure
+ * that captions are redrawn whenever their layout changes.
+ */
+ private OnLayoutChangeListener mOverlayLayoutListener;
+
public VideoView(Context context) {
super(context);
initVideoView();
@@ -194,6 +208,7 @@
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
+ mPendingSubtitleTracks = 0;
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
}
@@ -218,6 +233,47 @@
invalidate();
}
+ /**
+ * Adds an external subtitle source file (from the provided input stream.)
+ *
+ * Note that a single external subtitle source may contain multiple or no
+ * supported tracks in it. If the source contained at least one track in
+ * it, one will receive an {@link MediaPlayer#MEDIA_INFO_METADATA_UPDATE}
+ * info message. Otherwise, if reading the source takes excessive time,
+ * one will receive a {@link MediaPlayer#MEDIA_INFO_SUBTITLE_TIMED_OUT}
+ * message. If the source contained no supported track (including an empty
+ * source file or null input stream), one will receive a {@link
+ * MediaPlayer#MEDIA_INFO_UNSUPPORTED_SUBTITLE} message. One can find the
+ * total number of available tracks using {@link MediaPlayer#getTrackInfo()}
+ * to see what additional tracks become available after this method call.
+ *
+ * @param is input stream containing the subtitle data. It will be
+ * closed by the media framework.
+ * @param format the format of the subtitle track(s). Must contain at least
+ * the mime type ({@link MediaFormat#KEY_MIME}) and the
+ * language ({@link MediaFormat#KEY_LANGUAGE}) of the file.
+ * If the file itself contains the language information,
+ * specify "und" for the language.
+ */
+ public void addSubtitleSource(InputStream is, MediaFormat format) {
+ // always signal unsupported message for now
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } catch (IOException e) {
+ }
+
+ if (mMediaPlayer == null) {
+ ++mPendingSubtitleTracks;
+ } else {
+ mInfoListener.onInfo(
+ mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ }
+ }
+
+ private int mPendingSubtitleTracks;
+
public void stopPlayback() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
@@ -253,7 +309,7 @@
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
- mMediaPlayer.setOnInfoListener(mOnInfoListener);
+ mMediaPlayer.setOnInfoListener(mInfoListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
@@ -261,6 +317,12 @@
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
+
+ for (int ix = 0; ix < mPendingSubtitleTracks; ix++) {
+ mInfoListener.onInfo(
+ mMediaPlayer, MediaPlayer.MEDIA_INFO_UNSUPPORTED_SUBTITLE, 0);
+ }
+
// we don't set the target state here either, but preserve the
// target state that was there before.
mCurrentState = STATE_PREPARING;
@@ -277,6 +339,8 @@
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
+ } finally {
+ mPendingSubtitleTracks = 0;
}
}
@@ -386,6 +450,16 @@
}
};
+ private MediaPlayer.OnInfoListener mInfoListener =
+ new MediaPlayer.OnInfoListener() {
+ public boolean onInfo(MediaPlayer mp, int arg1, int arg2) {
+ if (mOnInfoListener != null) {
+ mOnInfoListener.onInfo(mp, arg1, arg2);
+ }
+ return true;
+ }
+ };
+
private MediaPlayer.OnErrorListener mErrorListener =
new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
@@ -530,6 +604,7 @@
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
+ mPendingSubtitleTracks = 0;
mCurrentState = STATE_IDLE;
if (cleartargetstate) {
mTargetState = STATE_IDLE;
@@ -702,4 +777,101 @@
}
return mAudioSession;
}
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+
+ // Layout overlay views, if necessary.
+ if (changed && mOverlays != null && !mOverlays.isEmpty()) {
+ measureAndLayoutOverlays();
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ final int count = mOverlays.size();
+ for (int i = 0; i < count; i++) {
+ final View overlay = mOverlays.get(i);
+ overlay.draw(canvas);
+ }
+ }
+
+ /**
+ * Adds a view to be overlaid on top of this video view. During layout, the
+ * view will be forced to match the bounds, less padding, of the video view.
+ * <p>
+ * Overlays are drawn in the order they are added. The last added overlay
+ * will be drawn on top.
+ *
+ * @param overlay the view to overlay
+ * @see #removeOverlay(View)
+ */
+ private void addOverlay(View overlay) {
+ if (mOverlays == null) {
+ mOverlays = new ArrayList<View>(1);
+ }
+
+ if (mOverlayLayoutListener == null) {
+ mOverlayLayoutListener = new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ invalidate();
+ }
+ };
+ }
+
+ if (mOverlays.isEmpty()) {
+ setWillNotDraw(false);
+ }
+
+ mOverlays.add(overlay);
+ overlay.addOnLayoutChangeListener(mOverlayLayoutListener);
+ measureAndLayoutOverlays();
+ }
+
+ /**
+ * Removes a view previously added using {@link #addOverlay}.
+ *
+ * @param overlay the view to remove
+ * @see #addOverlay(View)
+ */
+ private void removeOverlay(View overlay) {
+ if (mOverlays == null) {
+ return;
+ }
+
+ overlay.removeOnLayoutChangeListener(mOverlayLayoutListener);
+ mOverlays.remove(overlay);
+
+ if (mOverlays.isEmpty()) {
+ setWillNotDraw(true);
+ }
+
+ invalidate();
+ }
+
+ /**
+ * Forces a measurement and layout pass for all overlaid views.
+ *
+ * @see #addOverlay(View)
+ */
+ private void measureAndLayoutOverlays() {
+ final int left = getPaddingLeft();
+ final int top = getPaddingTop();
+ final int right = getWidth() - left - getPaddingRight();
+ final int bottom = getHeight() - top - getPaddingBottom();
+ final int widthSpec = MeasureSpec.makeMeasureSpec(right - left, MeasureSpec.EXACTLY);
+ final int heightSpec = MeasureSpec.makeMeasureSpec(bottom - top, MeasureSpec.EXACTLY);
+
+ final int count = mOverlays.size();
+ for (int i = 0; i < count; i++) {
+ final View overlay = mOverlays.get(i);
+ overlay.measure(widthSpec, heightSpec);
+ overlay.layout(left, top, right, bottom);
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index ac9bf166..16b119a 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -1583,7 +1583,7 @@
final int NSRVS = pkgState.mServices.size();
if (NPROCS > 0 || NSRVS > 0) {
if (!printedHeader) {
- pw.println("Per-Package Process Stats:");
+ pw.println("Per-Package Stats:");
printedHeader = true;
}
pw.print(" * "); pw.print(pkgName); pw.print(" / ");
@@ -1651,7 +1651,8 @@
continue;
}
if (!printedHeader) {
- pw.println("Process Stats:");
+ pw.println();
+ pw.println("Per-Process Stats:");
printedHeader = true;
}
pw.print(" * "); pw.print(procName); pw.print(" / ");
@@ -2536,7 +2537,8 @@
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = started ? memFactor : STATE_NOTHING;
+ final boolean wasStarted = mStartedState != STATE_NOTHING;
+ final int state = started ? memFactor : STATE_NOTHING;
if (mStartedState != state) {
if (mStartedState != STATE_NOTHING) {
addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT),
@@ -2546,8 +2548,8 @@
}
mStartedState = state;
mStartedStartTime = now;
- if (mProc != null) {
- mProc = mProc.pullFixedProc(mPackage);
+ mProc = mProc.pullFixedProc(mPackage);
+ if (wasStarted != started) {
if (started) {
mProc.incStartedServices(memFactor, now);
} else {
@@ -2561,7 +2563,7 @@
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = bound ? memFactor : STATE_NOTHING;
+ final int state = bound ? memFactor : STATE_NOTHING;
if (mBoundState != state) {
if (mBoundState != STATE_NOTHING) {
addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT),
@@ -2578,7 +2580,7 @@
if (mActive <= 0) {
throw new IllegalStateException("Service " + this + " has mActive=" + mActive);
}
- int state = executing ? memFactor : STATE_NOTHING;
+ final int state = executing ? memFactor : STATE_NOTHING;
if (mExecState != state) {
if (mExecState != STATE_NOTHING) {
addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ab81a37..8819237 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -287,102 +287,104 @@
}
protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
- // Build a reasonable intent filter, based on what matched.
- IntentFilter filter = new IntentFilter();
+ if (mAlwaysUseOption) {
+ // Build a reasonable intent filter, based on what matched.
+ IntentFilter filter = new IntentFilter();
- if (intent.getAction() != null) {
- filter.addAction(intent.getAction());
- }
- Set<String> categories = intent.getCategories();
- if (categories != null) {
- for (String cat : categories) {
- filter.addCategory(cat);
+ if (intent.getAction() != null) {
+ filter.addAction(intent.getAction());
}
- }
- filter.addCategory(Intent.CATEGORY_DEFAULT);
-
- int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
- Uri data = intent.getData();
- if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
- String mimeType = intent.resolveType(this);
- if (mimeType != null) {
- try {
- filter.addDataType(mimeType);
- } catch (IntentFilter.MalformedMimeTypeException e) {
- Log.w("ResolverActivity", e);
- filter = null;
+ Set<String> categories = intent.getCategories();
+ if (categories != null) {
+ for (String cat : categories) {
+ filter.addCategory(cat);
}
}
- }
- if (data != null && data.getScheme() != null) {
- // We need the data specification if there was no type,
- // OR if the scheme is not one of our magical "file:"
- // or "content:" schemes (see IntentFilter for the reason).
- if (cat != IntentFilter.MATCH_CATEGORY_TYPE
- || (!"file".equals(data.getScheme())
- && !"content".equals(data.getScheme()))) {
- filter.addDataScheme(data.getScheme());
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
- // Look through the resolved filter to determine which part
- // of it matched the original Intent.
- Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
- if (pIt != null) {
- String ssp = data.getSchemeSpecificPart();
- while (ssp != null && pIt.hasNext()) {
- PatternMatcher p = pIt.next();
- if (p.match(ssp)) {
- filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
- break;
- }
+ int cat = ri.match&IntentFilter.MATCH_CATEGORY_MASK;
+ Uri data = intent.getData();
+ if (cat == IntentFilter.MATCH_CATEGORY_TYPE) {
+ String mimeType = intent.resolveType(this);
+ if (mimeType != null) {
+ try {
+ filter.addDataType(mimeType);
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ Log.w("ResolverActivity", e);
+ filter = null;
}
}
- Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
- if (aIt != null) {
- while (aIt.hasNext()) {
- IntentFilter.AuthorityEntry a = aIt.next();
- if (a.match(data) >= 0) {
- int port = a.getPort();
- filter.addDataAuthority(a.getHost(),
- port >= 0 ? Integer.toString(port) : null);
- break;
+ }
+ if (data != null && data.getScheme() != null) {
+ // We need the data specification if there was no type,
+ // OR if the scheme is not one of our magical "file:"
+ // or "content:" schemes (see IntentFilter for the reason).
+ if (cat != IntentFilter.MATCH_CATEGORY_TYPE
+ || (!"file".equals(data.getScheme())
+ && !"content".equals(data.getScheme()))) {
+ filter.addDataScheme(data.getScheme());
+
+ // Look through the resolved filter to determine which part
+ // of it matched the original Intent.
+ Iterator<PatternMatcher> pIt = ri.filter.schemeSpecificPartsIterator();
+ if (pIt != null) {
+ String ssp = data.getSchemeSpecificPart();
+ while (ssp != null && pIt.hasNext()) {
+ PatternMatcher p = pIt.next();
+ if (p.match(ssp)) {
+ filter.addDataSchemeSpecificPart(p.getPath(), p.getType());
+ break;
+ }
}
}
- }
- pIt = ri.filter.pathsIterator();
- if (pIt != null) {
- String path = data.getPath();
- while (path != null && pIt.hasNext()) {
- PatternMatcher p = pIt.next();
- if (p.match(path)) {
- filter.addDataPath(p.getPath(), p.getType());
- break;
+ Iterator<IntentFilter.AuthorityEntry> aIt = ri.filter.authoritiesIterator();
+ if (aIt != null) {
+ while (aIt.hasNext()) {
+ IntentFilter.AuthorityEntry a = aIt.next();
+ if (a.match(data) >= 0) {
+ int port = a.getPort();
+ filter.addDataAuthority(a.getHost(),
+ port >= 0 ? Integer.toString(port) : null);
+ break;
+ }
+ }
+ }
+ pIt = ri.filter.pathsIterator();
+ if (pIt != null) {
+ String path = data.getPath();
+ while (path != null && pIt.hasNext()) {
+ PatternMatcher p = pIt.next();
+ if (p.match(path)) {
+ filter.addDataPath(p.getPath(), p.getType());
+ break;
+ }
}
}
}
}
- }
- if (filter != null) {
- final int N = mAdapter.mList.size();
- ComponentName[] set = new ComponentName[N];
- int bestMatch = 0;
- for (int i=0; i<N; i++) {
- ResolveInfo r = mAdapter.mList.get(i).ri;
- set[i] = new ComponentName(r.activityInfo.packageName,
- r.activityInfo.name);
- if (r.match > bestMatch) bestMatch = r.match;
- }
- if (alwaysCheck) {
- getPackageManager().addPreferredActivity(filter, bestMatch, set,
- intent.getComponent());
- } else {
- try {
- AppGlobals.getPackageManager().setLastChosenActivity(intent,
- intent.resolveTypeIfNeeded(getContentResolver()),
- PackageManager.MATCH_DEFAULT_ONLY,
- filter, bestMatch, intent.getComponent());
- } catch (RemoteException re) {
- Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+ if (filter != null) {
+ final int N = mAdapter.mList.size();
+ ComponentName[] set = new ComponentName[N];
+ int bestMatch = 0;
+ for (int i=0; i<N; i++) {
+ ResolveInfo r = mAdapter.mList.get(i).ri;
+ set[i] = new ComponentName(r.activityInfo.packageName,
+ r.activityInfo.name);
+ if (r.match > bestMatch) bestMatch = r.match;
+ }
+ if (alwaysCheck) {
+ getPackageManager().addPreferredActivity(filter, bestMatch, set,
+ intent.getComponent());
+ } else {
+ try {
+ AppGlobals.getPackageManager().setLastChosenActivity(intent,
+ intent.resolveTypeIfNeeded(getContentResolver()),
+ PackageManager.MATCH_DEFAULT_ONLY,
+ filter, bestMatch, intent.getComponent());
+ } catch (RemoteException re) {
+ Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
+ }
}
}
}
diff --git a/core/java/com/android/internal/app/RestrictionsPinActivity.java b/core/java/com/android/internal/app/RestrictionsPinActivity.java
index f8ce108..2112474 100644
--- a/core/java/com/android/internal/app/RestrictionsPinActivity.java
+++ b/core/java/com/android/internal/app/RestrictionsPinActivity.java
@@ -16,9 +16,7 @@
package com.android.internal.app;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.os.Bundle;
import android.os.UserManager;
import android.text.Editable;
@@ -26,7 +24,8 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.WindowManager;
+import android.view.View.OnClickListener;
+import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -38,14 +37,15 @@
* challenge for an existing PIN. The PIN is maintained by UserManager.
*/
public class RestrictionsPinActivity extends AlertActivity
- implements DialogInterface.OnClickListener, TextWatcher, OnEditorActionListener {
+ implements OnClickListener, TextWatcher, OnEditorActionListener {
protected UserManager mUserManager;
protected boolean mHasRestrictionsPin;
protected EditText mPinText;
protected TextView mPinErrorMessage;
- protected TextView mPinMessage;
+ private Button mOkButton;
+ private Button mCancelButton;
@Override
public void onCreate(Bundle icicle) {
@@ -59,19 +59,20 @@
protected void initUi() {
AlertController.AlertParams ap = mAlertParams;
- ap.mTitle = getString(R.string.restr_pin_enter_pin);
- ap.mPositiveButtonText = getString(R.string.ok);
- ap.mNegativeButtonText = getString(R.string.cancel);
- ap.mPositiveButtonListener = this;
- ap.mNegativeButtonListener = this;
+ ap.mTitle = getString(R.string.restr_pin_enter_admin_pin);
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ap.mView = inflater.inflate(R.layout.restrictions_pin_challenge, null);
- mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
- mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
+ mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
+ mOkButton = (Button) ap.mView.findViewById(R.id.pin_ok_button);
+ mCancelButton = (Button) ap.mView.findViewById(R.id.pin_cancel_button);
+
mPinText.addTextChangedListener(this);
+
+ mOkButton.setOnClickListener(this);
+ mCancelButton.setOnClickListener(this);
}
protected boolean verifyingPin() {
@@ -84,8 +85,7 @@
setPositiveButtonState(false);
boolean hasPin = mUserManager.hasRestrictionsPin();
if (hasPin) {
- mPinMessage.setVisibility(View.GONE);
- mPinErrorMessage.setVisibility(View.GONE);
+ mPinErrorMessage.setVisibility(View.INVISIBLE);
mPinText.setOnEditorActionListener(this);
updatePinTimer(-1);
} else if (verifyingPin()) {
@@ -94,39 +94,37 @@
}
}
- private void setPositiveButtonState(boolean enabled) {
- mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
+ protected void setPositiveButtonState(boolean enabled) {
+ mOkButton.setEnabled(enabled);
}
- private void updatePinTimer(int pinTimerMs) {
+ private boolean updatePinTimer(int pinTimerMs) {
if (pinTimerMs < 0) {
pinTimerMs = mUserManager.checkRestrictionsPin(null);
}
+ boolean enableInput;
if (pinTimerMs >= 200) {
- final int seconds = (pinTimerMs + 200) / 1000;
- final String formatString = getResources().getQuantityString(
- R.plurals.restr_pin_countdown,
- seconds);
- mPinErrorMessage.setText(String.format(formatString, seconds));
+ // Do the count down timer for less than a minute, otherwise just say try again later.
+ if (pinTimerMs <= 60000) {
+ final int seconds = (pinTimerMs + 200) / 1000;
+ final String formatString = getResources().getQuantityString(
+ R.plurals.restr_pin_countdown,
+ seconds);
+ mPinErrorMessage.setText(String.format(formatString, seconds));
+ } else {
+ mPinErrorMessage.setText(R.string.restr_pin_try_later);
+ }
+ enableInput = false;
mPinErrorMessage.setVisibility(View.VISIBLE);
- mPinText.setEnabled(false);
mPinText.setText("");
- setPositiveButtonState(false);
mPinText.postDelayed(mCountdownRunnable, Math.min(1000, pinTimerMs));
} else {
- mPinErrorMessage.setVisibility(View.INVISIBLE);
- mPinText.setEnabled(true);
- mPinText.setText("");
+ enableInput = true;
+ mPinErrorMessage.setText(R.string.restr_pin_incorrect);
}
- }
-
- public void onClick(DialogInterface dialog, int which) {
- setResult(RESULT_CANCELED);
- if (which == AlertDialog.BUTTON_POSITIVE) {
- performPositiveButtonAction();
- } else if (which == AlertDialog.BUTTON_NEGATIVE) {
- finish();
- }
+ mPinText.setEnabled(enableInput);
+ setPositiveButtonState(enableInput);
+ return enableInput;
}
protected void performPositiveButtonAction() {
@@ -135,7 +133,10 @@
setResult(RESULT_OK);
finish();
} else if (result >= 0) {
+ mPinErrorMessage.setText(R.string.restr_pin_incorrect);
+ mPinErrorMessage.setVisibility(View.VISIBLE);
updatePinTimer(result);
+ mPinText.setText("");
}
}
@@ -161,7 +162,20 @@
private Runnable mCountdownRunnable = new Runnable() {
public void run() {
- updatePinTimer(-1);
+ if (updatePinTimer(-1)) {
+ // If we are no longer counting down, clear the message.
+ mPinErrorMessage.setVisibility(View.INVISIBLE);
+ }
}
};
+
+ @Override
+ public void onClick(View v) {
+ if (v == mOkButton) {
+ performPositiveButtonAction();
+ } else if (v == mCancelButton) {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java b/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
index 1d09292..f7fc6c6 100644
--- a/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
+++ b/core/java/com/android/internal/app/RestrictionsPinSetupActivity.java
@@ -16,9 +16,7 @@
package com.android.internal.app;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.DialogInterface;
import android.os.UserManager;
import android.text.Editable;
import android.text.TextUtils;
@@ -44,17 +42,13 @@
ap.mTitle = getString(R.string.restr_pin_enter_pin);
ap.mPositiveButtonText = getString(R.string.ok);
ap.mNegativeButtonText = getString(R.string.cancel);
- ap.mPositiveButtonListener = this;
- ap.mNegativeButtonListener = this;
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ap.mView = inflater.inflate(R.layout.restrictions_pin_setup, null);
mPinText = (EditText) ap.mView.findViewById(R.id.pin_text);
- mPinMessage = (TextView) ap.mView.findViewById(R.id.pin_message);
mNewPinText = (EditText) ap.mView.findViewById(R.id.pin_new_text);
mConfirmPinText = (EditText) ap.mView.findViewById(R.id.pin_confirm_text);
- mPinErrorMessage = (TextView) ap.mView.findViewById(R.id.pin_error_message);
mNewPinText.addTextChangedListener(this);
mConfirmPinText.addTextChangedListener(this);
@@ -72,19 +66,7 @@
return false;
}
- private void setPositiveButtonState(boolean enabled) {
- mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(enabled);
- }
-
- public void onClick(DialogInterface dialog, int which) {
- setResult(RESULT_CANCELED);
- if (which == AlertDialog.BUTTON_POSITIVE) {
- performPositiveButtonAction();
- } else if (which == AlertDialog.BUTTON_NEGATIVE) {
- finish();
- }
- }
-
+ @Override
protected void performPositiveButtonAction() {
if (mHasRestrictionsPin) {
int result = mUserManager.checkRestrictionsPin(mPinText.getText().toString());
@@ -115,7 +97,6 @@
boolean showError = !TextUtils.isEmpty(pin1) && !TextUtils.isEmpty(pin2);
// TODO: Check recovery email address as well
setPositiveButtonState(match);
- mPinErrorMessage.setVisibility((match || !showError) ? View.INVISIBLE : View.VISIBLE);
}
@Override
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index c092807..30ca73e 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -35,7 +35,7 @@
import java.util.StringTokenizer;
public class ProcessCpuTracker {
- private static final String TAG = "ProcessStats";
+ private static final String TAG = "ProcessCpuTracker";
private static final boolean DEBUG = false;
private static final boolean localLOGV = DEBUG || false;
diff --git a/core/java/com/android/internal/widget/AutoScrollHelper.java b/core/java/com/android/internal/widget/AutoScrollHelper.java
index 6298e35..afa4103 100644
--- a/core/java/com/android/internal/widget/AutoScrollHelper.java
+++ b/core/java/com/android/internal/widget/AutoScrollHelper.java
@@ -32,7 +32,8 @@
* scrolling to Views.
* <p>
* <b>Note:</b> Implementing classes are responsible for overriding the
- * {@link #onScrollBy} method to scroll the target view. See
+ * {@link #scrollTargetBy}, {@link #canTargetScrollHorizontally}, and
+ * {@link #canTargetScrollVertically} methods. See
* {@link AbsListViewAutoScroller} for an {@link android.widget.AbsListView}
* -specific implementation.
* <p>
@@ -60,12 +61,14 @@
* {@link #setMaximumEdges}. Default value is {@link #NO_MAX}.
* </ul>
* <h1>Scrolling</h1> When automatic scrolling is active, the helper will
- * repeatedly call {@link #onScrollBy} to apply new scrolling offsets.
+ * repeatedly call {@link #scrollTargetBy} to apply new scrolling offsets.
* <p>
* The following scrolling properties may be configured:
* <ul>
* <li>Acceleration ramp-up duration, see {@link #setRampUpDuration}. Default
- * value is 2.5 seconds.
+ * value is 2500 milliseconds.
+ * <li>Acceleration ramp-down duration, see {@link #setRampDownDuration}.
+ * Default value is 500 milliseconds.
* <li>Target velocity relative to view size, see {@link #setRelativeVelocity}.
* Default value is 100% per second for both vertical and horizontal.
* <li>Minimum velocity used to constrain relative velocity, see
@@ -163,25 +166,22 @@
private float[] mMaximumVelocity = new float[] { NO_MAX, NO_MAX };
/** Whether to start activation immediately. */
- private boolean mSkipDelay;
+ private boolean mAlreadyDelayed;
/** Whether to reset the scroller start time on the next animation. */
- private boolean mResetScroller;
+ private boolean mNeedsReset;
- /** Whether the auto-scroller is active. */
- private boolean mActive;
+ /** Whether to send a cancel motion event to the target view. */
+ private boolean mNeedsCancel;
- /** Whether the auto-scroller is scrolling. */
- private boolean mScrolling;
+ /** Whether the auto-scroller is actively scrolling. */
+ private boolean mAnimating;
/** Whether the auto-scroller is enabled. */
private boolean mEnabled;
/** Whether the auto-scroller consumes events when scrolling. */
- private boolean mExclusiveEnabled;
-
- /** Down time of the most recent down touch event. */
- private long mDownTime;
+ private boolean mExclusive;
// Default values.
private static final int DEFAULT_EDGE_TYPE = EDGE_TYPE_INSIDE_EXTEND;
@@ -192,7 +192,7 @@
private static final float DEFAULT_RELATIVE_VELOCITY = 1f;
private static final int DEFAULT_ACTIVATION_DELAY = ViewConfiguration.getTapTimeout();
private static final int DEFAULT_RAMP_UP_DURATION = 2500;
- // TODO: RAMP_DOWN_DURATION of 500ms?
+ private static final int DEFAULT_RAMP_DOWN_DURATION = 500;
/**
* Creates a new helper for scrolling the specified target view.
@@ -220,8 +220,7 @@
setRelativeVelocity(DEFAULT_RELATIVE_VELOCITY, DEFAULT_RELATIVE_VELOCITY);
setActivationDelay(DEFAULT_ACTIVATION_DELAY);
setRampUpDuration(DEFAULT_RAMP_UP_DURATION);
-
- mEnabled = true;
+ setRampDownDuration(DEFAULT_RAMP_DOWN_DURATION);
}
/**
@@ -232,8 +231,8 @@
* @return The scroll helper, which may used to chain setter calls.
*/
public AutoScrollHelper setEnabled(boolean enabled) {
- if (!enabled) {
- stop(true);
+ if (mEnabled && !enabled) {
+ requestStop();
}
mEnabled = enabled;
@@ -255,13 +254,13 @@
* When enabled, {@link #onTouch} will return true if the helper is
* currently scrolling and false otherwise.
*
- * @param enabled True to exclusively handle touch events during scrolling,
+ * @param exclusive True to exclusively handle touch events during scrolling,
* false to allow the target view to receive all touch events.
- * @see #isExclusiveEnabled()
- * @see #onTouch(View, MotionEvent)
+ * @return The scroll helper, which may used to chain setter calls.
*/
- public void setExclusiveEnabled(boolean enabled) {
- mExclusiveEnabled = enabled;
+ public AutoScrollHelper setExclusive(boolean exclusive) {
+ mExclusive = exclusive;
+ return this;
}
/**
@@ -270,10 +269,10 @@
*
* @return True if exclusive handling of touch events during scrolling is
* enabled, false otherwise.
- * @see #setExclusiveEnabled(boolean)
+ * @see #setExclusive(boolean)
*/
- public boolean isExclusiveEnabled() {
- return mExclusiveEnabled;
+ public boolean isExclusive() {
+ return mExclusive;
}
/**
@@ -424,7 +423,22 @@
* @return The scroll helper, which may used to chain setter calls.
*/
public AutoScrollHelper setRampUpDuration(int durationMillis) {
- mScroller.setDuration(durationMillis);
+ mScroller.setRampUpDuration(durationMillis);
+ return this;
+ }
+
+ /**
+ * Sets the amount of time after de-activation of auto-scrolling that is
+ * takes to slow to a stop.
+ * <p>
+ * Specifying a duration greater than zero prevents sudden jumps in
+ * velocity.
+ *
+ * @param durationMillis The ramp-down duration in milliseconds.
+ * @return The scroll helper, which may used to chain setter calls.
+ */
+ public AutoScrollHelper setRampDownDuration(int durationMillis) {
+ mScroller.setRampDownDuration(durationMillis);
return this;
}
@@ -432,7 +446,7 @@
* Handles touch events by activating automatic scrolling, adjusting scroll
* velocity, or stopping.
* <p>
- * If {@link #isExclusiveEnabled()} is false, always returns false so that
+ * If {@link #isExclusive()} is false, always returns false so that
* the host view may handle touch events. Otherwise, returns true when
* automatic scrolling is active and false otherwise.
*/
@@ -445,52 +459,135 @@
final int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
- mDownTime = event.getDownTime();
+ mNeedsCancel = true;
+ mAlreadyDelayed = false;
+ // $FALL-THROUGH$
case MotionEvent.ACTION_MOVE:
- final float xValue = getEdgeValue(mRelativeEdges[HORIZONTAL], v.getWidth(),
- mMaximumEdges[HORIZONTAL], event.getX());
- final float yValue = getEdgeValue(mRelativeEdges[VERTICAL], v.getHeight(),
- mMaximumEdges[VERTICAL], event.getY());
- final float maxVelX = constrain(mRelativeVelocity[HORIZONTAL] * mTarget.getWidth(),
- mMinimumVelocity[HORIZONTAL], mMaximumVelocity[HORIZONTAL]);
- final float maxVelY = constrain(mRelativeVelocity[VERTICAL] * mTarget.getHeight(),
- mMinimumVelocity[VERTICAL], mMaximumVelocity[VERTICAL]);
- mScroller.setTargetVelocity(xValue * maxVelX, yValue * maxVelY);
+ final float xTargetVelocity = computeTargetVelocity(
+ HORIZONTAL, event.getX(), v.getWidth(), mTarget.getWidth());
+ final float yTargetVelocity = computeTargetVelocity(
+ VERTICAL, event.getY(), v.getHeight(), mTarget.getHeight());
+ mScroller.setTargetVelocity(xTargetVelocity, yTargetVelocity);
- if ((xValue != 0 || yValue != 0) && !mActive) {
- mActive = true;
- mResetScroller = true;
- if (mRunnable == null) {
- mRunnable = new AutoScrollRunnable();
- }
- if (mSkipDelay) {
- mTarget.postOnAnimation(mRunnable);
- } else {
- mSkipDelay = true;
- mTarget.postOnAnimationDelayed(mRunnable, mActivationDelay);
- }
+ // If the auto scroller was not previously active, but it should
+ // be, then update the state and start animations.
+ if (!mAnimating && shouldAnimate()) {
+ startAnimating();
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- stop(true);
+ requestStop();
break;
}
- return mExclusiveEnabled && mScrolling;
+ return mExclusive && mAnimating;
}
/**
- * Override this method to scroll the target view by the specified number
- * of pixels.
- * <p>
- * Returns whether the target view was able to scroll the requested amount.
- *
- * @param deltaX The amount to scroll in the X direction, in pixels.
- * @param deltaY The amount to scroll in the Y direction, in pixels.
- * @return true if the target view was able to scroll the requested amount.
+ * @return whether the target is able to scroll in the requested direction
*/
- public abstract boolean onScrollBy(int deltaX, int deltaY);
+ private boolean shouldAnimate() {
+ final ClampedScroller scroller = mScroller;
+ final int verticalDirection = scroller.getVerticalDirection();
+ final int horizontalDirection = scroller.getHorizontalDirection();
+
+ return verticalDirection != 0 && canTargetScrollVertically(verticalDirection)
+ || horizontalDirection != 0 && canTargetScrollHorizontally(horizontalDirection);
+ }
+
+ /**
+ * Starts the scroll animation.
+ */
+ private void startAnimating() {
+ if (mRunnable == null) {
+ mRunnable = new ScrollAnimationRunnable();
+ }
+
+ mAnimating = true;
+ mNeedsReset = true;
+
+ if (!mAlreadyDelayed && mActivationDelay > 0) {
+ mTarget.postOnAnimationDelayed(mRunnable, mActivationDelay);
+ } else {
+ mRunnable.run();
+ }
+
+ // If we start animating again before the user lifts their finger, we
+ // already know it's not a tap and don't need an activation delay.
+ mAlreadyDelayed = true;
+ }
+
+ /**
+ * Requests that the scroll animation slow to a stop. If there is an
+ * activation delay, this may occur between posting the animation and
+ * actually running it.
+ */
+ private void requestStop() {
+ if (mNeedsReset) {
+ // The animation has been posted, but hasn't run yet. Manually
+ // stopping animation will prevent it from running.
+ mAnimating = false;
+ } else {
+ mScroller.requestStop();
+ }
+ }
+
+ private float computeTargetVelocity(
+ int direction, float coordinate, float srcSize, float dstSize) {
+ final float relativeEdge = mRelativeEdges[direction];
+ final float maximumEdge = mMaximumEdges[direction];
+ final float value = getEdgeValue(relativeEdge, srcSize, maximumEdge, coordinate);
+ if (value == 0) {
+ // The edge in this direction is not activated.
+ return 0;
+ }
+
+ final float relativeVelocity = mRelativeVelocity[direction];
+ final float minimumVelocity = mMinimumVelocity[direction];
+ final float maximumVelocity = mMaximumVelocity[direction];
+ final float targetVelocity = relativeVelocity * dstSize;
+
+ // Target velocity is adjusted for interpolated edge position, then
+ // clamped to the minimum and maximum values. Later, this value will be
+ // adjusted for time-based acceleration.
+ if (value > 0) {
+ return constrain(value * targetVelocity, minimumVelocity, maximumVelocity);
+ } else {
+ return -constrain(-value * targetVelocity, minimumVelocity, maximumVelocity);
+ }
+ }
+
+ /**
+ * Override this method to scroll the target view by the specified number of
+ * pixels.
+ *
+ * @param deltaX The number of pixels to scroll by horizontally.
+ * @param deltaY The number of pixels to scroll by vertically.
+ */
+ public abstract void scrollTargetBy(int deltaX, int deltaY);
+
+ /**
+ * Override this method to return whether the target view can be scrolled
+ * horizontally in a certain direction.
+ *
+ * @param direction Negative to check scrolling left, positive to check
+ * scrolling right.
+ * @return true if the target view is able to horizontally scroll in the
+ * specified direction.
+ */
+ public abstract boolean canTargetScrollHorizontally(int direction);
+
+ /**
+ * Override this method to return whether the target view can be scrolled
+ * vertically in a certain direction.
+ *
+ * @param direction Negative to check scrolling up, positive to check
+ * scrolling down.
+ * @return true if the target view is able to vertically scroll in the
+ * specified direction.
+ */
+ public abstract boolean canTargetScrollVertically(int direction);
/**
* Returns the interpolated position of a touch point relative to an edge
@@ -534,7 +631,7 @@
if (current >= 0) {
// Movement up to the edge is scaled.
return 1f - current / leading;
- } else if (mActive && (mEdgeType == EDGE_TYPE_INSIDE_EXTEND)) {
+ } else if (mAnimating && (mEdgeType == EDGE_TYPE_INSIDE_EXTEND)) {
// Movement beyond the edge is always maximum.
return 1f;
}
@@ -551,6 +648,16 @@
return 0;
}
+ private static int constrain(int value, int min, int max) {
+ if (value > max) {
+ return max;
+ } else if (value < min) {
+ return min;
+ } else {
+ return value;
+ }
+ }
+
private static float constrain(float value, float min, float max) {
if (value > max) {
return max;
@@ -562,72 +669,48 @@
}
/**
- * Stops auto-scrolling immediately, optionally reseting the auto-scrolling
- * delay.
- *
- * @param reset Whether to reset the auto-scrolling delay.
- */
- private void stop(boolean reset) {
- mActive = false;
- mScrolling = false;
- mSkipDelay = !reset;
-
- if (mRunnable != null) {
- mTarget.removeCallbacks(mRunnable);
- }
- }
-
- /**
* Sends a {@link MotionEvent#ACTION_CANCEL} event to the target view,
* canceling any ongoing touch events.
*/
private void cancelTargetTouch() {
+ final long eventTime = SystemClock.uptimeMillis();
final MotionEvent cancel = MotionEvent.obtain(
- mDownTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_CANCEL, 0, 0, 0);
- cancel.setAction(MotionEvent.ACTION_CANCEL);
+ eventTime, eventTime, MotionEvent.ACTION_CANCEL, 0, 0, 0);
mTarget.onTouchEvent(cancel);
cancel.recycle();
}
- private class AutoScrollRunnable implements Runnable {
+ private class ScrollAnimationRunnable implements Runnable {
@Override
public void run() {
- if (!mActive) {
+ if (!mAnimating) {
return;
}
- if (mResetScroller) {
- mResetScroller = false;
+ if (mNeedsReset) {
+ mNeedsReset = false;
mScroller.start();
}
- final View target = mTarget;
final ClampedScroller scroller = mScroller;
+ if (scroller.isFinished() || !shouldAnimate()) {
+ mAnimating = false;
+ return;
+ }
+
+ if (mNeedsCancel) {
+ mNeedsCancel = false;
+ cancelTargetTouch();
+ }
+
scroller.computeScrollDelta();
final int deltaX = scroller.getDeltaX();
final int deltaY = scroller.getDeltaY();
- if ((deltaX != 0 || deltaY != 0 || !scroller.isFinished())
- && onScrollBy(deltaX, deltaY)) {
- // Update whether we're actively scrolling.
- final boolean scrolling = (deltaX != 0 || deltaY != 0);
- if (mScrolling != scrolling) {
- mScrolling = scrolling;
+ scrollTargetBy(deltaX, deltaY);
- // If we just started actively scrolling, make sure any down
- // or move events send to the target view are canceled.
- if (mExclusiveEnabled && scrolling) {
- cancelTargetTouch();
- }
- }
-
- // Keep going until the scroller has permanently stopped or the
- // view can't scroll any more. If the user moves their finger
- // again, we'll repost the animation.
- target.postOnAnimation(this);
- } else {
- stop(false);
- }
+ // Keep going until the scroller has permanently stopped.
+ mTarget.postOnAnimation(this);
}
}
@@ -637,27 +720,39 @@
* interpolated 1f value after a specified duration.
*/
private static class ClampedScroller {
- private final Interpolator mInterpolator = new AccelerateInterpolator();
-
- private int mDuration;
+ private int mRampUpDuration;
+ private int mRampDownDuration;
private float mTargetVelocityX;
private float mTargetVelocityY;
private long mStartTime;
+
private long mDeltaTime;
private int mDeltaX;
private int mDeltaY;
+ private long mStopTime;
+ private float mStopValue;
+ private int mEffectiveRampDown;
+
/**
* Creates a new ramp-up scroller that reaches full velocity after a
* specified duration.
*/
public ClampedScroller() {
- reset();
+ mStartTime = Long.MIN_VALUE;
+ mStopTime = -1;
+ mDeltaTime = 0;
+ mDeltaX = 0;
+ mDeltaY = 0;
}
- public void setDuration(int durationMillis) {
- mDuration = durationMillis;
+ public void setRampUpDuration(int durationMillis) {
+ mRampUpDuration = durationMillis;
+ }
+
+ public void setRampDownDuration(int durationMillis) {
+ mRampDownDuration = durationMillis;
}
/**
@@ -665,35 +760,53 @@
*/
public void start() {
mStartTime = AnimationUtils.currentAnimationTimeMillis();
+ mStopTime = -1;
mDeltaTime = mStartTime;
- }
-
- /**
- * Returns whether the scroller is finished, which means that its
- * acceleration is zero.
- *
- * @return Whether the scroller is finished.
- */
- public boolean isFinished() {
- if (mTargetVelocityX == 0 && mTargetVelocityY == 0) {
- return true;
- }
- final long currentTime = AnimationUtils.currentAnimationTimeMillis();
- final long elapsedSinceStart = currentTime - mStartTime;
- return elapsedSinceStart > mDuration;
- }
-
- /**
- * Stops the scroller and resets its values.
- */
- public void reset() {
- mStartTime = -1;
- mDeltaTime = -1;
+ mStopValue = 0.5f;
mDeltaX = 0;
mDeltaY = 0;
}
/**
+ * Stops the scroller at the current animation time.
+ */
+ public void requestStop() {
+ final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ mEffectiveRampDown = constrain((int) (currentTime - mStartTime), 0, mRampDownDuration);
+ mStopValue = getValueAt(currentTime);
+ mStopTime = currentTime;
+ }
+
+ public boolean isFinished() {
+ return mStopTime > 0
+ && AnimationUtils.currentAnimationTimeMillis() > mStopTime + mEffectiveRampDown;
+ }
+
+ private float getValueAt(long currentTime) {
+ if (currentTime < mStartTime) {
+ return 0f;
+ } else if (mStopTime < 0 || currentTime < mStopTime) {
+ final long elapsedSinceStart = currentTime - mStartTime;
+ return 0.5f * constrain(elapsedSinceStart / (float) mRampUpDuration, 0, 1);
+ } else {
+ final long elapsedSinceEnd = currentTime - mStopTime;
+ return (1 - mStopValue) + mStopValue
+ * constrain(elapsedSinceEnd / (float) mEffectiveRampDown, 0, 1);
+ }
+ }
+
+ /**
+ * Interpolates the value along a parabolic curve corresponding to the equation
+ * <code>y = -4x * (x-1)</code>.
+ *
+ * @param value The value to interpolate, between 0 and 1.
+ * @return the interpolated value, between 0 and 1.
+ */
+ private float interpolateValue(float value) {
+ return -4 * value * value + 4 * value;
+ }
+
+ /**
* Computes the current scroll deltas. This usually only be called after
* starting the scroller with {@link #start()}.
*
@@ -701,18 +814,13 @@
* @see #getDeltaY()
*/
public void computeScrollDelta() {
- final long currentTime = AnimationUtils.currentAnimationTimeMillis();
- final long elapsedSinceStart = currentTime - mStartTime;
- final float value;
- if (mStartTime < 0) {
- value = 0f;
- } else if (elapsedSinceStart < mDuration) {
- value = (float) elapsedSinceStart / mDuration;
- } else {
- value = 1f;
+ if (mDeltaTime == 0) {
+ throw new RuntimeException("Cannot compute scroll delta before calling start()");
}
- final float scale = mInterpolator.getInterpolation(value);
+ final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+ final float value = getValueAt(currentTime);
+ final float scale = interpolateValue(value);
final long elapsedSinceDelta = currentTime - mDeltaTime;
mDeltaTime = currentTime;
@@ -731,6 +839,14 @@
mTargetVelocityY = y;
}
+ public int getHorizontalDirection() {
+ return (int) (mTargetVelocityX / Math.abs(mTargetVelocityX));
+ }
+
+ public int getVerticalDirection() {
+ return (int) (mTargetVelocityY / Math.abs(mTargetVelocityY));
+ }
+
/**
* The distance traveled in the X-coordinate computed by the last call
* to {@link #computeScrollDelta()}.
@@ -749,20 +865,60 @@
}
/**
- * Implementation of {@link AutoScrollHelper} that knows how to scroll
- * generic {@link AbsListView}s.
+ * An implementation of {@link AutoScrollHelper} that knows how to scroll
+ * through an {@link AbsListView}.
*/
public static class AbsListViewAutoScroller extends AutoScrollHelper {
private final AbsListView mTarget;
public AbsListViewAutoScroller(AbsListView target) {
super(target);
+
mTarget = target;
}
@Override
- public boolean onScrollBy(int deltaX, int deltaY) {
- return mTarget.scrollListBy(deltaY);
+ public void scrollTargetBy(int deltaX, int deltaY) {
+ mTarget.scrollListBy(deltaY);
+ }
+
+ @Override
+ public boolean canTargetScrollHorizontally(int direction) {
+ // List do not scroll horizontally.
+ return false;
+ }
+
+ @Override
+ public boolean canTargetScrollVertically(int direction) {
+ final AbsListView target = mTarget;
+ final int itemCount = target.getCount();
+ final int childCount = target.getChildCount();
+ final int firstPosition = target.getFirstVisiblePosition();
+ final int lastPosition = firstPosition + childCount;
+
+ if (direction > 0) {
+ // Are we already showing the entire last item?
+ if (lastPosition >= itemCount) {
+ final View lastView = target.getChildAt(childCount - 1);
+ if (lastView.getBottom() <= target.getHeight()) {
+ return false;
+ }
+ }
+ } else if (direction < 0) {
+ // Are we already showing the entire first item?
+ if (firstPosition <= 0) {
+ final View firstView = target.getChildAt(0);
+ if (firstView.getTop() >= 0) {
+ return false;
+ }
+ }
+ } else {
+ // The behavior for direction 0 is undefined and we can return
+ // whatever we want.
+ return false;
+ }
+
+ return true;
}
}
}
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 6646579..ee47ac4 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -141,7 +141,7 @@
jboolean isShareable) {
jobject brd = NULL;
// for now we don't allow shareable with java inputstreams
- SkStream* stream = CopyJavaInputStream(env, is, storage);
+ SkStreamRewindable* stream = CopyJavaInputStream(env, is, storage);
if (stream) {
brd = createBitmapRegionDecoder(env, stream);
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index 797d155..d264392 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -159,8 +159,8 @@
friend class RewindableJavaStream;
};
-SkStream* WrapJavaInputStream(JNIEnv* env, jobject stream,
- jbyteArray storage) {
+SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream,
+ jbyteArray storage) {
static bool gInited;
if (!gInited) {
@@ -190,6 +190,7 @@
return new JavaInputStreamAdaptor(env, stream, storage);
}
+
static SkMemoryStream* adaptor_to_mem_stream(SkStream* adaptor) {
SkASSERT(adaptor != NULL);
SkDynamicMemoryWStream wStream;
@@ -203,9 +204,9 @@
return new SkMemoryStream(data.get());
}
-SkMemoryStream* CopyJavaInputStream(JNIEnv* env, jobject stream,
- jbyteArray storage) {
- SkAutoTUnref<SkStream> adaptor(WrapJavaInputStream(env, stream, storage));
+SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
+ jbyteArray storage) {
+ SkAutoTUnref<SkStream> adaptor(CreateJavaInputStreamAdaptor(env, stream, storage));
if (NULL == adaptor.get()) {
return NULL;
}
@@ -302,7 +303,7 @@
SkStreamRewindable* GetRewindableStream(JNIEnv* env, jobject stream,
jbyteArray storage) {
- SkAutoTUnref<SkStream> adaptor(WrapJavaInputStream(env, stream, storage));
+ SkAutoTUnref<SkStream> adaptor(CreateJavaInputStreamAdaptor(env, stream, storage));
if (NULL == adaptor.get()) {
return NULL;
}
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
index 5218dc5..fcc0c9a 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.h
@@ -24,8 +24,8 @@
* function returns, since the Java InputStream is not managed
* by the SkStream.
*/
-SkStream* WrapJavaInputStream(JNIEnv* env, jobject stream,
- jbyteArray storage);
+SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream,
+ jbyteArray storage);
/**
* Copy a Java InputStream.
@@ -33,13 +33,11 @@
* @param stream Pointer to Java InputStream.
* @param storage Java byte array for retrieving data from the
* Java InputStream.
- * @return SkMemoryStream The data in stream will be copied to a new
- * SkMemoryStream.
- * FIXME: Could return a more generic return type if ViewStateSerializer
- * did not require an SkMemoryStream.
+ * @return SkStreamRewindable The data in stream will be copied
+ * to a new SkStreamRewindable.
*/
-SkMemoryStream* CopyJavaInputStream(JNIEnv* env, jobject stream,
- jbyteArray storage);
+SkStreamRewindable* CopyJavaInputStream(JNIEnv* env, jobject stream,
+ jbyteArray storage);
/**
* Get a rewindable stream from a Java InputStream.
@@ -50,7 +48,7 @@
* @return SkStreamRewindable Either a wrapper around the Java
* InputStream, if possible, or a copy which is rewindable.
* Since it may be a wrapper, must not be used after the
- * caller returns, like the result of WrapJavaInputStream.
+ * caller returns, like the result of CreateJavaInputStreamAdaptor.
*/
SkStreamRewindable* GetRewindableStream(JNIEnv* env, jobject stream,
jbyteArray storage);
@@ -69,5 +67,4 @@
SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream,
jbyteArray storage);
-
#endif
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 527aee4..40e0731 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -764,8 +764,6 @@
static void doTextBounds(JNIEnv* env, const jchar* text, int count,
jobject bounds, const SkPaint& paint, jint bidiFlags) {
SkRect r;
- r.set(0,0,0,0);
-
SkIRect ir;
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index dff2b18..fcf22b8 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -39,9 +39,10 @@
static SkPicture* deserialize(JNIEnv* env, jobject, jobject jstream,
jbyteArray jstorage) {
SkPicture* picture = NULL;
- SkAutoTUnref<SkStream> strm(WrapJavaInputStream(env, jstream, jstorage));
- if (strm.get()) {
- picture = SkPicture::CreateFromStream(strm.get());
+ SkStream* strm = CreateJavaInputStreamAdaptor(env, jstream, jstorage);
+ if (strm) {
+ picture = SkPicture::CreateFromStream(strm);
+ delete strm;
}
return picture;
}
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index ae0113b..4290a6e 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -31,6 +31,7 @@
static struct {
jclass clazz;
jmethodID dispatchSensorEvent;
+ jmethodID dispatchFlushCompleteEvent;
} gBaseEventQueueClassInfo;
namespace android {
@@ -46,6 +47,8 @@
jfieldID resolution;
jfieldID power;
jfieldID minDelay;
+ jfieldID fifoReservedEventCount;
+ jfieldID fifoMaxEventCount;
} gSensorOffsets;
@@ -67,6 +70,9 @@
sensorOffsets.resolution = _env->GetFieldID(sensorClass, "mResolution","F");
sensorOffsets.power = _env->GetFieldID(sensorClass, "mPower", "F");
sensorOffsets.minDelay = _env->GetFieldID(sensorClass, "mMinDelay", "I");
+ sensorOffsets.fifoReservedEventCount =
+ _env->GetFieldID(sensorClass, "mFifoReservedEventCount", "I");
+ sensorOffsets.fifoMaxEventCount = _env->GetFieldID(sensorClass, "mFifoMaxEventCount", "I");
}
static jint
@@ -78,7 +84,7 @@
size_t count = mgr.getSensorList(&sensorList);
if (size_t(next) >= count)
return -1;
-
+
Sensor const* const list = sensorList[next];
const SensorOffsets& sensorOffsets(gSensorOffsets);
jstring name = env->NewStringUTF(list->getName().string());
@@ -92,7 +98,9 @@
env->SetFloatField(sensor, sensorOffsets.resolution, list->getResolution());
env->SetFloatField(sensor, sensorOffsets.power, list->getPowerUsage());
env->SetIntField(sensor, sensorOffsets.minDelay, list->getMinDelay());
-
+ env->SetIntField(sensor, sensorOffsets.fifoReservedEventCount,
+ list->getFifoReservedEventCount());
+ env->SetIntField(sensor, sensorOffsets.fifoMaxEventCount, list->getFifoMaxEventCount());
next++;
return size_t(next) < count ? next : 0;
}
@@ -150,12 +158,20 @@
env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
}
- env->CallVoidMethod(mReceiverObject,
- gBaseEventQueueClassInfo.dispatchSensorEvent,
- buffer[i].sensor,
- mScratch,
- buffer[i].vector.status,
- buffer[i].timestamp);
+ if (buffer[i].type == SENSOR_TYPE_META_DATA) {
+ // This is a flush complete sensor event. Call dispatchFlushCompleteEvent
+ // method.
+ env->CallVoidMethod(mReceiverObject,
+ gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+ buffer[i].meta_data.sensor);
+ } else {
+ env->CallVoidMethod(mReceiverObject,
+ gBaseEventQueueClassInfo.dispatchSensorEvent,
+ buffer[i].sensor,
+ mScratch,
+ buffer[i].vector.status,
+ buffer[i].timestamp);
+ }
if (env->ExceptionCheck()) {
ALOGE("Exception dispatching input event.");
@@ -186,9 +202,11 @@
return jint(receiver.get());
}
-static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint us) {
+static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle, jint rate_us,
+ jint maxBatchReportLatency, jint reservedFlags) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
- return receiver->getSensorEventQueue()->enableSensor(handle, us);
+ return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
+ reservedFlags);
}
static jint nativeDisableSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
@@ -202,6 +220,10 @@
receiver->decStrong((void*)nativeInitSensorEventQueue);
}
+static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
+ sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
+ return receiver->getSensorEventQueue()->flushSensor(handle);
+}
//----------------------------------------------------------------------------
@@ -221,7 +243,7 @@
(void*)nativeInitSensorEventQueue },
{"nativeEnableSensor",
- "(III)I",
+ "(IIIII)I",
(void*)nativeEnableSensor },
{"nativeDisableSensor",
@@ -231,6 +253,10 @@
{"nativeDestroySensorEventQueue",
"(I)V",
(void*)nativeDestroySensorEventQueue },
+
+ {"nativeFlushSensor",
+ "(II)I",
+ (void*)nativeFlushSensor },
};
}; // namespace android
@@ -260,5 +286,9 @@
gBaseEventQueueClassInfo.clazz,
"dispatchSensorEvent", "(I[FIJ)V");
+ GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchFlushCompleteEvent,
+ gBaseEventQueueClassInfo.clazz,
+ "dispatchFlushCompleteEvent", "(I)V");
+
return 0;
}
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index a3ce2a5..50b3302 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -351,9 +351,9 @@
"Make sure the SurfaceTexture is valid");
return 0;
}
-
+
sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(_env, native_window));
- window = new Surface(producer);
+ window = new Surface(producer, true);
if (window == NULL)
goto not_valid_surface;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9613df3..49945f0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -247,6 +247,7 @@
<protected-broadcast android:name="android.location.GPS_ENABLED_CHANGE" />
<protected-broadcast android:name="android.location.PROVIDERS_CHANGED" />
+ <protected-broadcast android:name="android.location.MODE_CHANGED" />
<protected-broadcast android:name="android.location.GPS_FIX_CHANGE" />
<protected-broadcast android:name="android.net.proxy.PAC_REFRESH" />
diff --git a/core/res/res/drawable-hdpi/stat_sys_secure.png b/core/res/res/drawable-hdpi/stat_sys_secure.png
deleted file mode 100644
index 5e979db..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_secure.png b/core/res/res/drawable-ldpi/stat_sys_secure.png
deleted file mode 100644
index 096aa95..0000000
--- a/core/res/res/drawable-ldpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_secure.png b/core/res/res/drawable-mdpi/stat_sys_secure.png
deleted file mode 100644
index da3e318..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_secure.png b/core/res/res/drawable-xhdpi/stat_sys_secure.png
deleted file mode 100644
index bef2fd7..0000000
--- a/core/res/res/drawable-xhdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_secure.png b/core/res/res/drawable-xxhdpi/stat_sys_secure.png
deleted file mode 100755
index 07c27cb..0000000
--- a/core/res/res/drawable-xxhdpi/stat_sys_secure.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/layout/restrictions_pin_challenge.xml b/core/res/res/layout/restrictions_pin_challenge.xml
index 954af92..f41924c 100644
--- a/core/res/res/layout/restrictions_pin_challenge.xml
+++ b/core/res/res/layout/restrictions_pin_challenge.xml
@@ -18,42 +18,73 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginTop="48dp"
- android:layout_marginBottom="48dp"
android:overScrollMode="ifContentScrolls">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:padding="8dip"
android:orientation="vertical">
-
- <TextView android:id="@+id/pin_message"
- style="?android:attr/textAppearanceMedium"
- android:layout_marginTop="16dp"
- android:layout_marginBottom="16dp"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/restr_pin_create_pin"
- android:textColor="?android:attr/textColorSecondary" />
+ android:padding="8dip"
+ android:orientation="vertical">
- <EditText android:id="@+id/pin_text"
- style="?android:attr/textAppearanceMedium"
- android:layout_marginBottom="16dp"
+ <EditText android:id="@+id/pin_text"
+ android:layout_marginLeft="8dip"
+ android:layout_marginStart="8dip"
+ android:layout_marginRight="8dip"
+ android:layout_marginEnd="8dip"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="numberPassword"
+ android:textColor="?android:attr/textColorPrimary" />
+
+ <TextView android:id="@+id/pin_error_message"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/restr_pin_incorrect"
+ android:gravity="center"/>
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/buttonPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:hint="@string/restr_pin_enter_pin"
- android:inputType="numberPassword"
- android:textColor="?android:attr/textColorPrimary" />
-
- <TextView android:id="@+id/pin_error_message"
- style="?android:attr/textAppearanceSmall"
- android:layout_marginBottom="16dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/restr_pin_error_doesnt_match"
- android:textColor="#FFFF0000" />
-
+ android:minHeight="@dimen/alert_dialog_button_bar_height"
+ android:orientation="vertical"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="beginning"
+ android:dividerPadding="0dip">
+ <LinearLayout
+ style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layoutDirection="locale"
+ android:measureWithLargestChild="true">
+ <Button android:id="@+id/pin_cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_gravity="start"
+ android:layout_weight="1"
+ android:maxLines="2"
+ android:minHeight="@dimen/alert_dialog_button_bar_height"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textSize="14sp"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel" />
+ <Button android:id="@+id/pin_ok_button"
+ android:layout_width="wrap_content"
+ android:layout_gravity="end"
+ android:layout_weight="1"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle"
+ android:textSize="14sp"
+ android:minHeight="@dimen/alert_dialog_button_bar_height"
+ android:layout_height="wrap_content"
+ android:text="@string/ok" />
+ </LinearLayout>
+ </LinearLayout>
</LinearLayout>
-
</ScrollView>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 7abdc6d..575bf55 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Dit laat die houer toe om aan die top-koppelvlak van \'n toeganklikheidsdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"verbind aan \'n drukdiens"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Laat die houer toe om aan die top-koppelvlak van \'n drukdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"kry toegang tot alle druktake"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Gee die houer toegang tot druktake wat deur \'n ander program geskep is. Behoort nooit vir normale programme nodig te wees nie."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"verbind aan \'n drukdatabufferdiens"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Laat die houer toe om aan die top-koppelvlak van \'n drukdatabufferdiens te verbind. Behoort nooit vir gewone programme nodig te wees nie."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"verbind aan NFC-diens"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Laat die houer toe om te verbind aan programme wat NFC-kaarte nastrewe. Behoort nooit vir normale programme nodig te wees nie."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind aan \'n teksdiens"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Gekanselleer"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kon nie inhoud skryf nie"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Voer PIN in"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuwe PIN"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ce827f9..0425180 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ያዢው ወደ የአንድ ተደራሽነት አገልግሎት ከፍተኛ-ደረጃ በይነገጽ እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች መቼም ቢሆን ሊያስፈልግ አይገባም።"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ከአንድ የህትመት አገልግሎት ጋር ማያያዝ"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ያዢው የህትመት አገልግሎቱን ወደ ከፍተኛ-ደረጃ በይነገጽ እንዲጠርዝ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ሁሉንም የህትመት ስራዎችን መድረስ"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ያዢው በሌላ መተግበሪያ የተፈጠሩ የህትመት ስራዎች እንዲደርስባቸው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ከአንድ የህትመት አስተላላፊ አገልግሎት ጋር ይሰሩ"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ያዢው የህትመት አስተላላፊ አገልግሎቱን ከከፍተኛ-ደረጃ በይነገጽ ጋር እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"ከNFC አገልግሎት ጋር ይሰሩ"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"ያዢው የNFC ካርዶችን የሚያስመስሉ መተግበሪያዎችን እንዲያስር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"ለፅሁፍ አገልግሎት አሰረ"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ታብሎይድ"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ተትቷል"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ይዘት መጻፍ ላይ ስህተት"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"አይታወቅም"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"ፒን ያስገቡ"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"የአሁኑ ፒን"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"አዲስ ፒን"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 81b3464..dbd270c 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة إمكانية الدخول. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"الالتزام بخدمة طباعة"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"الدخول إلى جميع وظائف الطباعة"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"للسماح للمالك بالدخول إلى وظائف الطباعة التي أنشأها تطبيق آخر. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"الالتزام بخدمة التخزين المؤقت للطباعة"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة التخزين المؤقت للطباعة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"الربط بخدمة NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"للسماح لحامل البطاقة بالربط بالتطبيقات التي تحاكي بطاقات NFC. لا يتوجب استخدامه على الإطلاق للتطبيقات العادية."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"الالتزام بخدمة إدخال النصوص"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ملغاة"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"حدث خطأ أثناء كتابة المحتوى"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"غير معروف"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"إدخال رقم التعريف الشخصي"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"رقم التعريف الشخصي الحالي"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"رقم التعريف الشخصي الجديد"</string>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 0ae4dda..e6d8c9b 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Sahibə giriş xidmətin ən üst səviyyə interfeysi bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"çap servisini qoşma"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Sahibinə bir çap xidmətinin ən üst səviyə araüzünü bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"bütün çap işlərinə giriş əldə et"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Sahibinə digər tətbiqlər tərəfindən yaradılan çap işlərinə giriş hüququ verir. Normal tətbiqlər üçün tələb olunmamalıdır."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"çap spuler servisinə qoş"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Sahibinə çap spuler xidmətinin ən üst səviyyə interfeysinə bağlamağa imkan verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC xidmətlərinə qoşun"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sahibinə NFC kartlarını emulyasiya edən tətbiqləri bir-birinə qoşmağa icazə verin. Normal tətbiqlər üçün lazım deyil."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"mətn servisini qoşma"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Qısa"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ləğv edildi"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Kontent yazmna xətası"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"naməlum"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN daxil edin"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Cari PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index e04c6e6..d3782e0 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -365,9 +365,9 @@
<skip />
<!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
<skip />
- <!-- no translation found for permlab_accessAllPrintJobs (1120792468465711159) -->
+ <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
<skip />
- <!-- no translation found for permdesc_accessAllPrintJobs (2978185311041864762) -->
+ <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
<skip />
<!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
<skip />
@@ -1637,6 +1637,8 @@
<skip />
<!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
<skip />
+ <!-- no translation found for reason_unknown (6048913880184628119) -->
+ <skip />
<!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
<skip />
<!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 46f211e..3bb818b3 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за достъпност. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"обвързване с услуга за отпечатване"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"достъп до всички задания за отпечатване"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Разрешава на притежателя да осъществява достъп до създадените от друго приложение задания за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"обвързване с услуга за спулер за отпечатване"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за спулер за отпечатване. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"обвързване с услуга за КБП"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Разрешава на притежателя да се обвързва с приложения, които емулират карти за КБП. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"обвързване с текстова услуга"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Анулирано"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при записване на съдържанието"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Въведете ПИН кода"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Текущ ПИН код"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Нов ПИН код"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a6fd663..3d6315f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet vincular amb la interfície de nivell superior d\'un servei d\'accessibilitat. Les aplicacions normals no haurien de necessitar-ho."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"vincula amb un servei d\'impressió"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accedeix a totes les tasques d\'impressió"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet que el propietari accedeixi a les tasques d\'impressió creades per una altra aplicació. Les aplicacions normals no l\'haurien de necessitar mai."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincula amb un servei de gestor de cues d\'impressió"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de gestor de cues d\'impressió. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"vincula al servei NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet que el titular es vinculi a les aplicacions que emulen les targetes de NFC. No hauria de ser mai necessari per a les aplicacions normals."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincula a un servei de text"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancel·lada"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error en escriure el contingut"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"desconegut"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introdueix el PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nou"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 98e1783..0d0e95c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby usnadnění přístupu. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"navázat se na tiskovou službu"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje navázání na nejvyšší úroveň tiskové služby. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"přístup ke všem tiskovým úlohám"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Umožňuje přístup k tiskovým úlohám vytvořeným jinou aplikací. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"navázat se na službu zařazování tisku"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteli navázat se na nejvyšší úroveň služby zařazování tisku. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"navázat se na službu NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteli navázat se na aplikace, které emulují karty NFC. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"navázat se na textovou službu"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušeno"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Při zápisu obsahu došlo k chybě"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"neznámé"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadejte kód PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuální kód PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 5f100cf..36272ab 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at brugeren binder sig til en grænseflade for en tilgængelighedstjeneste på øverste niveau. Bør aldrig være nødvendigt til almindelige apps."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"forbinde til en udskriftstjeneste"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Tillader, at brugeren forbinder til grænsefladen for en udskriftstjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"få adgang til alle udskriftsjob"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Tillader, at brugeren får adgang til udskriftsjob, der er oprettet af en anden app. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"forbinde til en udskriftsspoolertjeneste"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Tillader, at brugeren forbinder til grænsefladen for en udskriftsspoolertjeneste på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"Knyt til NFC-tjeneste"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillader, at indehaveren opretter tilknytninger til applikationer, der efterligner NFC-kort. Dette bør aldrig være nødvendigt for normale apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"forpligte sig til en sms-tjeneste"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Amerikansk \"Tabloid\""</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulleret"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fejl ved skrivning af indhold"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"ukendt"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Indtast pinkode"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuel pinkode:"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkode"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0170f2e..863c2c0 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ermöglicht dem Halter, sich an die Oberfläche einer Bedienungshilfe auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"An einen Druckdienst binden"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druckdienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Auf alle Druckaufträge zugreifen"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ermöglicht dem Inhaber den Zugriff auf von einer anderen App erstellte Druckaufträge. Sollte für normale Apps nie benötigt werden."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"An Druck-Spooler-Dienst binden"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ermöglicht dem Inhaber, sich an die Oberfläche eines Druck-Spooler-Dienstes auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"An NFC-Dienst binden"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ermöglicht dem Inhaber die Bindung an Apps, die NFC-Karten emulieren. Dies sollte für normale Apps niemals notwendig sein."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"An einen Textdienst binden"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Abgebrochen"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fehler beim Schreiben von Inhalten"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"Unbekannt"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN eingeben"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuelle PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Neue PIN"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index b172f2b..be12c74 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανώτατου επιπέδου μιας υπηρεσίας προσβασιμότητας. Δεν απαιτείται σε κανονικές εφαρμογές."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"δέσμευση σε υπηρεσία εκτύπωσης"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης. Δεν απαιτείται για κανονικές εφαρμογές."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"πρόσβαση σε όλες τις εργασίες εκτύπωσης"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Επιτρέπει στον κάτοχο να αποκτά πρόσβαση σε εργασίες εκτύπωσης από άλλες εφαρμογές. Δεν απαιτείται για κανονικές εφαρμογές."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"σύνδεση με μια υπηρεσία εκτύπωσης σε ουράς"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Επιτρέπει στον κάτοχο τη σύνδεση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας εκτύπωσης σε ουρά. Δεν απαιτείται για κανονικές εφαρμογές."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"σύνδεση με υπηρεσία NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Δίνει στον κάτοχο τη δυνατότητα σύνδεσης με εφαρμογές που προσομοιώνουν κάρτες NFC. Δεν ζητείται ποτέ για κανονικές εφαρμογές."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"δέσμευση σε υπηρεσία ανταλλαγής μηνυμάτων"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Ακυρώθηκε"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Σφάλμα κατά την εγγραφή περιεχομένου"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"άγνωστο"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Εισαγωγή PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Ισχύων κωδικός PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Νέος κωδικός PIN"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 63004a8..5b431fd 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"access all print jobs"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Allows the holder to access print jobs created by another app. Should never be needed for normal apps."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 63004a8..5b431fd 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Allows the holder to bind to the top-level interface of an accessibility service. Should never be needed for normal apps."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"bind to a print service"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Allows the holder to bind to the top-level interface of a print service. Should never be needed for normal apps."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"access all print jobs"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Allows the holder to access print jobs created by another app. Should never be needed for normal apps."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bind to a print spooler service"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Allows the holder to bind to the top-level interface of a print spooler service. Should never be needed for normal apps."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"bind to NFC service"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Allows the holder to bind to applications that are emulating NFC cards. Should never be needed for normal apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind to a text service"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelled"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error writing content"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"unknown"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Enter PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Current PIN:"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"New PIN"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b0737e5..ee051db 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a un servicio de impresión"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite al propietario vincularse a la interfaz de nivel superior de un servicio de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acceder a todos los trabajos de impresión"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite al propietario acceder a trabajos de impresión creados con otra aplicación. Las aplicaciones normales no deberían necesitar este permiso."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Vincular a un servicio de administrador de trabajos de impresión"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite al propietario vincularse con la interfaz de nivel superior de un servicio de administrador de trabajos de impresión. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"Vincular con servicio NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite vincular con aplicaciones que emulen tarjetas NFC. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a un servicio de texto"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingresar PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 170abd2..844412d 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite enlazar con la interfaz de nivel superior de un servicio de accesibilidad. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"enlazar con un servicio de impresión"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite enlazar con la interfaz de nivel superior de un servicio de impresión. No debe ser necesario para las aplicaciones normales."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acceder a todos los trabajos de impresión"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite acceder a trabajos de impresión creados con otra aplicación. No debe ser necesario para aplicaciones normales."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"enlazar con un servicio de cola de impresión"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite enlazar con la interfaz de nivel superior de un servicio de cola de impresión. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"enlazar con servicio NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite enlazar con aplicaciones que emulen tarjetas NFC. No debe ser necesario para las aplicaciones normales."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"enlazar con un servicio de texto"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Error al escribir contenido"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"desconocido"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introducir PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN actual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN nuevo"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index b58bf7b..f99f774 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lubab omanikul luua sideme juurdepääsuteenuse ülataseme liidesega. Tavarakenduste puhul ei tohiks seda kunagi vaja minna."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"sidumine printimisteenusega"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lubab omanikul siduda printimisteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"juurdepääs kõikidele printimistöödele"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lubab omanikule juurdepääsu teise rakenduse loodud printimistöödele. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"seo printimise spuulerteenusega"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lubab omanikul siduda printimise spuulerteenuse ülataseme liidesega. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC-teenusega sidumine"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Lubab õiguste omajal luua seosed rakendustega, mis emuleerivad NFC-kaarte. Pole kunagi vajalik tavaliste rakenduste korral."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tekstiteenusega sidumine"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tühistatud"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Viga sisu kirjutamisel"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"teadmata"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Sisestage PIN-kood"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Praegune PIN-kood"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uus PIN-kood"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 65f26aa..0135830 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"به دارنده اجازه میدهد که به رابط سطح بالای سرویس دسترسی متصل شود. هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"اتصال به یک سرویس چاپ"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"به برنامه اجازه میدهد که به رابط سطح بالای سرویس چاپ متصل شود. هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"دسترسی به تمام کارهای چاپ"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"به دارنده اجازه دسترسی به کارهای چاپی ایجاد شده توسط برنامهای دیگر را میدهد.هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"اتصال به سرویس هماهنگکننده چاپ"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"به دارنده اجازه میدهد که به واسط سطح بالای سرویس هماهنگکننده چاپ متصل شود. هرگز برای برنامههای معمولی مورد نیاز نیست."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"اتصال به سرویس NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"به دارنده اجازه میدهد به برنامههایی متصل شود که مشابه با کارتهای NFC عمل میکنند. هرگز نباید برای برنامههای عادی مورد نیاز باشد."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"اتصال به یک سرویس متنی"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"لغو شد"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"خطا هنگام نوشتن محتوا"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"نامعلوم"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"پین را وارد کنید"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"پین کنونی"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"پین جدید"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 524128dc..fd11b88 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Antaa sovelluksen sitoutua esteettömyyspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"Tulostuspalveluun sitoutuminen"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Kaikkien tulostustöiden käyttäminen"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Antaa luvanhaltijan käyttää toisen sovelluksen luomia tulostustöitä. Ei tavallisten sovelluksien käyttöön."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tulostuspalveluun sitoutuminen"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Antaa sovelluksen sitoutua tulostuspalvelun ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"luo sidos NFC-palveluun"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Sallii oikeuden haltijan luoda sidoksia sovelluksiin, jotka jäljittelevät NFC-kortteja. Tämän ei pitäisi olla tarpeen tavallisille sovelluksille."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tekstipalveluun sitoutuminen"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Peruutettu"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Sisällön kirjoittamisessa tapahtui virhe"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"tuntematon"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Anna PIN-koodi"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Nykyinen PIN-koodi"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Uusi PIN-koodi"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 2b48342..051fea1 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"lier à un service d\'impression"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de widget. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accéder à tous les travaux d\'impression"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet à l\'application d\'accéder aux travaux d\'impression créés par une autre application. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service d\'impression désynchronisée"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression désynchronisée. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"s\'associer à un service de texte"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annulé"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de l\'écriture du contenu"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisissez le NIP"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"NIP actuel"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau NIP"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3017dd2..379bc13 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service d\'accessibilité. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"s\'associer à un service d\'impression"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accéder à l\'ensemble des tâches d\'impression"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permet à l\'application autorisée d\'accéder aux tâches d\'impression créées via une autre application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"s\'associer à un service de spouleur d\'impression"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permet à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un service de spouleur d\'impression. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"s\'associer au service NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permet à l\'application autorisée de s\'associer aux applications qui reproduisent le fonctionnement des cartes NFC. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"associer à un service de texte"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloïd"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Tâche annulée."</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erreur lors de la modification du contenu."</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"inconnu"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Saisir le code PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Code PIN actuel"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nouveau code PIN"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 113757b..b88f663d 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"धारक को किसी पहुंच-योग्यता सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"प्रिंट सेवा से आबद्ध करें"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"सभी प्रिंट कार्य एक्सेस करें"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"धारक को अन्य एप्लिकेशन के द्वारा बनाए गए प्रिंट कार्य एक्सेस करने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिंट स्पूलर सेवा से आबद्ध करें"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्तर इंटरफ़ेस से आबद्ध होने देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवा से आबद्ध रहें"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"धारक को ऐसे एप्लिकेशन से आबद्ध रहने देता है जो NFC कार्ड का अनुकरण कर रहे हैं. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"किसी पाठ सेवा पर बने रहें"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"टेबलॉइड"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द कर दी गई"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिखने में त्रुटि"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN डालें"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान पिन"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नया पिन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 9a3c50c..136b704 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Nositelju omogućuje vezanje uz sučelje najviše razine usluge dostupnosti. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"veži se uz uslugu ispisa"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Dopušta nositelju vezanje uza sučelje usluge ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"pristupi svim zadacima ispisa"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Dopušta nositelju pristup zadacima ispisa koje je izradila neka druga aplikacija. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"veži se uz uslugu predmemoriranja ispisa"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Dopušta nositelju vezanje uza sučelje usluge predmemoriranja ispisa najviše razine. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"povezivanje s NFC uslugom"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Omogućuje nositelju povezivanje s aplikacijama koje emuliraju NFC kartice. Nikada ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vezanje na tekstualnu uslugu"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Otkazano"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pogreška prilikom pisanja sadržaja"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"nepoznato"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Unesite PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutačni PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 2ef6d9b..8351c56 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lehetővé teszi a használó számára, hogy csatlakozzon egy kisegítő szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"csatlakozás egy nyomtatási szolgáltatáshoz"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatási szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"hozzáférés valamennyi nyomtatási feladathoz"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lehetővé teszi a használó számára, hogy megtekintsen más alkalmazások által létrehozott nyomtatási feladatokat. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"csatlakozás egy nyomtatásisor-kezelő szolgáltatáshoz"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lehetővé teszi a használó számára, hogy csatlakozzon egy nyomtatásisor-kezelő legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"csatlakozás NFC-szolgáltatáshoz"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Az eszköz kezelője csatlakozhat NFC-kártyákat emuláló alkalmazásokhoz. A normál alkalmazásoknak nincs rá szükségük."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"csatlakozás szövegszolgáltatáshoz"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"„Tabloid” méret"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Törölve"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hiba történt a tartalomírás közben"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"ismeretlen"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN kód megadása"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Jelenlegi PIN kód"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Új PIN kód"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 337027c..232add4 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Թույլ է տալիս սեփականատիրոջը միանալ հասանելիության ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"միանալ տպման ծառայությանը"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Թույլ է տալիս սեփականատիրոջը միանալ տպման ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"մուտքի գործել բոլոր տպման աշխատանքներ"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Թույլ է տալիս սեփականատիրոջը մուտք ունենալ մեկ այլ ծրագրի կողմից ստեղծված տպման աշխատանքներ: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"միանալ տպման կարգավարի ծառայությանը"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Թույլ է տալիս սեփականատիրոջը միանալ տպման կարգավարի ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ անհրաժեշտ չպետք է լինի:"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"կապվել NFC ծառայությանը"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Թույլ է տալիս տիրոջը կապվել ծրագրերին, որոնք օգտագործում են NFC քարտեր: Սովորական ծրագրերի համար երբեք անհրաժեշտ չէ:"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"միանալ տեքստային ծառայությանը"</string>
@@ -1093,8 +1093,8 @@
<string name="no" msgid="5141531044935541497">"Չեղարկել"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Ուշադրություն"</string>
<string name="loading" msgid="7933681260296021180">"Բեռնում..."</string>
- <string name="capital_on" msgid="1544682755514494298">"Միացնել"</string>
- <string name="capital_off" msgid="6815870386972805832">"Անջատել"</string>
+ <string name="capital_on" msgid="1544682755514494298">"I"</string>
+ <string name="capital_off" msgid="6815870386972805832">"O"</string>
<string name="whichApplication" msgid="4533185947064773386">"ավարտել գործողությունը` օգտագործելով"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Օգտագործել լռելյայն այս գործողության համար:"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Մաքրել լռելյայնը Համակարգի կարգավորումներ > Ծրագրեր >Ներբեռնված էջից:"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Չեղարկված է"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Բովանդակության գրելու սխալ"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"անհայտ"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Մուտքագրեք PIN-ը"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Ընթացիկ PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Նոր PIN"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3b9a280..d69e121 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Mengizinkan pemegang untuk mengikat antarmuka tingkat tinggi dari suatu layanan. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"mengikat ke layanan pencetakan"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"mengakses semua tugas pencetakan"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Memungkinkan pemegang mengakses tugas pencetakan yang dibuat oleh aplikasi lain. Tidak pernah diperlukan aplikasi normal."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mengikat ke layanan penampung pencetakan"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Memungkinkan pemegang mengikat antarmuka tingkat tinggi dari layanan penampung pencetakan. Tidak pernah diperlukan oleh aplikasi normal."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"mengikat ke layanan NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Memungkinkan pemegang mengikat ke aplikasi yang meniru kartu NFC. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"mengikat ke layanan SMS"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Terjadi kesalahan saat menulis konten"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"tak diketahui"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Saat Ini"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN Baru"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 1195923..0a1dad1 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di accessibilità. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"collegamento a un servizio di stampa"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio di stampa. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"accesso a tutti i processi di stampa"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Consente al titolare di accedere ai processi di stampa creati da un\'altra app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"collegamento a un servizio spooler di stampa"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un servizio spooler di stampa. Non dovrebbe essere mai necessaria per le normali app."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"associazione a servizio NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Consente al titolare di collegarsi alle applicazioni che emulano carte NFC. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"associazione a un servizio di testo"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Annullato"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Errore nella scrittura dei contenuti"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"sconosciuto"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Inserisci PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN corrente"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nuovo PIN"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5d2b391..ba52642 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"מתיר לבעלים להכפיף לממשק ברמה העליונה של שירות זמינות. הרשאה זו אף פעם אינה אמורה להיות נחוצה ליישומים רגילים."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"איגוד לשירות הדפסה"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ההרשאה הזו מאפשרת לבעלים לבצע איגוד לממשק הרמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"גישה אל כל עבודות ההדפסה"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ההרשאה הזו מאפשרת לבעלים לגשת לעבודות הדפסה שנוצרו על ידי אפליקציה אחרת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"איגוד לשירות הדפסה"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"מאפשרת לבעלים לבצע איגוד לממשק ברמה העליונה של שירות הדפסה. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"איגוד לשירות NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"מאפשרת לבעלים לאגד את האפליקציות המחקות כרטיסיות NFC. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"הכפפה לשירות טקסט"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"בוטלה"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"שגיאה בכתיבת תוכן"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"לא ידוע"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"הזן מספר PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"מספר PIN נוכחי"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"מספר PIN חדש"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b86ba32..7d38f88 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ユーザー補助サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"印刷サービスへのバインド"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"印刷サービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"すべての印刷ジョブへのアクセス"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"別のアプリが作成した印刷ジョブにアクセスすることを所有者に許可します。通常のアプリでは不要です。"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"印刷スプーラサービスへのバインド"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"印刷スプーラサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFCサービスへのバインド"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFCカードをエミュレートしているアプリにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"テキストサービスにバインド"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"タブロイド"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"キャンセルされました"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"コンテンツの書き込み中にエラーが発生しました"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PINを入力"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"現在のPIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新しいPIN"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 43f0be6..b2c1c3d 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"აპს შეეძლება გამარტივებული წვდომის სერვისის ზედა დონის ინტერფეისთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ბეჭდვის სევისზე მიბმა"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"მფლობელს შეეძლება მიებას ბეჭდვის სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ბეჭდვის ყველა დავალებაზე წვდომა"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"საშუალებას აძლევს მფლობელს იქონიოს წვდომა სხვა აპის მიერ შექმნილ ბეჭდვის დავალებებზე. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ბეჭდვის spooler სევისზე მიბმა"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"მფლობელს შეეძლება მიებას ბეჭდვის spooler სერვისების ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC სერვისთან შეკავშირება"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"საშუალებას აძლევს მფლობელს შეკავშირდეს აპლიკაციებთან, რომლებიც NFC ბარათების სიმულაციას ახდენს. ჩვეულებრივ აპებს უმეტეს შემთხვევაში არ დაჭირდება."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"ტექსტ სერვისთან დაკავშირება"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"გაუქმებული"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"შეცდომა კონტენტის ჩაწერისას"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"უცნობი"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"შეიყვანეთ PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ამჟამინდელი PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ახალი PIN"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index fee8e66..4feebe5 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មភាពងាយស្រួល។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ចងសេវាកម្មបោះពុម្ព"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ឲ្យម្ចាស់ចងចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្មធាតុក្រាហ្វិក។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ចូលដំណើរការការងារបោះពុម្ពទាំងអស់"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"អនុញ្ញាតឲ្យម្ចាស់អាចបោះពុម្ពការងារដែលបានបង្កើតដោយកម្មវិធីផ្សេង។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ភ្ជាប់ទៅសេវាកម្ម print spooler"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅចំណុចប្រទាក់កម្រិតកំពូលនៃសេវាកម្ម print spooler ។ មិនគួរទាមទារសម្រាប់កម្មវិធីធម្មតាទេ។"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"ភ្ជាប់ជាមួយសេវាកម្ម NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"អនុញ្ញាតឲ្យភ្ជាប់បញ្ជីជាមួយកម្មវិធីដែលត្រូវបានត្រាប់តាមកាត NFC ។ មិនគួរត្រូវការសម្រាប់កម្មវិធីធម្មតា។"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"ចងសេវាកម្មអត្ថបទ"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"បានបោះបង់"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"កំហុសក្នុងការសរសេរមាតិកា"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"មិនស្គាល់"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"បញ្ចូលកូដ PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"កូដ PIN បច្ចុប្បន្ន"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"កូដ PIN ថ្មី"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 23fbda9..cdbf256 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"권한을 가진 프로그램이 접근성 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"인쇄 서비스 사용"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"권한을 가진 프로그램이 인쇄 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"모든 인쇄 작업에 액세스"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"권한을 가진 프로그램이 다른 앱에서 생성한 인쇄 작업에 액세스하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"인쇄 스풀러 서비스 사용"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"권한을 가진 프로그램이 인쇄 스풀러 서비스에 대한 최상위 인터페이스를 사용하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC 서비스 사용"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"권한을 가진 프로그램이 NFC 카드를 에뮬레이션하는 애플리케이션을 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"텍스트 서비스 연결"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"타블로이드"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"취소됨"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"콘텐츠 작성 중 오류"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"알 수 없음"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN 입력"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"현재 PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"새 PIN"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 37770d4..d55a2c8 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງ ເຊື່ອມໂຍງສ່ວນຕິດຕໍ່ລະດັບເທິງສຸດ ຂອງບໍລິການການເຂົ້າເຖິງ. ແອັບຯທົ່ວໄປບໍ່ຄວນຈຳເປັນຕ້ອງໃຊ້."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"ຜູກມັດກັບການບໍລິການພິມ"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"ເຂົ້າເຖິງວຽກການພິມທັງໝົດ"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງເຂົ້າເຖິງວຽກການພິມທີ່ຖືກສ້າງໂດຍແອັບຯອື່ນ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"ຜູກມັດກັບບໍລິການການພິມແບບ spooler"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"ອະນຸຍາດໃຫ້ເຈົ້າຂອງຜູກກັບສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງການບໍລິການການພິມ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"ເຊື່ອມໂຍງກັບບໍລິການ NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"ອະນຸຍາດໃຫ້ຜູ່ຖືອຸປະກອນໃຫ້ສາມາດເຊື່ອມໂຍງແອັບພລິເຄຊັນ ທີ່ຄ້າຍກັບບັດ NFC. ມັນບໍ່ຈຳເປັນຕ້ອງໃຊ້ໃນແອັບຯທຳມະດາ."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"ເຊື່ອມໂຍງໄປຫາບໍລິການສົ່ງຂໍ້ຄວາມ"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"ແຖບບລອຍ"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ຍົກເລີກແລ້ວ"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ເນື້ອໃນການຂຽນຜິດພາດ"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"ບໍ່ຮູ້ຈັກ"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"ໃສ່ລະຫັດ PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ປະຈຸບັນ"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ລະຫັດ PIN ໃໝ່"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4548ebe..ca810ae 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Savininkui leidžiama susisaistyti su aukščiausio lygio pasiekiamumo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"susisaistyti su spausdinimo paslauga"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Turėtojui leidžiama susisaistyti su spausdinimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"pasiekti visas spausdinimo užduotis"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Turėtojui leidžiama pasiekti spausdinimo užduotis, sukurtas naudojant kitą programą. Įprastoms programoms to neturėtų prireikti."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"susaistyti su spausdinimo kaupimo paslauga"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Turėtojui leidžiama susaistyti programą su spausdinimo kaupimo paslaugos aukščiausio lygio sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"susaistyti su ALR paslauga"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Savininkui leidžiama susaistyti programas, kurios kopijuoja ALR korteles. Neturėtų prireikti įprastoms programoms."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"priskirti teksto paslaugą"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Bulvarinė spauda"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atšaukta"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Klaida rašant turinį"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"nežinoma"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Įveskite PIN kodą"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Dabartinis PIN kodas"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Naujas PIN kodas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index f0314cf..529e763 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ļauj īpašniekam izveidot saiti ar pieejamības pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"Savienojuma izveide ar drukāšanas pakalpojumu"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ļauj īpašniekam izveidot savienojumu ar drukāšanas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Piekļuve visiem drukas darbiem"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ļauj īpašniekam piekļūt drukas darbiem, kas izveidoti citā lietotnē. Parastām lietotnēm tas nekad nav nepieciešams."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"izveidot savienojumu ar drukas spolētāja pakalpojumu"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ļauj īpašniekam izveidot savienojumu ar drukas spolētāja pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"Saistīt ar TDLS pakalpojumu"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ļauj īpašniekam saistīt lietojumprogrammas, kas emulē TDLS kartes. Parastajām lietotnēm šī atļauja nav nepieciešama."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"saistīt ar īsziņu pakalpojumu"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Atcelts"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Rakstot saturu, radās kļūda."</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"nezināms"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ievadiet PIN."</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Pašreizējais PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Jaunais PIN"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 67ec195..25a4f1b 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Эзэмшигч нь хандах үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"хэвлэх үйлчилгээтэй холбох"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"бүх хэвлэх ажилд хандалт хийх"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Эзэмшигчид өөр апп-аас үүсгэсэн хэвлэх ажилд хандалт хийх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"хэвлэгчийн буфер үйлчилгээтэй холбох"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Эзэмшигчид хэвлэх үйлчилгээний дээд-түвшний интерфейстэй холбох боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC үйлчилгээтэй холбох"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Эзэмшигчид NFC картуудыг дуурайлгадаг аппликешнүүдийг холбох боломж олгоно. Энгийн апп-уудад хэзээ ч шаардагдахгүй."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"текст үйлчилгээтэй холбох"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Цуцлагдсан"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Контентыг бичих явцад алдаа гарсан"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"тодорхойгүй"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN оруулна уу"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Одоогийн PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Шинэ PIN"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 9031a79..0088f44 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan yang boleh diakses. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"terikat kepada perkhidmatan cetakan"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"akses semua kerja cetakan"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Membenarkan pemegang mengakses kerja cetakan yang dibuat oleh apl lain. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"terikat kepada perkhidmatan penspul cetakan"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi perkhidmatan penspul cetakan. Tidak sekali-kali diperlukan untuk apl biasa."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"terikat kepada perkhidmatan NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Membenarkan pemegang untuk terikat kepada aplikasi yang mengikut kad NFC. Tidak sekali-kali diperlukan untuk apl normal."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"terikat kepada perkhidmatan teks"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Dibatalkan"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ralat menulis kandungan"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"tidak diketahui"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Masukkan PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN semasa"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN baharu"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3e20e6e..ba81a46 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Gir innehaveren tillatelse til å bindes til det øverste nivået av grensesnittet for en tilgjengelighetstjeneste. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"binding til en utskriftstjeneste"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en utskriftstjeneste. Dette skal ikke være nødvendig for vanlige apper."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"tilgang til alle utskriftsjobber"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Gir innehaveren tillatelse til å åpne utskriftsjobber som er opprettet av andre apper. Dette skal ikke være nødvendig for vanlige apper."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binde til en tjeneste for utskriftskø"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Gir innehaveren tillatelse til å binde til toppnivået av brukergrensesnittet for en tjeneste for utskriftskø. Dette skal ikke være nødvendig for vanlige apper."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"binding til NFC-tjenesten"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Tillater eieren å binde seg til apper som emulerer NFC-kort. Skal aldri være nødvendig for vanlige apper."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"binde til en teksttjeneste"</string>
@@ -415,7 +415,7 @@
<string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige nettbrettfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
<string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Lar appen endre hvorvidt en komponent i en annen app er aktivert eller ikke. Ondsinnede apper kan bruke dette til å deaktivere viktige telefonfunksjoner. Denne tillatelsen må brukes med forsiktighet, ettersom det er mulig å få appkomponenter inn i en ubrukelig, inkonsistent eller ustabil tilstand."</string>
<string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"gi eller trekke tilbake tillatelser"</string>
- <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar programmer gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre programmer. Skadelige programmer kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
+ <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Lar apper gi eller trekke tilbake spesielle tillatelser for eget bruk eller for andre apper. Skadelige apper kan bruke dette for å få tilgang til funksjoner de ikke skal ha tilgang til."</string>
<string name="permlab_setPreferredApplications" msgid="8463181628695396391">"angi foretrukne apper"</string>
<string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Lar appen endre de foretrukne appene dine. Ondsinnede apper kan ubemerket endre apper som kjøres, og forfalske eksisterende apper til å samle private data fra deg."</string>
<string name="permlab_writeSettings" msgid="2226195290955224730">"endre systeminnstillingene"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kansellert"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Feil under skriving av innhold"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"ukjent"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Skriv inn PIN-koden"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Gjeldende PIN-kode:"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny PIN-kode"</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index bd8dece3..e00d0af 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"एक पहुँच सेवाको उच्च स्तरको कुराकानीलाई पक्का गर्नको लागि समाती राख्नेले अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"एउटा प्रिन्ट सेवासँग जोड्नुहोस्"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"एउटा प्रिन्ट सेवाको उच्च स्तरको इन्टरफेसलाई पक्का गर्नको लागि प्रयोगकर्तालाई अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"सबै प्रिन्ट कार्यहरूको पहुँच गर्नुहोस्"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"प्रयोगकर्तालाई अन्य अनुप्रयोगद्वारा निर्मित प्रिन्ट कार्यहरू पहुँच गर्न अनुमति दिन्छ। साधारण अनुप्रयोगहरूलाई कहिल्यै आवश्यक पर्ने छैन।"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिन्ट स्पुलर सेवासँग बाध्नुहोस्"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"प्रिन्ट स्पुलर सेवाको शीर्ष तह इन्टर्फेसलाई बाहकसँग बाँध्न अनुमति दिन्छ। सामान्य अनुप्रयोगलाई कहिल्यै पनि आवाश्यक नपर्न सक्छ।"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC सेवामा बाँध्नुहोस्"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC कार्डहरू इमुलेट गर्ने अनुप्रयोगहरूलाई बाँध्नका लागि होल्डरलाई अनुमति दिन्छ। सामान्य अनुप्रयोगहरूका लागि कहिल्यै पनि आवश्यक पर्दैन।"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"एउटा पाठ सेवासँग संगठित हुनुहोस्"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द गरियो"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामाग्री लेखनमा त्रुटि"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN प्रविष्टि गर्नुहोस्"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"वर्तमान PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"नयाँ PIN"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 20a3f99..1ae4607 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een toegankelijkheidsservice. Nooit vereist voor normale apps."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"koppelen aan een afdrukservice"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukservice. Nooit vereist voor normale apps."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"toegang krijgen tot alle afdruktaken"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Hiermee kan de houder toegang krijgen tot afdruktaken die zijn gemaakt door een andere app. Nooit vereist voor normale apps."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"koppelen aan een afdrukspoolerservice"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Hiermee kan de houder verbinding maken met de hoofdinterface van een afdrukspoolerservice. Nooit vereist voor normale apps."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"koppelen aan NFC-service"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Hiermee kan de houder apps koppelen die NFC-kaarten emuleren. Nooit vereist voor normale apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"koppelen aan een sms-service"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Geannuleerd"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Fout bij schrijven van inhoud"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"onbekend"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Geef de pincode op"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Huidige pincode"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nieuwe pincode"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index d4be6ba..ade7c40 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi ułatwień dostępu. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"tworzenie powiązania z usługą drukowania"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi drukowania. Nieprzeznaczone dla zwykłych aplikacji."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"dostęp do wszystkich zadań drukowania"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Zezwala na dostęp do zadań drukowania utworzonych przez inną aplikację. Nieprzeznaczone dla zwykłych aplikacji."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"tworzenie powiązania z usługą buforowania wydruku"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi buforowania wydruku. Nieprzeznaczone dla zwykłych aplikacji."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"powiązanie z usługą NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umożliwia właścicielowi powiązanie z aplikacjami emulującymi karty NFC. Nie powinno być nigdy potrzebne w normalnych aplikacjach."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"tworzenie powiązania z usługą tekstową"</string>
@@ -442,7 +442,7 @@
<string name="permlab_writeCallLog" msgid="8552045664743499354">"zapisywanie rejestru połączeń"</string>
<string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Zezwala aplikacji na modyfikowanie rejestru połączeń tabletu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
<string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Zezwala aplikacji na modyfikowanie rejestru połączeń telefonu, w tym danych o połączeniach przychodzących i wychodzących. Złośliwe aplikacje mogą wykorzystać tę możliwość, by wyczyścić lub zmodyfikować rejestr połączeń."</string>
- <string name="permlab_readProfile" msgid="4701889852612716678">"odczyt własnej karty kontaktu"</string>
+ <string name="permlab_readProfile" msgid="4701889852612716678">"odczytywanie własnej karty kontaktu"</string>
<string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Pozwala aplikacji na odczyt osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
<string name="permlab_writeProfile" msgid="907793628777397643">"zmiana własnej karty kontaktu"</string>
<string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pozwala aplikacji na zmianę lub dodanie osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string>
@@ -597,7 +597,7 @@
<string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Pozwala aplikacji na konfigurowanie lokalnego telefonu z funkcją Bluetooth oraz na wykrywanie urządzeń zdalnych i parowanie z nimi."</string>
<string name="permlab_accessWimaxState" msgid="4195907010610205703">"łączenie się i rozłączanie z siecią WiMAX"</string>
<string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Pozawala aplikacji określić, czy obsługa WiMAX jest włączona, oraz uzyskać informacje o wszystkich podłączonych sieciach WiMAX."</string>
- <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Zmień stan WiMAX"</string>
+ <string name="permlab_changeWimaxState" msgid="2405042267131496579">"zmienianie stanu WiMAX"</string>
<string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w tablecie."</string>
<string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Pozwala aplikacji na nawiązywanie i kończenie połączeń z sieciami WiMAX w telefonie."</string>
<string name="permlab_bluetooth" msgid="6127769336339276828">"parowanie z urządzeniami Bluetooth"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulowane"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Błąd podczas zapisu treści"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"brak informacji"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Podaj PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Bieżący PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nowy PIN"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index cd26fc7..810b5b3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o titular vincule a interface de nível superior de um serviço de acessibilidade. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"vincular a um serviço de impressão"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o titular vincule a interface de nível superior de um serviço de impressão. Nunca deverá ser necessário para aplicações normais."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"aceder a todas as tarefas de impressão"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite que o titular aceda a tarefas de impressão criadas por outra aplicação. Nunca deverá ser necessário para aplicações normais."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"vincular a um serviço spooler de impressão"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o titular vincule a interface de nível superior de um serviço spooler de impressão. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"vincular a serviço NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao titular vincular a aplicações que recriam cartões NFC. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"vincular a um serviço de texto"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelada"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao escrever conteúdo"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduzir PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN Atual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 22c5774..f457e21 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite que o proprietário use a interface de nível superior de um serviço de acessibilidade. Nunca deve ser necessário para aplicativos comuns."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"associar a um serviço de impressão"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite que o proprietário use a interface de nível superior de um serviço de impressão. Não deve ser necessário para aplicativos comuns."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acessar todos os trabalhos de impressão"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite que o proprietário acesse trabalhos de impressão criados por outro aplicativo. Não deve ser necessário para aplicativos comuns."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"associar a um serviço de spooler de impressão"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite que o proprietário use a interface de nível superior de um serviço de spooler de impressão. Não deve ser necessário para aplicativos comuns."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"associar ao serviço NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite ao proprietário associar a aplicativos que emulam cartões NFC. Não deve ser necessário para aplicativos comuns."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"sujeitar-se a um serviço de texto"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloide"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Cancelado"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Erro ao gravar o conteúdo"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"desconhecido"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Insira o PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN atual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novo PIN"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 84632f9..74830ef 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -561,9 +561,9 @@
<skip />
<!-- no translation found for permdesc_bindPrintService (7960067623209111135) -->
<skip />
- <!-- no translation found for permlab_accessAllPrintJobs (1120792468465711159) -->
+ <!-- no translation found for permlab_bindPrintSpoolerService (6807762783744125954) -->
<skip />
- <!-- no translation found for permdesc_accessAllPrintJobs (2978185311041864762) -->
+ <!-- no translation found for permdesc_bindPrintSpoolerService (3680552285933318372) -->
<skip />
<!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
<skip />
@@ -2576,6 +2576,8 @@
<skip />
<!-- no translation found for write_fail_reason_cannot_write (8132505417935337724) -->
<skip />
+ <!-- no translation found for reason_unknown (6048913880184628119) -->
+ <skip />
<!-- no translation found for restr_pin_enter_pin (3395953421368476103) -->
<skip />
<!-- no translation found for restr_pin_enter_old_pin (1462206225512910757) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index aad5797..4ab2b43 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu de accesibilitate. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"conectarea la un serviciu de printare"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"acces la toate procesele de printare"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Permite proprietarului să acceseze procesele de printare create de o altă aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"conectare la un serviciu derulator de printare"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Permite proprietarului să se conecteze la interfața de nivel superior a unui serviciu derulator de printare. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"conectare la serviciul NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Permite aplicației autorizate să se asocieze cu aplicații care emulează carduri NFC. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"conectare la un serviciu text"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Anulat"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Eroare la scrierea conținutului"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"necunoscut"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Introduceți codul PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Codul PIN actual"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Codul PIN nou"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e32b6de..5635381 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Приложение сможет подключаться к базовому интерфейсу службы специальных возможностей. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"Подключение к службе печати"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Приложение сможет подключаться к базовому интерфейсу службы печати. Это разрешение не используется обычными приложениями."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"Доступ к заданиям печати"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Владелец сможет просматривать задания печати, созданные другими приложениями. Это разрешение не используется обычными приложениями."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"подключение к спулеру печати"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Приложение сможет подключаться к базовому интерфейсу спулера печати. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"подключаться к службе NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Приложение сможет подключаться к программам с имитацией карт NFC. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"Подключение к службе текстовых сообщений"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid (279 х 432 мм)"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Печать отменена"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Ошибка записи"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"неизвестно"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Введите PIN-код"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Текущий PIN-код"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новый PIN-код"</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 3a01bad..50aa81c 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"ප්රවේශ්යතා සේවාවේ ඉහළ මට්ටමේ අතුරුමුහුණතට බැඳීමට දරන්නාට අවසර දේ. සාමාන්ය යෙදුම් සඳහා කිසිවිටක අවශ්ය නොවේ."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"මුද්රණ සේවාවකට බද්ධ වී ඇත"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"මුද්රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"සියලු මුද්රණ කාර්යයන් වෙත පිවිසෙන්න"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"වෙනත් යෙදුමකින් සෑදු මුද්රණ කාර්ය වෙත පිවිසීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම් සඳහා කිසිදා අවශ්ය නොවෙයි."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"මුද්රණ සේවාවකට බද්ධ වී ඇත"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"මුද්රණ සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්ය යෙදුම්වලට කිසි විටෙක අවශ්ය නොවෙයි."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC සේවාව වෙත බැඳෙන්න"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"NFC කාඩ් පත් ආදර්ශනය කරන යෙදුම් රඳවනයට සම්බන්ධ වීමට ඉඩ දෙන්න. සාමාන්ය යෙදුම් සඳහා කිසිදා අවශ්ය නොවෙයි."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"පෙළ සේවාවකට බඳින්න"</string>
@@ -1571,6 +1571,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"කුඩා පුවත්පත"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"අවලංගු කරන ලදි"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"අන්තර්ගතය ලිවීමේදී දෝෂයකි"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"නොදනී"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN එක ඇතුළු කරන්න"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"වත්මන් PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"නව PIN"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 49486675..b4ba202 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby zjednodušeného ovládania. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"viazanie na tlačovú službu"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"prístup ku všetkým tlačovým úlohám"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Umožňuje držiteľovi prístup k tlačovým úlohám vytvoreným inou aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"väzba na tlačovú službu"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tlačovej služby. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"previazať so službou NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Umožňuje držiteľovi previazať sa s aplikáciami, ktoré vydávajú karty NFC. Bežné aplikácie toto povolenie nikdy nepotrebujú."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"väzba na textovú službu"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Zrušené"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Pri zapisovaní obsahu došlo ku chybe"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"neznáme"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Zadajte kód PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuálny kód PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Nový kód PIN"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 04c2adf..3336dab 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Lastniku omogoča povezovanje z vmesnikom najvišje ravni storitve za ljudi s posebnimi potrebami. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"povezava s storitvijo tiskanja"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Lastniku omogoča povezovanje z vmesnikom storitve tiskanja najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"dostop do vseh tiskalnih poslov"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Lastniku omogoča dostop do tiskalnih poslov, ki jih je ustvarila druga aplikacija. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"povezava s storitvijo čakalne vrste za tiskanje"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Lastniku omogoča povezovanje z vmesnikom storitve čakalne vrste za tiskanje najvišje ravni. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"povezava s storitvijo NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Dovoljuje, da se lastnik poveže z aplikacijami, ki posnemajo kartice za NFC. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"poveži z besedilno storitvijo"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Preklicano"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Napaka pri pisanju vsebine"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"neznano"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Vnesite PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Trenutni PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Novi PIN"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 26de499..d66f18c 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозвољава власнику да се повеже са интерфејсом услуге приступачности највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"повезивање са услугом штампања"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозвољава власнику да се повеже са интерфејсом услуге штампања највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"приступ свим задацима за штампање"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Дозвољава власнику да приступа задацима за штампање које је направила друга апликација. Уобичајене апликације никада не би требало да је користе."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"повезивање са услугом штампања из меморије"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа услуге штампања из меморије. Не би требало никада да буде потребно за нормалне апликације."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"повезивање са NFC услугом"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозвољава власнику да се повеже са апликацијама које опонашају NFC картице. Никада не би требало да буде потребно за обичне апликације."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"обавезивање на текстуалну услугу"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Отказано је"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Грешка при исписивању садржаја"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"непознато"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Унесите PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Актуелни PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Нови PIN"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 3eac87f..00aa419 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en tillgänglighetstjänst. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"binda till en utskriftstjänst"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftstjänst. Ska inte behövas för vanliga appar."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"få tillgång till alla utskriftsjobb"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ger innehavaren tillgång till utskriftsjobb som skapas med en annan app. Ska inte behövas för normala appar."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"binda till en utskriftskö"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en utskriftskö. Ska inte behövas för vanliga appar."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"låsa till NFC-tjänsten"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Innehavaren får låsa appar som fungerar som NFC-kort. Behövs normalt inte för vanliga appar."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bind till en texttjänst"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Inställd"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Det gick inte att skriva innehållet"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"okänt"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ange pinkod"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Aktuell pinkod"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Ny pinkod"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 58f8723..b7b6506 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -160,9 +160,9 @@
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mtindo wa kimya"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Sauti Imezimwa"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Sauti imewashwa"</string>
- <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Modi ya ndege"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Hali ya ndege"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Hali ya ndege IMEWASHWA"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Modi ya ndege IMEZIMWA"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Hali ya ndege IMEZIMWA"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
<string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
<string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Inamuruhusu mmiliki kufunga kipengee kinachojitokeza katika nyanja mbalimbali za kiwango cha juu cha huduma ya afikiaji. Hapaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"tundika kwenye huduma ya kuchapisha"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Inaruhusu kishikiliaji kujifungilia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"fikia kazi zote za kuchapisha"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Huruhusu mmiliki kufikia kazi za kuchapisha zilizoundwa na programu nyingine. Haipaswi kuhitajika kwa programu za kawaida kamwe."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"Fungia kwenye huduma ya kuchapisha"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Inaruhusu mtumiaji kujifungia kiolesura cha kiwango cha juu cha huduma ya kuchapisha. Haipaswi kuhitajika kwa programu za kawaida."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"funga kwenye huduma za NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Huruhusu mmiliki kufunga kwa programu zinazoiga kadi za NFC. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"Imefungwa kwa huduma ya maandishi"</string>
@@ -555,7 +555,7 @@
<string name="permlab_setWallpaperHints" msgid="3278608165977736538">"rekebisha ukubwa wa mandhari yako"</string>
<string name="permdesc_setWallpaperHints" msgid="8235784384223730091">"Inaruhusu programu kuweka vidokezo vya ukubwa wa mandhari ya mfumo."</string>
<string name="permlab_masterClear" msgid="2315750423139697397">"weka upya mfumo kwa chaguo-msingi za kiwanda"</string>
- <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, usanidi, na programu zote zilizosanikishwa."</string>
+ <string name="permdesc_masterClear" msgid="3665380492633910226">"Huruhusu programu kurudisha mfumo kwenye mipangilio yake ya mwanzo, hatua ambayo hufuta data, mipangilio, na programu zote zilizosanikishwa."</string>
<string name="permlab_setTime" msgid="2021614829591775646">"weka muda"</string>
<string name="permdesc_setTime" product="tablet" msgid="1896341438151152881">"Inaruhusu programu kubadilisha wakati wa saa ya kompyuta kibao."</string>
<string name="permdesc_setTime" product="default" msgid="1855702730738020">"Inaruhusu programu kubadilisha wakati wa saa ya simu."</string>
@@ -1121,7 +1121,7 @@
<string name="screen_compat_mode_hint" msgid="1064524084543304459">"Wezesha tena hii katika mipangilio ya Mfumo > Programu > iliyopakuliwa."</string>
<string name="smv_application" msgid="3307209192155442829">"Programu <xliff:g id="APPLICATION">%1$s</xliff:g> (utaratibu <xliff:g id="PROCESS">%2$s</xliff:g>) imeenda kinyume na sera yake ya StrictMode."</string>
<string name="smv_process" msgid="5120397012047462446">"Shughuli ya <xliff:g id="PROCESS">%1$s</xliff:g> imeenda kinyume na kulazimisha sera yake ya StrictMode."</string>
- <string name="android_upgrading_title" msgid="1584192285441405746">"Android inapandishwa gredi..."</string>
+ <string name="android_upgrading_title" msgid="1584192285441405746">"Toleo jipya la Android linawekwa..."</string>
<string name="android_upgrading_apk" msgid="7904042682111526169">"Inasadifisha programu <xliff:g id="NUMBER_0">%1$d</xliff:g> ya <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
<string name="android_upgrading_starting_apps" msgid="451464516346926713">"Programu zinaanza"</string>
<string name="android_upgrading_complete" msgid="1405954754112999229">"Inamaliza kuwasha."</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Kijigazeti"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Imeghairiwa"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Hitilafu katika kuandika maudhui"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"haijulikani"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ingiza PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ya sasa"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN mpya"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 54728fb..376ee26 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"อนุญาตให้เจ้าของเชื่อมโยงกับส่วนติดต่อระดับบนสุดของบริการการเข้าถึง ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"เชื่อมโยงกับบริการการพิมพ์"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"อนุญาตให้ผู้ใช้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"เข้าถึงงานพิมพ์ทั้งหมด"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"อนุญาตให้ผู้ใช้สามารถเข้าถึงงานพิมพ์ที่สร้างโดยแอปอื่นได้ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"เชื่อมโยงกับบริการจัิดคิวและจัดการการพิมพ์"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"อนุญาตให้ผู้ใช้เชื่อมโยงกับอินเทอร์เฟซระดับสูงสุดของบริการจัดคิวและจัดการการพิมพ์ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"เชื่อมโยงกับบริการ NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"อนุญาตให้ผู้ถือเชื่อมโยงกับแอปพลิเคชันที่เลียนแบบการ์ด NFC ไม่จำเป็นสำหรับแอปทั่วไป"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"เชื่อมโยงกับบริการข้อความ"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"ยกเลิก"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"ข้อผิดพลาดในการเขียนเนื้อหา"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"ไม่ทราบ"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"ป้อน PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"PIN ปัจจุบัน"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"PIN ใหม่"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 1bd10ae..b6bca5d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Binibigyang-daan ang may-ari na sumailalim sa nasa nangungunang antas na interface ng isang serbisyo sa accessibility. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"sumailalim sa isang serbisyo sa pag-print"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Nagbibigay-daan sa may-ari na sumailalim sa interface sa nangungunang antas ng isang serbisyo sa pag-print. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"i-access ang lahat ng pag-print"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Nagbibigay-daan sa may-ari na i-access ang mga pag-print na ginawa ng ibang app. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"mag-bind sa isang serbisyo ng print spooler"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Nagbibigay-daan sa may-ari na mag-bind sa interface sa nangungunang antas ng isang serbisyo ng print spooler. Hindi dapat kailanganin para sa normal na apps."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"i-bind sa serbisyo ng NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Nagbibigay-daan sa may-ari na mag-bind sa mga application na nag-e-emulate ng mga NFC card. Hindi dapat kailanman kailanganin para sa normal na apps."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"sumailalim sa serbisyo ng teksto"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kinansela"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"May error sa pagsusulat ng nilalaman"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"hindi alam"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Ilagay ang PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Kasalukuyang PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Bagong PIN"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 5ab9165..44168d2 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"İzin sahibine bir erişilebilirlik hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"bir yazdırma hizmetine bağlan"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"İzin sahibine, bir yazdırma hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"tüm yazdırma işlerine eriş"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"İzin sahibine, başka uygulama tarafından oluşturulan yazdırma işlerine erişim izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bir yazdırma biriktirici hizmetine bağlan"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"İzin sahibine, bir yazdırma biriktirici hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"NFC hizmetine bağla"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"İzin sahibine, NFC kartlara öykünen uygulamalara bağlama izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"kısa mesaj hizmetine bağla"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"İptal edildi"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"İçerik yazılırken hata oluştu"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"bilinmiyor"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN\'i girin"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mevcut PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Yeni PIN"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 8877a05..2dcb546 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби доступності. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"прив’язуватися до служби друку"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби друку. Ніколи не застосовується для звичайних програм."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"отримувати доступ до всіх завдань друку"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Дозволяє власнику отримувати доступ до завдань друку, створених в іншій програмі. Ніколи не застосовується для звичайних програм."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"прив’язуватися до служби спулера друку"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби спулера друку. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"прив’язуватися до служби NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Дозволяє власникові прив’язуватися до програм, які емулюють картки NFC. Ніколи не використовується звичайними програмами."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"прив’язати до текстової служби"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Скасовано"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Помилка записування вмісту"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"невідомо"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Введіть PIN-код"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Поточний PIN-код"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Новий PIN-код"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5e1a9ae..0f417fe 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ truy cập. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"liên kết với dịch vụ in"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ in. Không cần thiết cho các ứng dụng thông thường."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"truy cập tất cả các lệnh in"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Cho phép chủ sở hữu truy cập các lệnh in được tạo ra bởi ứng dụng khác. Không cần thiết cho các ứng dụng thông thường."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"liên kết với dịch vụ bộ đệm in"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ bộ đệm in. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"liên kết với dịch vụ NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Cho phép chủ sở hữu liên kết với ứng dụng đang mô phỏng thẻ NFC. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"liên kết với dịch vụ văn bản"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Đã hủy"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Lỗi ghi nội dung"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"không xác định"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Nhập mã PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"Mã PIN hiện tại"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"Mã PIN mới"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 529997b..3bd2566 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允许应用绑定至辅助服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"绑定至打印服务"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"允许应用绑定至打印服务的顶级接口。普通应用绝不需要此权限。"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"查看或修改所有打印作业"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允许应用查看或修改其他应用创建的打印作业。普通应用绝不需要此权限。"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"绑定至打印后台处理程序服务"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允许应用绑定至打印后台处理程序服务的顶级接口。普通应用绝不需要此权限。"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"绑定到 NFC 服务"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"允许应用绑定到模拟 NFC 卡的应用。普通应用绝不需要此权限。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"绑定至文字服务"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"写入内容时出错"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"未知"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"输入 PIN 码"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"当前 PIN 码"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN 码"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 0252a81..c27890f 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (不建議一般應用程式使用)。"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"存取所有列印工作"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允許應用程式存取其他應用程式所建立的列印工作 (不建議一般應用程式使用)。"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (不建議一般應用程式使用)。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"輸入 PIN 碼"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"目前的 PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新的 PIN"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 5b8d8e8..571e01c 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"允許應用程式繫結至協助工具服務的頂層介面 (一般應用程式不需使用)。"</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"繫結至列印服務"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"允許應用程式繫結至列印服務的頂層介面 (一般應用程式並不需要)。"</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"存取所有列印工作"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"允許應用程式存取其他應用程式所建立的列印工作 (一般應用程式並不需要)。"</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"繫結至列印多工緩衝處理器服務"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"允許應用程式繫結至列印多工緩衝處理器服務的頂層介面 (一般應用程式並不需要)。"</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"繫結至 NFC 服務"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"允許應用程式繫結至模擬 NFC 卡的應用程式 (一般應用程式並不需要)。"</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"繫結至文字服務"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Tabloid"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"已取消"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"寫入內容時發生錯誤"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"不明"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"輸入 PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"目前的 PIN"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"新 PIN"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 3ff3303..c0b5c86 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -360,8 +360,8 @@
<string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Ivumela isibambi ukuhlanganisa uxhumo nomsebenzisi kwezinga eliphezulu lesevisi yesinqunjwana. Akusoze kwadingekela izinhlelo zokusebenza ezivamile."</string>
<string name="permlab_bindPrintService" msgid="8462815179572748761">"bophezela kusevisi yokuphrinta"</string>
<string name="permdesc_bindPrintService" msgid="7960067623209111135">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi lokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
- <string name="permlab_accessAllPrintJobs" msgid="1120792468465711159">"finyelela kuyo yonke imisebenzi yokuphrinta"</string>
- <string name="permdesc_accessAllPrintJobs" msgid="2978185311041864762">"Ivumela umnikazi ukuthi afinyelele imisebenzi yokushicilela edalwe olunye uhlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+ <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"bophezela kusevisi yendawo yokuphrinta"</string>
+ <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"Ivumela umnikazi ukuthi abophezele isixhumanisi esibonakalayo sezinga eliphezulu sesevisi yendawo yokuphrinta. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_bindNfcService" msgid="2752731300419410724">"bophezela kusevisi ye-NFC"</string>
<string name="permdesc_bindNfcService" msgid="6120647629174066862">"Ivumela umnikazi ukuthi abophezele izinhlelo zokusebenza ezifana namakhadi we-NFC. Akumele idingeke kuzinhlelo zokusebenza ezijwayelekile."</string>
<string name="permlab_bindTextService" msgid="7358378401915287938">"bophezela kunsizakalo yombhalo"</string>
@@ -1568,6 +1568,7 @@
<string name="mediaSize_na_tabloid" msgid="5775966416333578127">"Iphephandaba"</string>
<string name="write_fail_reason_cancelled" msgid="7091258378121627624">"Kukhanseliwe"</string>
<string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"Iphutha ekubhaleni okuqukethwe"</string>
+ <string name="reason_unknown" msgid="6048913880184628119">"akwaziwa"</string>
<string name="restr_pin_enter_pin" msgid="3395953421368476103">"Faka i-PIN"</string>
<string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"I-PIN yamanje"</string>
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"I-PIN entsha"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5444cb1..b6a4250 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2379,7 +2379,13 @@
method should be considered an option as the default. -->
<attr name="isDefault" format="boolean" />
<!-- Set to true if this input method supports ways to switch to
- a next input method (e.g. a globe key.). -->
+ a next input method (e.g. a globe key.). When this is true and
+ InputMethodManager#shouldOfferSwitchingToNextInputMethod() returns true,
+ the IME has to offer ways to to invoke InputMethodManager#switchToNextInputMethod()
+ accordingly.
+ <p> Note that the system determines the most appropriate next input method
+ and subtype in order to provide the consistent user experience in switching
+ between IMEs and subtypes. -->
<attr name="supportsSwitchingToNextInputMethod" format="boolean" />
</declare-styleable>
@@ -2605,6 +2611,9 @@
<!-- Whether the device must be unlocked before routing data to this service.
The default is false.-->
<attr name="requireDeviceUnlock" format="boolean"/>
+ <!-- A drawable that can be rendered in Android's system UI for representing
+ the service. -->
+ <attr name="apduServiceBanner" format="reference"/>
</declare-styleable>
<!-- Use <code>offhost-apdu-service</code> as the root tag of the XML resource that
@@ -2615,6 +2624,9 @@
<!-- Short description of the functionality the service implements. This attribute
is mandatory.-->
<attr name="description" />
+ <!-- A drawable that can be rendered in Android's system UI for representing
+ the service. -->
+ <attr name="apduServiceBanner"/>
</declare-styleable>
<!-- Specify one or more <code>aid-group</code> elements inside a
@@ -5743,11 +5755,11 @@
describes an injected "Location services" setting. Note that the status value (subtitle)
for the setting is specified dynamically by a subclass of SettingInjectorService.
-->
- <declare-styleable name="InjectedLocationSetting">
- <!-- The user-visible name (title) of the setting. -->
- <attr name="label"/>
- <!-- The icon for the apps covered by the setting. Typically a generic icon for the
- developer. -->
+ <declare-styleable name="SettingInjectorService">
+ <!-- The title for the preference. -->
+ <attr name="title"/>
+ <!-- The icon for the preference, should refer to all apps covered by the setting. Typically
+ a generic icon for the developer. -->
<attr name="icon"/>
<!-- The activity to launch when the setting is clicked on. -->
<attr name="settingsActivity"/>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index d4a408d..dd233c5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -774,6 +774,9 @@
re-validation -->
<bool name="config_bluetooth_address_validation">false</bool>
+ <!-- Boolean indicating if current platform supports BLE peripheral mode -->
+ <bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
+
<!-- The default data-use polling period. -->
<integer name="config_datause_polling_period_sec">600</integer>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 696e782..e6702b0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2074,5 +2074,7 @@
<public type="attr" name="autoMirrored" />
<public type="attr" name="supportsSwitchingToNextInputMethod" />
<public type="attr" name="requireDeviceUnlock" />
+ <public type="attr" name="apduServiceBanner" />
+ <public type="attr" name="provideAssistData" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4b32e2b..aa04bf6 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3970,11 +3970,6 @@
<!-- Title for a dialog showing possible activities for sharing in ShareActionProvider [CHAR LIMIT=25] -->
<string name="share_action_provider_share_with">Share with</string>
- <!-- Status Bar icon descriptions -->
-
- <!-- Description of for the status bar's icon that the device is locked for accessibility. [CHAR LIMIT=NONE] -->
- <string name="status_bar_device_locked">Device locked.</string>
-
<!-- Delimeter used between each item in a textual list; for example "Alpha, Beta". [CHAR LIMIT=3] -->
<string name="list_delimeter">", "</string>
@@ -4296,8 +4291,12 @@
<!-- Print fail reason: unknown. [CHAR LIMIT=25] -->
<string name="reason_unknown">unknown</string>
+ <!-- PIN entry dialog title for entering the administrator PIN [CHAR LIMIT=none] -->
+ <string name="restr_pin_enter_admin_pin">Enter administrator PIN</string>
<!-- PIN entry dialog label/hint for PIN [CHAR LIMIT=none] -->
<string name="restr_pin_enter_pin">Enter PIN</string>
+ <!-- PIN entry dialog label/hint for incorrect PIN entry [CHAR LIMIT=none] -->
+ <string name="restr_pin_incorrect">Incorrect</string>
<!-- PIN entry dialog label/hint for old PIN [CHAR LIMIT=none] -->
<string name="restr_pin_enter_old_pin">Current PIN</string>
<!-- PIN entry dialog label for new PIN [CHAR LIMIT=none] -->
@@ -4313,9 +4312,11 @@
<!-- PIN entry dialog countdown message for next chance to enter the PIN [CHAR LIMIT=none] -->
<!-- Phrase describing a time duration using seconds [CHAR LIMIT=16] -->
<plurals name="restr_pin_countdown">
- <item quantity="one">Incorrect PIN. Try again in 1 second.</item>
- <item quantity="other">Incorrect PIN. Try again in <xliff:g id="count">%d</xliff:g> seconds.</item>
+ <item quantity="one">Try again in 1 second</item>
+ <item quantity="other">Try again in <xliff:g id="count">%d</xliff:g> seconds</item>
</plurals>
+ <!-- PIN entry dialog tells the user to not enter a PIN for a while. [CHAR LIMIT=none] -->
+ <string name="restr_pin_try_later">Try again later</string>
<!-- Toast bar message when hiding the transient navigation bar [CHAR LIMIT=35] -->
<string name="transient_navigation_confirmation">Swipe edge of screen to reveal bar</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f008b10..1035054 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -212,7 +212,8 @@
<java-symbol type="id" name="sms_short_code_remember_undo_instruction" />
<java-symbol type="id" name="breadcrumb_section" />
<java-symbol type="id" name="action_bar_spinner" />
- <java-symbol type="id" name="pin_message" />
+ <java-symbol type="id" name="pin_cancel_button" />
+ <java-symbol type="id" name="pin_ok_button" />
<java-symbol type="id" name="pin_text" />
<java-symbol type="id" name="pin_new_text" />
<java-symbol type="id" name="pin_confirm_text" />
@@ -248,6 +249,7 @@
<java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" />
<java-symbol type="bool" name="config_bluetooth_address_validation" />
<java-symbol type="bool" name="config_bluetooth_sco_off_call" />
+ <java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
<java-symbol type="bool" name="config_cellBroadcastAppLinks" />
<java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
<java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" />
@@ -870,7 +872,10 @@
<java-symbol type="string" name="mediaSize_na_ledger" />
<java-symbol type="string" name="mediaSize_na_tabloid" />
<java-symbol type="string" name="reason_unknown" />
+ <java-symbol type="string" name="restr_pin_enter_admin_pin" />
<java-symbol type="string" name="restr_pin_enter_pin" />
+ <java-symbol type="string" name="restr_pin_incorrect" />
+ <java-symbol type="string" name="restr_pin_try_later" />
<java-symbol type="string" name="write_fail_reason_cancelled" />
<java-symbol type="string" name="write_fail_reason_cannot_write" />
<java-symbol type="string" name="transient_navigation_confirmation" />
@@ -1244,7 +1249,6 @@
<java-symbol type="drawable" name="jog_tab_target_yellow" />
<java-symbol type="drawable" name="magnified_region_frame" />
<java-symbol type="drawable" name="menu_background" />
- <java-symbol type="drawable" name="stat_sys_secure" />
<java-symbol type="id" name="action_mode_bar_stub" />
<java-symbol type="id" name="button0" />
<java-symbol type="id" name="button4" />
@@ -1307,7 +1311,6 @@
<java-symbol type="string" name="global_action_toggle_silent_mode" />
<java-symbol type="string" name="invalidPuk" />
<java-symbol type="string" name="lockscreen_carrier_default" />
- <java-symbol type="string" name="status_bar_device_locked" />
<java-symbol type="style" name="Animation.LockScreen" />
<java-symbol type="style" name="Theme.Dialog.RecentApplications" />
<java-symbol type="style" name="Theme.ExpandedMenu" />
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 22fa7fc..be55444 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -22,7 +22,7 @@
$(call all-java-files-under, EnabledTestApp/src)
LOCAL_DX_FLAGS := --core-library
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib mockwebserver guava littlemock
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support android-common frameworks-core-util-lib mockwebserver guava littlemock
LOCAL_JAVA_LIBRARIES := android.test.runner conscrypt telephony-common
LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java b/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
deleted file mode 100644
index 417a85f..0000000
--- a/core/tests/coretests/src/android/webkit/AccessibilityInjectorTest.java
+++ /dev/null
@@ -1,1809 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.webkit;
-
-import android.accessibilityservice.AccessibilityService;
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.KeyEvent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-/**
- * This is a test for the behavior of the {@link AccessibilityInjector}
- * which is used by {@link WebView} to provide basic accessibility support
- * in case JavaScript is disabled.
- * </p>
- * Note: This test works against the generated {@link AccessibilityEvent}s
- * to so it also checks if the test for announcing navigation axis and
- * status messages as appropriate.
- */
-public class AccessibilityInjectorTest
- extends ActivityInstrumentationTestCase2<AccessibilityInjectorTestActivity> {
-
- /** The timeout to wait for the expected selection. */
- private static final long TIMEOUT_WAIT_FOR_SELECTION_STRING = 1000;
-
- /** The timeout to wait for accessibility and the mock service to be enabled. */
- private static final long TIMEOUT_ENABLE_ACCESSIBILITY_AND_MOCK_SERVICE = 1000;
-
- /** The count of tests to detect when to shut down the service. */
- private static final int TEST_CASE_COUNT = 19;
-
- /** The meta state for pressed left ALT. */
- private static final int META_STATE_ALT_LEFT_ON = KeyEvent.META_ALT_ON
- | KeyEvent.META_ALT_LEFT_ON;
-
- /** Prefix for the CSS style span appended by WebKit. */
- private static final String APPLE_SPAN_PREFIX = "<span class=\"Apple-style-span\"";
-
- /** Suffix for the CSS style span appended by WebKit. */
- private static final String APPLE_SPAN_SUFFIX = "</span>";
-
- /** The value for not specified selection string since null is a valid value. */
- private static final String SELECTION_STRING_UNKNOWN = "Unknown";
-
- /** Lock for locking the test. */
- private static final Object sTestLock = new Object();
-
- /** Key bindings used for testing. */
- private static final String TEST_KEY_DINDINGS =
- "0x13=0x01000100;" +
- "0x14=0x01010100;" +
- "0x15=0x04000000;" +
- "0x16=0x04000000;" +
- "0x200000013=0x03020701:0x03010201:0x03000101:0x03030001:0x03040001:0x03050001:0x03060001;" +
- "0x200000014=0x03010001:0x03020101:0x03070201:0x03030701:0x03040701:0x03050701:0x03060701;" +
- "0x200000015=0x03040301:0x03050401:0x03060501:0x03000601:0x03010601:0x03020601:0x03070601;" +
- "0x200000016=0x03050601:0x03040501:0x03030401:0x03020301:0x03070301:0x03010301:0x03000301;";
-
- /** Handle to the test for use by the mock service. */
- private static AccessibilityInjectorTest sInstance;
-
- /** Flag indicating if the accessibility service is ready to receive events. */
- private static boolean sIsAccessibilityServiceReady;
-
- /** The count of executed tests to detect when to toggle accessibility and the service. */
- private static int sExecutedTestCount;
-
- /** Worker thread with a handler to perform non test thread processing. */
- private Worker mWorker;
-
- /** Handle to the {@link WebView} to load data in. */
- private WebView mWebView;
-
- /** Used for caching the default bindings so they can be restored. */
- private static String sDefaultKeyBindings;
-
- /** The received selection string for assertion checking. */
- private static String sReceivedSelectionString = SELECTION_STRING_UNKNOWN;
-
- public AccessibilityInjectorTest() {
- super(AccessibilityInjectorTestActivity.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mWorker = new Worker();
- sInstance = this;
- if (sExecutedTestCount == 0) {
- // until JUnit4 comes to play with @BeforeTest
- disableAccessibilityAndMockAccessibilityService();
- enableAccessibilityAndMockAccessibilityService();
- injectTestWebContentKeyBindings();
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (mWorker != null) {
- mWorker.stop();
- }
- if (sExecutedTestCount == TEST_CASE_COUNT) {
- // until JUnit4 comes to play with @AfterTest
- disableAccessibilityAndMockAccessibilityService();
- restoreDefaultWebContentKeyBindings();
- }
- super.tearDown();
- }
-
- /**
- * Tests navigation by character.
- */
- @LargeTest
- public void testNavigationByCharacter() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<p>" +
- "a<b>b</b>c" +
- "</p>" +
- "<p>" +
- "d" +
- "<p/>" +
- "e" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
- assertSelectionString("1"); // expect the word navigation axis
-
- // change navigation axis to character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
- assertSelectionString("0"); // expect the character navigation axis
-
- // go to the first character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("a");
-
- // go to the second character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<b>b</b>");
-
- // go to the third character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("c");
-
- // go to the fourth character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("d");
-
- // go to the fifth character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("e");
-
- // try to go past the last character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the fifth character (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("e");
-
- // go to the fourth character (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("d");
-
- // go to the third character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("c");
-
- // go to the second character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<b>b</b>");
-
- // go to the first character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("a");
-
- // try to go before the first character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the first character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("a");
-
- // go to the second character (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<b>b</b>");
- }
-
- /**
- * Tests navigation by word.
- */
- @LargeTest
- public void testNavigationByWord() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<p>" +
- "This is <b>a</b> sentence" +
- "</p>" +
- "<p>" +
- " scattered " +
- "<p/>" +
- " all over " +
- "</p>" +
- "<div>" +
- "<p>the place.</p>" +
- "</div>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
- assertSelectionString("1"); // expect the word navigation axis
-
- // go to the first word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This");
-
- // go to the second word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("is");
-
- // go to the third word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<b>a</b>");
-
- // go to the fourth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("sentence");
-
- // go to the fifth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("scattered");
-
- // go to the sixth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("all");
-
- // go to the seventh word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("over");
-
- // go to the eight word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("the");
-
- // go to the ninth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("place");
-
- // NOTE: WebKit selection returns the dot as a word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(".");
-
- // try to go past the last word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the last word (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("place.");
-
- // go to the eight word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("the");
-
- // go to the seventh word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("over");
-
- // go to the sixth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("all");
-
- // go to the fifth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("scattered");
-
- // go to the fourth word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("sentence");
-
- // go to the third word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<b>a</b>");
-
- // go to the second word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("is");
-
- // go to the first word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This");
-
- // try to go before the first word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the first word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This");
-
- // go to the second word (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("is");
- }
-
- /**
- * Tests navigation by sentence.
- */
- @LargeTest
- public void testNavigationBySentence() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<div>" +
- "<p>" +
- "This is the first sentence of the first paragraph and has an <b>inline bold tag</b>." +
- "This is the second sentence of the first paragraph." +
- "</p>" +
- "<h1>This is a heading</h1>" +
- "<p>" +
- "This is the first sentence of the second paragraph." +
- "This is the second sentence of the second paragraph." +
- "</p>" +
- "</div>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // Sentence axis is the default
-
- // go to the first sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the first sentence of the first paragraph and has an "
- + "<b>inline bold tag</b>.");
-
- // go to the second sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the second sentence of the first paragraph.");
-
- // go to the third sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is a heading");
-
- // go to the fourth sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the first sentence of the second paragraph.");
-
- // go to the fifth sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the second sentence of the second paragraph.");
-
- // try to go past the last sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the fifth sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This is the second sentence of the second paragraph.");
-
- // go to the fourth sentence (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This is the first sentence of the second paragraph.");
-
- // go to the third sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This is a heading");
-
- // go to the second sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This is the second sentence of the first paragraph.");
-
- // go to the first sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("This is the first sentence of the first paragraph and has an "
- + "<b>inline bold tag</b>.");
-
- // try to go before the first sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the first sentence
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the first sentence of the first paragraph and has an "
- + "<b>inline bold tag</b>.");
-
- // go to the second sentence (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("This is the second sentence of the first paragraph.");
- }
-
- /**
- * Tests navigation by heading.
- */
- @LargeTest
- public void testNavigationByHeading() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<h1>Heading one</h1>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<h2>Heading two</h2>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<h3>Heading three</h3>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<h4>Heading four</h4>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<h5>Heading five</h5>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<h6>Heading six</h6>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("3"); // expect the heading navigation axis
-
- // go to the first heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h1>Heading one</h1>");
-
- // go to the second heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h2>Heading two</h2>");
-
- // go to the third heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h3>Heading three</h3>");
-
- // go to the fourth heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h4>Heading four</h4>");
-
- // go to the fifth heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h5>Heading five</h5>");
-
- // go to the sixth heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h6>Heading six</h6>");
-
- // try to go past the last heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the fifth heading (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h5>Heading five</h5>");
-
- // go to the fourth heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h4>Heading four</h4>");
-
- // go to the third heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h3>Heading three</h3>");
-
- // go to the second heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h2>Heading two</h2>");
-
- // go to the first heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h1>Heading one</h1>");
-
- // try to go before the first heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the second heading (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h2>Heading two</h2>");
- }
-
- /**
- * Tests navigation by sibling.
- */
- @LargeTest
- public void testNavigationBySibing() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<h1>Heading one</h1>" +
- "<p>" +
- "This is some text" +
- "</p>" +
- "<div>" +
- "<button>Input</button>" +
- "</div>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("3"); // expect the heading navigation axis
-
- // change navigation axis to sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("4"); // expect the sibling navigation axis
-
- // change navigation axis to parent/first child
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("5"); // expect the parent/first child navigation axis
-
- // go to the first child of the body
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<h1>Heading one</h1>");
-
- // change navigation axis to sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("4"); // expect the sibling navigation axis
-
- // go to the next sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<p>This is some text</p>");
-
- // go to the next sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<div><button>Input</button></div>");
-
- // try to go past the last sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the previous sibling (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<p>This is some text</p>");
-
- // go to the previous sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<h1>Heading one</h1>");
-
- // try to go before the previous sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the next sibling (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<p>This is some text</p>");
- }
-
- /**
- * Tests navigation by parent/first child.
- */
- @LargeTest
- public void testNavigationByParentFirstChild() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<div>" +
- "<button>Input</button>" +
- "</div>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to document
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("6"); // expect the document navigation axis
-
- // change navigation axis to parent/first child
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("5"); // expect the parent/first child navigation axis
-
- // go to the first child
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<div><button>Input</button></div>");
-
- // go to the first child
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<button>Input</button>");
-
- // try to go to the first child of a leaf element
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString(null);
-
- // go to the parent (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<div><button>Input</button></div>");
-
- // go to the parent
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<body><div><button>Input</button></div></body>");
-
- // try to go to the body parent
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString(null);
-
- // go to the first child (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<div><button>Input</button></div>");
- }
-
- /**
- * Tests navigation by document.
- */
- @LargeTest
- public void testNavigationByDocument() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<button>Click</button>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to document
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_LEFT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("6"); // expect the document navigation axis
-
- // go to the bottom of the document
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("Click");
-
- // go to the top of the document (reverse)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, 0);
- assertSelectionString("<body><button>Click</button></body>");
-
- // go to the bottom of the document (reverse again)
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("Click");
- }
-
- /**
- * Tests the sync between the text navigation and navigation by DOM elements.
- */
- @LargeTest
- public void testSyncBetweenTextAndDomNodeNavigation() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<p>" +
- "First" +
- "</p>" +
- "<button>Second</button>" +
- "<p>" +
- "Third" +
- "</p>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);
-
- // change navigation axis to word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, META_STATE_ALT_LEFT_ON);
- assertSelectionString("1"); // expect the word navigation axis
-
- // go to the first word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("First");
-
- // change navigation axis to heading
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("3"); // expect the heading navigation axis
-
- // change navigation axis to sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_RIGHT, META_STATE_ALT_LEFT_ON);
- assertSelectionString("4"); // expect the sibling navigation axis
-
- // go to the next sibling
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("<button>Second</button>");
-
- // change navigation axis to character
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, META_STATE_ALT_LEFT_ON);
- assertSelectionString("0"); // expect the character navigation axis
-
- // change navigation axis to word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_UP, META_STATE_ALT_LEFT_ON);
- assertSelectionString("1"); // expect the word navigation axis
-
- // go to the next word
- sendKeyEvent(webView, KeyEvent.KEYCODE_DPAD_DOWN, 0);
- assertSelectionString("Third");
- }
-
- /**
- * Tests that the selection does not cross anchor boundaries. This is a
- * workaround for the asymmetric and inconsistent handling of text with
- * links by WebKit while traversing by sentence.
- */
- @LargeTest
- public void testEnforceSelectionDoesNotCrossAnchorBoundary1() throws Exception {
- // a bit ugly but helps detect beginning and end of all tests so accessibility
- // and the mock service are not toggled on every test (expensive)
- sExecutedTestCount++;
-
- String html =
- "<!DOCTYPE html>" +
- "<html>" +
- "<head>" +
- "</head>" +
- "<body>" +
- "<div>First</div>" +
- "<p>" +
- "<a href=\"\">Second</a> Third" +
- "</p>" +
- "</body>" +
- "</html>";
-
- WebView webView = loadHTML(html);